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))]> {
1855 let hasNoSchedulingInfo = 1;
1858 class Atomic2OpsPostRA<RegisterClass RC> :
1859 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1864 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1865 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1866 RC:$shiftamnt), []>;
1868 // Atomic Compare & Swap.
1869 // Atomic compare and swap is lowered into two stages. The first stage happens
1870 // during ISelLowering, which produces the PostRA version of this instruction.
1871 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1872 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1873 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
1874 let hasNoSchedulingInfo = 1;
1877 class AtomicCmpSwapPostRA<RegisterClass RC> :
1878 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1883 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1884 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1885 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1890 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1891 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1892 [], II_LL, FrmI, opstr> {
1893 let DecoderMethod = "DecodeMem";
1897 class SCBase<string opstr, RegisterOperand RO> :
1898 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1899 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1900 let DecoderMethod = "DecodeMem";
1902 let Constraints = "$rt = $dst";
1905 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1906 InstrItinClass itin> :
1907 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1908 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1909 let BaseOpcode = asmstr;
1912 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1913 InstrItinClass itin> :
1914 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1915 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1916 let BaseOpcode = asmstr;
1919 class TrapBase<Instruction RealInst>
1920 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1921 PseudoInstExpansion<(RealInst 0, 0)> {
1923 let isTerminator = 1;
1924 let isCodeGenOnly = 1;
1928 //===----------------------------------------------------------------------===//
1929 // Pseudo instructions
1930 //===----------------------------------------------------------------------===//
1933 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1934 let hasDelaySlot=1 in
1935 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1937 let hasSideEffects=1 in
1938 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1941 let Defs = [SP], Uses = [SP], hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
1942 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1943 [(callseq_start timm:$amt1, timm:$amt2)]>;
1944 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1945 [(callseq_end timm:$amt1, timm:$amt2)]>;
1948 let usesCustomInserter = 1 in {
1949 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1950 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1951 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1952 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1953 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1954 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1955 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1956 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1957 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1958 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1959 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1960 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1961 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1962 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1963 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1964 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1965 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1966 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1968 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1969 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1970 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1972 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1973 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1974 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1978 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1979 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1980 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1981 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1982 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1983 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1984 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1985 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1986 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1987 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1988 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1989 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1990 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1991 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1992 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1993 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1994 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1995 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1997 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1998 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1999 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
2001 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
2002 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
2003 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
2005 /// Pseudo instructions for loading and storing accumulator registers.
2006 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
2007 def LOAD_ACC64 : Load<"", ACC64>;
2008 def STORE_ACC64 : Store<"", ACC64>;
2011 // We need these two pseudo instructions to avoid offset calculation for long
2012 // branches. See the comment in file MipsLongBranch.cpp for detailed
2015 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
2016 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
2017 (ins brtarget:$tgt, brtarget:$baltgt), []> {
2018 bit hasNoSchedulingInfo = 1;
2020 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
2021 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
2022 (ins brtarget:$tgt), []> {
2023 bit hasNoSchedulingInfo = 1;
2026 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2027 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2028 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []> {
2029 bit hasNoSchedulingInfo = 1;
2031 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2032 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2033 (ins GPR32Opnd:$src, brtarget:$tgt), []> {
2034 bit hasNoSchedulingInfo = 1;
2037 //===----------------------------------------------------------------------===//
2038 // Instruction definition
2039 //===----------------------------------------------------------------------===//
2040 //===----------------------------------------------------------------------===//
2041 // MipsI Instructions
2042 //===----------------------------------------------------------------------===//
2044 /// Arithmetic Instructions (ALU Immediate)
2045 let AdditionalPredicates = [NotInMicroMips] in {
2046 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2047 II_ADDIU, immSExt16, add>,
2048 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2050 def ANDi : MMRel, StdMMR6Rel,
2051 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
2052 ADDI_FM<0xc>, ISA_MIPS1;
2053 def ORi : MMRel, StdMMR6Rel,
2054 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
2055 ADDI_FM<0xd>, ISA_MIPS1;
2056 def XORi : MMRel, StdMMR6Rel,
2057 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
2058 ADDI_FM<0xe>, ISA_MIPS1;
2059 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2060 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2061 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2062 SLTI_FM<0xa>, ISA_MIPS1;
2063 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2064 SLTI_FM<0xb>, ISA_MIPS1;
2066 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2069 /// Arithmetic Instructions (3-Operand, R-Type)
2070 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2071 ADD_FM<0, 0x21>, ISA_MIPS1;
2072 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2073 ADD_FM<0, 0x23>, ISA_MIPS1;
2075 let Defs = [HI0, LO0] in
2076 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2077 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2079 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2080 ADD_FM<0, 0x20>, ISA_MIPS1;
2081 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2082 ADD_FM<0, 0x22>, ISA_MIPS1;
2084 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2086 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2088 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2089 ADD_FM<0, 0x24>, ISA_MIPS1;
2090 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2091 ADD_FM<0, 0x25>, ISA_MIPS1;
2092 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2093 ADD_FM<0, 0x26>, ISA_MIPS1;
2094 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2098 let AdditionalPredicates = [NotInMicroMips] in {
2099 /// Shift Instructions
2100 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
2101 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2102 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
2103 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2104 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
2105 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2106 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
2107 SRLV_FM<4, 0>, ISA_MIPS1;
2108 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
2109 SRLV_FM<6, 0>, ISA_MIPS1;
2110 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
2111 SRLV_FM<7, 0>, ISA_MIPS1;
2113 // Rotate Instructions
2114 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2116 SRA_FM<2, 1>, ISA_MIPS32R2;
2117 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2118 SRLV_FM<6, 1>, ISA_MIPS32R2;
2121 /// Load and Store Instructions
2123 let AdditionalPredicates = [NotInMicroMips] in {
2124 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2125 LW_FM<0x20>, ISA_MIPS1;
2126 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2127 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2128 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2129 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2130 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2131 MMRel, LW_FM<0x25>, ISA_MIPS1;
2132 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2133 LW_FM<0x23>, ISA_MIPS1;
2134 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2135 LW_FM<0x28>, ISA_MIPS1;
2136 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2138 def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>, ISA_MIPS1;
2141 /// load/store left/right
2142 let AdditionalPredicates = [NotInMicroMips] in {
2143 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2144 ISA_MIPS1_NOT_32R6_64R6;
2145 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2146 ISA_MIPS1_NOT_32R6_64R6;
2147 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2148 ISA_MIPS1_NOT_32R6_64R6;
2149 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2150 ISA_MIPS1_NOT_32R6_64R6;
2152 // COP2 Memory Instructions
2153 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2154 ISA_MIPS1_NOT_32R6_64R6;
2155 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2156 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2157 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2158 ISA_MIPS2_NOT_32R6_64R6;
2159 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2160 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2162 // COP3 Memory Instructions
2163 let DecoderNamespace = "COP3_" in {
2164 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2165 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2166 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2167 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2168 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2169 ISA_MIPS2, NOT_ASE_CNMIPS;
2170 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2171 ISA_MIPS2, NOT_ASE_CNMIPS;
2174 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2175 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2179 let AdditionalPredicates = [NotInMicroMips] in {
2180 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2182 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2184 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2186 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2188 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2190 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2193 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2194 ISA_MIPS2_NOT_32R6_64R6;
2195 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2196 ISA_MIPS2_NOT_32R6_64R6;
2197 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2198 ISA_MIPS2_NOT_32R6_64R6;
2199 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2200 ISA_MIPS2_NOT_32R6_64R6;
2201 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2202 ISA_MIPS2_NOT_32R6_64R6;
2203 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2204 ISA_MIPS2_NOT_32R6_64R6;
2207 let AdditionalPredicates = [NotInMicroMips] in {
2208 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2209 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2211 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2212 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2213 ISA_MIPS32_NOT_32R6_64R6;
2215 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2216 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2218 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2220 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2222 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2225 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2228 let AdditionalPredicates = [NotInMicroMips] in {
2229 /// Load-linked, Store-conditional
2230 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2231 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2233 /// Jump and Branch Instructions
2234 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2235 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2236 IsBranch, ISA_MIPS1;
2238 let AdditionalPredicates = [NotInMicroMips] in {
2239 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
2240 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2242 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2243 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2244 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2246 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2247 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2248 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2249 BGEZ_FM<1, 1>, ISA_MIPS1;
2250 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2251 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2252 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2253 BGEZ_FM<7, 0>, ISA_MIPS1;
2254 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2255 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2256 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2257 BGEZ_FM<6, 0>, ISA_MIPS1;
2258 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2259 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2260 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2261 BGEZ_FM<1, 0>, ISA_MIPS1;
2262 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2263 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2264 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2266 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2270 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2271 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2272 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2275 let AdditionalPredicates = [NotInMicroMips] in {
2276 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2277 ISA_MIPS32_NOT_32R6_64R6;
2278 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2279 ISA_MIPS1_NOT_32R6_64R6;
2280 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2281 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2282 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2283 ISA_MIPS1_NOT_32R6_64R6;
2284 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2285 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2286 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2288 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2289 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2291 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2292 NoIndirectJumpGuards] in
2293 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2295 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2296 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2297 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2298 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2299 II_IndirectBranchPseudo>,
2300 PseudoInstExpansion<(JumpInst RO:$rs)> {
2303 let hasDelaySlot = 1;
2305 let isIndirectBranch = 1;
2309 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2310 NoIndirectJumpGuards] in
2311 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2312 ISA_MIPS1_NOT_32R6_64R6;
2314 // Return instructions are matched as a RetRA instruction, then are expanded
2315 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2316 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2318 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2319 [], II_ReturnPseudo> {
2320 let isTerminator = 1;
2322 let hasDelaySlot = 1;
2324 let isCodeGenOnly = 1;
2326 let hasExtraSrcRegAllocReq = 1;
2330 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2332 // Exception handling related node and instructions.
2333 // The conversion sequence is:
2334 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2335 // MIPSeh_return -> (stack change + indirect branch)
2337 // MIPSeh_return takes the place of regular return instruction
2338 // but takes two arguments (V1, V0) which are used for storing
2339 // the offset and return address respectively.
2340 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2342 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2343 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2345 let Uses = [V0, V1], isTerminator = 1, isReturn = 1,
2346 isBarrier = 1, isCTI = 1, hasNoSchedulingInfo = 1 in {
2347 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2348 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2349 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, GPR64:$dst),
2350 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2353 /// Multiply and Divide Instructions.
2354 let AdditionalPredicates = [NotInMicroMips] in {
2355 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2356 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2357 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2358 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2359 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2360 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2361 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2362 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2363 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2364 ISA_MIPS1_NOT_32R6_64R6;
2365 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2366 ISA_MIPS1_NOT_32R6_64R6;
2367 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2368 ISA_MIPS1_NOT_32R6_64R6;
2369 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2370 ISA_MIPS1_NOT_32R6_64R6;
2372 /// Sign Ext In Register Instructions.
2373 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2374 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2375 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2376 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2379 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2380 ISA_MIPS32_NOT_32R6_64R6;
2381 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2382 ISA_MIPS32_NOT_32R6_64R6;
2384 /// Word Swap Bytes Within Halfwords
2385 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2389 def NOP : PseudoSE<(outs), (ins), []>,
2390 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2392 // FrameIndexes are legalized when they are operands from load/store
2393 // instructions. The same not happens for stack address copies, so an
2394 // add op with mem ComplexPattern is used and the stack address copy
2395 // can be matched. It's similar to Sparc LEA_ADDRi
2396 let AdditionalPredicates = [NotInMicroMips] in
2397 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>, ISA_MIPS1;
2400 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2401 ISA_MIPS32_NOT_32R6_64R6;
2402 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2403 ISA_MIPS32_NOT_32R6_64R6;
2404 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2405 ISA_MIPS32_NOT_32R6_64R6;
2406 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2407 ISA_MIPS32_NOT_32R6_64R6;
2410 let AdditionalPredicates = [NotDSP] in {
2411 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2412 ISA_MIPS1_NOT_32R6_64R6;
2413 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2414 ISA_MIPS1_NOT_32R6_64R6;
2415 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2416 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2417 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2418 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2419 ISA_MIPS32_NOT_32R6_64R6;
2420 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2421 ISA_MIPS32_NOT_32R6_64R6;
2422 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2423 ISA_MIPS32_NOT_32R6_64R6;
2424 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2425 ISA_MIPS32_NOT_32R6_64R6;
2428 let AdditionalPredicates = [NotInMicroMips] in {
2429 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2430 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2431 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2432 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2433 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2434 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2435 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2436 immZExt5, immZExt5Plus1, MipsExt>,
2437 EXT_FM<0>, ISA_MIPS32R2;
2438 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2439 uimm5_inssize_plus1, immZExt5,
2441 EXT_FM<4>, ISA_MIPS32R2;
2443 /// Move Control Registers From/To CPU Registers
2444 let AdditionalPredicates = [NotInMicroMips] in {
2445 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2446 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2447 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2448 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2449 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2450 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2451 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2452 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2455 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2456 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2457 let AdditionalPredicates = [NotInMicroMips] in {
2458 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2460 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2463 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2467 // JR_HB and JALR_HB are defined here using the new style naming
2468 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2469 // and because of that it doesn't follow the naming convention of the
2470 // rest of the file. To avoid a mixture of old vs new style, the new
2471 // style was chosen.
2472 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2473 dag OutOperandList = (outs);
2474 dag InOperandList = (ins GPROpnd:$rs);
2475 string AsmString = !strconcat(instr_asm, "\t$rs");
2476 list<dag> Pattern = [];
2479 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2480 dag OutOperandList = (outs GPROpnd:$rd);
2481 dag InOperandList = (ins GPROpnd:$rs);
2482 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2483 list<dag> Pattern = [];
2486 class JR_HB_DESC<RegisterOperand RO> :
2487 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2489 let isIndirectBranch=1;
2496 class JALR_HB_DESC<RegisterOperand RO> :
2497 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2499 let isIndirectBranch=1;
2504 class JR_HB_ENC : JR_HB_FM<8>;
2505 class JALR_HB_ENC : JALR_HB_FM<9>;
2507 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2508 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2510 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2511 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2514 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2515 UseIndirectJumpsHazard] in {
2516 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2517 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2518 ISA_MIPS32R2_NOT_32R6_64R6;
2521 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2522 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2523 let AdditionalPredicates = [NotInMicroMips] in {
2524 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2525 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2526 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2527 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2529 class CacheOp<string instr_asm, Operand MemOpnd,
2530 InstrItinClass itin = NoItinerary> :
2531 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2532 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2534 let DecoderMethod = "DecodeCacheOp";
2537 let AdditionalPredicates = [NotInMicroMips] in {
2538 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2539 INSN_MIPS3_32_NOT_32R6_64R6;
2540 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2541 INSN_MIPS3_32_NOT_32R6_64R6;
2543 // FIXME: We are missing the prefx instruction.
2544 def ROL : MipsAsmPseudoInst<(outs),
2545 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2546 "rol\t$rs, $rt, $rd">;
2547 def ROLImm : MipsAsmPseudoInst<(outs),
2548 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2549 "rol\t$rs, $rt, $imm">;
2550 def : MipsInstAlias<"rol $rd, $rs",
2551 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2552 def : MipsInstAlias<"rol $rd, $imm",
2553 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2555 def ROR : MipsAsmPseudoInst<(outs),
2556 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2557 "ror\t$rs, $rt, $rd">;
2558 def RORImm : MipsAsmPseudoInst<(outs),
2559 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2560 "ror\t$rs, $rt, $imm">;
2561 def : MipsInstAlias<"ror $rd, $rs",
2562 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2563 def : MipsInstAlias<"ror $rd, $imm",
2564 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2566 def DROL : MipsAsmPseudoInst<(outs),
2567 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2568 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2569 def DROLImm : MipsAsmPseudoInst<(outs),
2570 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2571 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2572 def : MipsInstAlias<"drol $rd, $rs",
2573 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2574 def : MipsInstAlias<"drol $rd, $imm",
2575 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2577 def DROR : MipsAsmPseudoInst<(outs),
2578 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2579 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2580 def DRORImm : MipsAsmPseudoInst<(outs),
2581 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2582 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2583 def : MipsInstAlias<"dror $rd, $rs",
2584 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2585 def : MipsInstAlias<"dror $rd, $imm",
2586 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2588 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2591 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2592 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2593 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2595 def : MipsInstAlias<"seq $rd, $rs",
2596 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2599 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2600 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2601 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2603 def : MipsInstAlias<"seq $rd, $imm",
2604 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2607 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2608 simm32_relaxed:$imm),
2609 "mul\t$rd, $rs, $imm">,
2610 ISA_MIPS1_NOT_32R6_64R6;
2611 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2613 "mulo\t$rd, $rs, $rt">,
2614 ISA_MIPS1_NOT_32R6_64R6;
2615 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2617 "mulou\t$rd, $rs, $rt">,
2618 ISA_MIPS1_NOT_32R6_64R6;
2620 // Virtualization ASE
2621 class HYPCALL_FT<string opstr> :
2622 InstSE<(outs), (ins uimm10:$code_),
2623 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2624 let BaseOpcode = opstr;
2627 let AdditionalPredicates = [NotInMicroMips] in {
2628 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2629 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2630 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2631 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2632 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2633 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2634 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2635 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2636 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2637 ISA_MIPS32R5, ASE_VIRT;
2638 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2639 ISA_MIPS32R5, ASE_VIRT;
2640 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2641 ISA_MIPS32R5, ASE_VIRT;
2642 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2643 ISA_MIPS32R5, ASE_VIRT;
2644 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2645 ISA_MIPS32R5, ASE_VIRT;
2646 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2647 ISA_MIPS32R5, ASE_VIRT;
2648 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2649 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2652 //===----------------------------------------------------------------------===//
2653 // Instruction aliases
2654 //===----------------------------------------------------------------------===//
2656 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2658 RegisterOperand RO = GPR32Opnd,
2659 Operand Imm = simm32_relaxed> {
2660 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2664 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2670 let AdditionalPredicates = [NotInMicroMips] in {
2671 def : MipsInstAlias<"move $dst, $src",
2672 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2674 def : MipsInstAlias<"move $dst, $src",
2675 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2678 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2679 ISA_MIPS1_NOT_32R6_64R6;
2681 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2683 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2685 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2688 def : MipsInstAlias<"neg $rt, $rs",
2689 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2690 def : MipsInstAlias<"neg $rt",
2691 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2692 def : MipsInstAlias<"negu $rt, $rs",
2693 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2694 def : MipsInstAlias<"negu $rt",
2695 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2697 def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2698 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2699 "sge\t$rd, $rs, $rt">, ISA_MIPS1;
2700 def : MipsInstAlias<"sge $rs, $rt",
2701 (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2703 def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2704 (ins GPR32Opnd:$rs, simm32:$imm),
2705 "sge\t$rd, $rs, $imm">, GPR_32;
2706 def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs,
2711 def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2712 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2713 "sgeu\t$rd, $rs, $rt">, ISA_MIPS1;
2714 def : MipsInstAlias<"sgeu $rs, $rt",
2715 (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2717 def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2718 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2719 "sgeu\t$rd, $rs, $imm">, GPR_32;
2720 def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs,
2722 uimm32_coerced:$imm), 0>,
2725 def : MipsInstAlias<
2726 "sgt $rd, $rs, $rt",
2727 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2728 def : MipsInstAlias<
2730 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2732 def SGTImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2733 (ins GPR32Opnd:$rs, simm32:$imm),
2734 "sgt\t$rd, $rs, $imm">, GPR_32;
2735 def : MipsInstAlias<"sgt $rs, $imm", (SGTImm GPR32Opnd:$rs,
2739 def : MipsInstAlias<
2740 "sgtu $rd, $rs, $rt",
2741 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2742 def : MipsInstAlias<
2744 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2746 def SGTUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2747 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2748 "sgtu\t$rd, $rs, $imm">, GPR_32;
2749 def : MipsInstAlias<"sgtu $rs, $imm", (SGTUImm GPR32Opnd:$rs,
2751 uimm32_coerced:$imm), 0>,
2754 def : MipsInstAlias<
2756 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2757 def : MipsInstAlias<
2759 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2761 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2763 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
2765 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2767 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2769 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2771 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2773 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2775 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2777 def : MipsInstAlias<"mfgc0 $rt, $rd",
2778 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2779 ISA_MIPS32R5, ASE_VIRT;
2780 def : MipsInstAlias<"mtgc0 $rt, $rd",
2781 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2782 ISA_MIPS32R5, ASE_VIRT;
2783 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2784 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2785 ISA_MIPS32R5, ASE_VIRT;
2786 def : MipsInstAlias<"mthgc0 $rt, $rd",
2787 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2788 ISA_MIPS32R5, ASE_VIRT;
2789 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2791 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2793 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2795 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2798 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2801 def : MipsInstAlias<"bnez $rs,$offset",
2802 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2804 def : MipsInstAlias<"bnezl $rs, $offset",
2805 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2807 def : MipsInstAlias<"beqz $rs,$offset",
2808 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2810 def : MipsInstAlias<"beqzl $rs, $offset",
2811 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2814 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2816 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2817 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2818 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2819 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2821 def : MipsInstAlias<"teq $rs, $rt",
2822 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2823 def : MipsInstAlias<"tge $rs, $rt",
2824 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2825 def : MipsInstAlias<"tgeu $rs, $rt",
2826 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2827 def : MipsInstAlias<"tlt $rs, $rt",
2828 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2829 def : MipsInstAlias<"tltu $rs, $rt",
2830 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2831 def : MipsInstAlias<"tne $rs, $rt",
2832 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2833 def : MipsInstAlias<"rdhwr $rt, $rs",
2834 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2837 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2838 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2839 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2840 def : MipsInstAlias<"sub $rs, $imm",
2841 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2842 0>, ISA_MIPS1_NOT_32R6_64R6;
2843 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2844 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2845 InvertedImOperand:$imm), 0>;
2846 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2847 InvertedImOperand:$imm), 0>;
2848 let AdditionalPredicates = [NotInMicroMips] in {
2849 def : MipsInstAlias<"sll $rd, $rt, $rs",
2850 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2851 def : MipsInstAlias<"sra $rd, $rt, $rs",
2852 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2853 def : MipsInstAlias<"srl $rd, $rt, $rs",
2854 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2855 def : MipsInstAlias<"sll $rd, $rt",
2856 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2857 def : MipsInstAlias<"sra $rd, $rt",
2858 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2859 def : MipsInstAlias<"srl $rd, $rt",
2860 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2861 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2863 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2866 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2867 let AdditionalPredicates = [NotInMicroMips] in
2868 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2870 def : MipsInstAlias<"mulo $rs, $rt",
2871 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2872 ISA_MIPS1_NOT_32R6_64R6;
2873 def : MipsInstAlias<"mulou $rs, $rt",
2874 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2875 ISA_MIPS1_NOT_32R6_64R6;
2877 let AdditionalPredicates = [NotInMicroMips] in
2878 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2880 //===----------------------------------------------------------------------===//
2881 // Assembler Pseudo Instructions
2882 //===----------------------------------------------------------------------===//
2884 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2886 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2887 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2888 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2889 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2891 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2892 RegisterOperand RO> :
2893 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2894 !strconcat(instr_asm, "\t$rt, $addr")> ;
2895 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2897 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2898 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2899 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2900 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2902 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2904 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2907 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2908 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2909 "nor\t$rs, $rt, $imm">;
2910 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2911 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2912 simm32_relaxed:$imm)>, GPR_32;
2914 let hasDelaySlot = 1, isCTI = 1 in {
2915 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2916 (ins imm64:$imm64, brtarget:$offset),
2917 "bne\t$rt, $imm64, $offset">;
2918 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2919 (ins imm64:$imm64, brtarget:$offset),
2920 "beq\t$rt, $imm64, $offset">;
2922 class CondBranchPseudo<string instr_asm> :
2923 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2925 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2928 def BLT : CondBranchPseudo<"blt">;
2929 def BLE : CondBranchPseudo<"ble">;
2930 def BGE : CondBranchPseudo<"bge">;
2931 def BGT : CondBranchPseudo<"bgt">;
2932 def BLTU : CondBranchPseudo<"bltu">;
2933 def BLEU : CondBranchPseudo<"bleu">;
2934 def BGEU : CondBranchPseudo<"bgeu">;
2935 def BGTU : CondBranchPseudo<"bgtu">;
2936 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2937 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2938 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2939 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2940 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2941 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2942 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2943 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2946 class CondBranchImmPseudo<string instr_asm> :
2947 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2948 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2950 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2951 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2953 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2954 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2955 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2956 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2957 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2958 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2959 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2960 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2961 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2962 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2963 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2964 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2965 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2966 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2967 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2968 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2970 // FIXME: Predicates are removed because instructions are matched regardless of
2971 // predicates, because PredicateControl was not in the hierarchy. This was
2972 // done to emit more precise error message from expansion function.
2973 // Once the tablegen-erated errors are made better, this needs to be fixed and
2974 // predicates needs to be restored.
2976 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2977 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2978 "div\t$rd, $rs, $rt">,
2979 ISA_MIPS1_NOT_32R6_64R6;
2980 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2981 (ins GPR32Opnd:$rs, simm32:$imm),
2982 "div\t$rd, $rs, $imm">,
2983 ISA_MIPS1_NOT_32R6_64R6;
2984 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2985 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2986 "divu\t$rd, $rs, $rt">,
2987 ISA_MIPS1_NOT_32R6_64R6;
2988 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2989 (ins GPR32Opnd:$rs, simm32:$imm),
2990 "divu\t$rd, $rs, $imm">,
2991 ISA_MIPS1_NOT_32R6_64R6;
2994 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
2996 ISA_MIPS1_NOT_32R6_64R6;
2997 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
2998 GPR32NonZeroOpnd:$rs,
3000 ISA_MIPS1_NOT_32R6_64R6;
3001 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3003 ISA_MIPS1_NOT_32R6_64R6;
3005 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
3007 ISA_MIPS1_NOT_32R6_64R6;
3008 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
3009 GPR32NonZeroOpnd:$rt,
3011 ISA_MIPS1_NOT_32R6_64R6;
3013 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3015 ISA_MIPS1_NOT_32R6_64R6;
3017 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3018 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3019 "rem\t$rd, $rs, $rt">,
3020 ISA_MIPS1_NOT_32R6_64R6;
3021 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3022 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3023 "rem\t$rd, $rs, $imm">,
3024 ISA_MIPS1_NOT_32R6_64R6;
3025 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3026 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3027 "remu\t$rd, $rs, $rt">,
3028 ISA_MIPS1_NOT_32R6_64R6;
3029 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3030 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3031 "remu\t$rd, $rs, $imm">,
3032 ISA_MIPS1_NOT_32R6_64R6;
3034 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3036 ISA_MIPS1_NOT_32R6_64R6;
3037 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3038 simm32_relaxed:$imm), 0>,
3039 ISA_MIPS1_NOT_32R6_64R6;
3040 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3042 ISA_MIPS1_NOT_32R6_64R6;
3043 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3044 simm32_relaxed:$imm), 0>,
3045 ISA_MIPS1_NOT_32R6_64R6;
3047 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3048 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3050 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3051 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3053 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3054 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3056 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3057 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3059 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3060 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3062 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3063 (ins mem_simm16:$addr), "ld $rt, $addr">,
3064 ISA_MIPS1_NOT_MIPS3;
3065 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3066 (ins mem_simm16:$addr), "sd $rt, $addr">,
3067 ISA_MIPS1_NOT_MIPS3;
3068 //===----------------------------------------------------------------------===//
3069 // Arbitrary patterns that map to one or more instructions
3070 //===----------------------------------------------------------------------===//
3072 // Load/store pattern templates.
3073 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3074 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3076 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3077 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3079 // Materialize constants.
3080 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3081 Instruction ADDiuOp, Instruction LUiOp,
3082 Instruction ORiOp> {
3084 // Constant synthesis previously relied on the ordering of the patterns below.
3085 // By making the predicates they use non-overlapping, the patterns were
3086 // reordered so that the effect of the newly introduced predicates can be
3089 // Arbitrary immediates
3090 def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3092 // Bits 32-16 set, sign/zero extended.
3093 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3096 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3097 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3100 let AdditionalPredicates = [NotInMicroMips] in
3101 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3103 // Carry MipsPatterns
3104 let AdditionalPredicates = [NotInMicroMips] in {
3105 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3106 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3108 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3109 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3110 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3111 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3113 // Support multiplication for pre-Mips32 targets that don't have
3114 // the MUL instruction.
3115 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3116 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3117 ISA_MIPS1_NOT_32R6_64R6;
3120 def : MipsPat<(MipsSync (i32 immz)),
3121 (SYNC 0)>, ISA_MIPS2;
3124 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3125 (JAL texternalsym:$dst)>, ISA_MIPS1;
3126 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3127 // (JALR GPR32:$dst)>;
3130 let AdditionalPredicates = [NotInMicroMips] in {
3131 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3132 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3133 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3134 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3137 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3138 Register ZeroReg, RegisterOperand GPROpnd> {
3139 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3140 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3141 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3142 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3143 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3145 def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>;
3146 def : MipsPat<(MipsLo tblockaddress:$in),
3147 (Addiu ZeroReg, tblockaddress:$in)>;
3148 def : MipsPat<(MipsLo tjumptable:$in), (Addiu ZeroReg, tjumptable:$in)>;
3149 def : MipsPat<(MipsLo tconstpool:$in), (Addiu ZeroReg, tconstpool:$in)>;
3150 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3151 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3152 def : MipsPat<(MipsLo texternalsym:$in), (Addiu ZeroReg, texternalsym:$in)>;
3154 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3155 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3156 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3157 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3158 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3159 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3160 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3161 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3162 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3163 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3167 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3168 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3170 let AdditionalPredicates = [NotInMicroMips] in {
3171 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3173 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3174 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3177 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3181 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3182 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3183 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3184 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3186 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3187 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3188 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3189 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3190 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3191 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3193 // Mips does not have "not", so we expand our way
3194 def : MipsPat<(not GPR32:$in),
3195 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3199 let AdditionalPredicates = [NotInMicroMips] in {
3200 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3201 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3202 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3205 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3209 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3210 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3211 Instruction SLTiOp, Instruction SLTiuOp,
3213 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3214 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3215 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3216 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3218 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3219 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3220 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3221 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3222 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3223 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3224 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3225 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3226 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3227 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3228 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3229 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3231 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3232 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3233 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3234 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3236 def : MipsPat<(brcond RC:$cond, bb:$dst),
3237 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3239 let AdditionalPredicates = [NotInMicroMips] in {
3240 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3242 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3243 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3244 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3245 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3249 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3250 Instruction SLTuOp, Register ZEROReg> {
3251 def : MipsPat<(seteq RC:$lhs, 0),
3252 (SLTiuOp RC:$lhs, 1)>;
3253 def : MipsPat<(setne RC:$lhs, 0),
3254 (SLTuOp ZEROReg, RC:$lhs)>;
3255 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3256 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3257 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3258 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3261 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3262 Instruction SLTuOp> {
3263 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3264 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3265 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3266 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3269 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3270 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3271 (SLTOp RC:$rhs, RC:$lhs)>;
3272 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3273 (SLTuOp RC:$rhs, RC:$lhs)>;
3276 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3277 Instruction SLTuOp> {
3278 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3279 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3280 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3281 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3284 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3285 Instruction SLTiOp, Instruction SLTiuOp> {
3286 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3287 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3288 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3289 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3292 let AdditionalPredicates = [NotInMicroMips] in {
3293 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3294 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3295 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3296 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3297 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3300 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3303 // Load halfword/word patterns.
3304 let AdditionalPredicates = [NotInMicroMips] in {
3305 let AddedComplexity = 40 in {
3306 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3307 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3308 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3309 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3310 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3313 // Atomic load patterns.
3314 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3315 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3316 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3318 // Atomic store patterns.
3319 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>,
3321 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>,
3323 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>,
3327 //===----------------------------------------------------------------------===//
3328 // Floating Point Support
3329 //===----------------------------------------------------------------------===//
3331 include "MipsInstrFPU.td"
3332 include "Mips64InstrInfo.td"
3333 include "MipsCondMov.td"
3335 include "Mips32r6InstrInfo.td"
3336 include "Mips64r6InstrInfo.td"
3341 include "Mips16InstrFormats.td"
3342 include "Mips16InstrInfo.td"
3345 include "MipsDSPInstrFormats.td"
3346 include "MipsDSPInstrInfo.td"
3349 include "MipsMSAInstrFormats.td"
3350 include "MipsMSAInstrInfo.td"
3353 include "MipsEVAInstrFormats.td"
3354 include "MipsEVAInstrInfo.td"
3357 include "MipsMTInstrFormats.td"
3358 include "MipsMTInstrInfo.td"
3361 include "MicroMipsInstrFormats.td"
3362 include "MicroMipsInstrInfo.td"
3363 include "MicroMipsInstrFPU.td"
3366 include "MicroMips32r6InstrFormats.td"
3367 include "MicroMips32r6InstrInfo.td"
3370 include "MicroMipsDSPInstrFormats.td"
3371 include "MicroMipsDSPInstrInfo.td"