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()); }]>;
1266 def timmZExt7 : PatLeaf<(timm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1268 // Node immediate fits as 16-bit zero extended on target immediate.
1269 // The LO16 param means that only the lower 16 bits of the node
1270 // immediate are caught.
1271 // e.g. addiu, sltiu
1272 def immZExt16 : PatLeaf<(imm), [{
1273 if (N->getValueType(0) == MVT::i32)
1274 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1276 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1279 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1280 def immSExt32Low16Zero : PatLeaf<(imm), [{
1281 int64_t Val = N->getSExtValue();
1282 return isInt<32>(Val) && !(Val & 0xffff);
1285 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1286 def immZExt32Low16Zero : PatLeaf<(imm), [{
1287 uint64_t Val = N->getZExtValue();
1288 return isUInt<32>(Val) && !(Val & 0xffff);
1291 // Note immediate fits as a 32 bit signed extended on target immediate.
1292 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1294 // Note immediate fits as a 32 bit zero extended on target immediate.
1295 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1297 // shamt field must fit in 5 bits.
1298 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1299 def timmZExt5 : TImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1301 def immZExt5Plus1 : PatLeaf<(imm), [{
1302 return isUInt<5>(N->getZExtValue() - 1);
1304 def immZExt5Plus32 : PatLeaf<(imm), [{
1305 return isUInt<5>(N->getZExtValue() - 32);
1307 def immZExt5Plus33 : PatLeaf<(imm), [{
1308 return isUInt<5>(N->getZExtValue() - 33);
1311 def immZExt5To31 : SDNodeXForm<imm, [{
1312 return getImm(N, 31 - N->getZExtValue());
1315 // True if (N + 1) fits in 16-bit field.
1316 def immSExt16Plus1 : PatLeaf<(imm), [{
1317 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1320 def immZExtRange2To64 : PatLeaf<(imm), [{
1321 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1322 (N->getZExtValue() <= 64);
1325 def ORiPred : PatLeaf<(imm), [{
1326 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1329 def LUiPred : PatLeaf<(imm), [{
1330 int64_t Val = N->getSExtValue();
1331 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1334 def LUiORiPred : PatLeaf<(imm), [{
1335 int64_t SVal = N->getSExtValue();
1336 return isInt<32>(SVal) && (SVal & 0xffff);
1339 // Mips Address Mode! SDNode frameindex could possibily be a match
1340 // since load and store instructions from stack used it.
1342 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1345 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1348 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1350 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1351 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1353 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1355 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1358 //===----------------------------------------------------------------------===//
1359 // Instructions specific format
1360 //===----------------------------------------------------------------------===//
1362 // Arithmetic and logical instructions with 3 register operands.
1363 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1364 InstrItinClass Itin = NoItinerary,
1365 SDPatternOperator OpNode = null_frag>:
1366 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1367 !strconcat(opstr, "\t$rd, $rs, $rt"),
1368 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1369 let isCommutable = isComm;
1370 let isReMaterializable = 1;
1371 let TwoOperandAliasConstraint = "$rd = $rs";
1374 // Arithmetic and logical instructions with 2 register operands.
1375 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1376 InstrItinClass Itin = NoItinerary,
1377 SDPatternOperator imm_type = null_frag,
1378 SDPatternOperator OpNode = null_frag> :
1379 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1380 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1381 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1382 Itin, FrmI, opstr> {
1383 let isReMaterializable = 1;
1384 let TwoOperandAliasConstraint = "$rs = $rt";
1387 // Arithmetic Multiply ADD/SUB
1388 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1389 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1390 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1391 let Defs = [HI0, LO0];
1392 let Uses = [HI0, LO0];
1393 let isCommutable = isComm;
1397 class LogicNOR<string opstr, RegisterOperand RO>:
1398 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1399 !strconcat(opstr, "\t$rd, $rs, $rt"),
1400 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1401 let isCommutable = 1;
1405 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1406 RegisterOperand RO, InstrItinClass itin,
1407 SDPatternOperator OpNode = null_frag,
1408 SDPatternOperator PF = null_frag> :
1409 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1410 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1411 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1412 let TwoOperandAliasConstraint = "$rt = $rd";
1415 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1416 SDPatternOperator OpNode = null_frag>:
1417 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1418 !strconcat(opstr, "\t$rd, $rt, $rs"),
1419 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1422 // Load Upper Immediate
1423 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1424 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1425 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1426 let hasSideEffects = 0;
1427 let isReMaterializable = 1;
1430 // Memory Load/Store
1431 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1432 SDPatternOperator OpNode = null_frag,
1433 InstrItinClass Itin = NoItinerary,
1434 ComplexPattern Addr = addr> :
1435 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1436 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1437 let DecoderMethod = "DecodeMem";
1438 let canFoldAsLoad = 1;
1439 string BaseOpcode = opstr;
1443 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1444 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1445 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1447 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1448 SDPatternOperator OpNode = null_frag,
1449 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1450 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1451 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1452 let DecoderMethod = "DecodeMem";
1453 string BaseOpcode = opstr;
1457 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1458 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1459 DAGOperand MO = mem> :
1460 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1462 // Load/Store Left/Right
1463 let canFoldAsLoad = 1 in
1464 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1465 InstrItinClass Itin> :
1466 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1467 !strconcat(opstr, "\t$rt, $addr"),
1468 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1469 let DecoderMethod = "DecodeMem";
1470 string Constraints = "$src = $rt";
1471 let BaseOpcode = opstr;
1474 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1475 InstrItinClass Itin> :
1476 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1477 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1478 let DecoderMethod = "DecodeMem";
1479 let BaseOpcode = opstr;
1483 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1484 SDPatternOperator OpNode= null_frag> :
1485 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1486 !strconcat(opstr, "\t$rt, $addr"),
1487 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1488 let DecoderMethod = "DecodeFMem2";
1492 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1493 SDPatternOperator OpNode= null_frag> :
1494 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1495 !strconcat(opstr, "\t$rt, $addr"),
1496 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1497 let DecoderMethod = "DecodeFMem2";
1502 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1503 SDPatternOperator OpNode= null_frag> :
1504 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1505 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1506 let DecoderMethod = "DecodeFMem3";
1510 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1511 SDPatternOperator OpNode= null_frag> :
1512 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1513 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1514 let DecoderMethod = "DecodeFMem3";
1518 // Conditional Branch
1519 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1520 RegisterOperand RO> :
1521 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1522 !strconcat(opstr, "\t$rs, $rt, $offset"),
1523 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1526 let isTerminator = 1;
1527 let hasDelaySlot = 1;
1532 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1533 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1534 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1536 let isTerminator = 1;
1537 let hasDelaySlot = 1;
1542 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1543 RegisterOperand RO> :
1544 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1545 !strconcat(opstr, "\t$rs, $offset"),
1546 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1549 let isTerminator = 1;
1550 let hasDelaySlot = 1;
1555 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1556 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1557 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1559 let isTerminator = 1;
1560 let hasDelaySlot = 1;
1566 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1567 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1568 !strconcat(opstr, "\t$rd, $rs, $rt"),
1569 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1570 II_SLT_SLTU, FrmR, opstr>;
1572 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1573 RegisterOperand RO>:
1574 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1575 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1576 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1577 II_SLTI_SLTIU, FrmI, opstr>;
1580 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1581 SDPatternOperator targetoperator, string bopstr> :
1582 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1583 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1586 let hasDelaySlot = 1;
1587 let DecoderMethod = "DecodeJumpTarget";
1592 // Unconditional branch
1593 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1594 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1595 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1597 let isTerminator = 1;
1599 let hasDelaySlot = 1;
1600 let AdditionalPredicates = [RelocPIC];
1605 // Base class for indirect branch and return instruction classes.
1606 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1607 class JumpFR<string opstr, RegisterOperand RO,
1608 SDPatternOperator operator = null_frag>:
1609 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1613 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1615 let isIndirectBranch = 1;
1618 // Jump and Link (Call)
1619 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1620 class JumpLink<string opstr, DAGOperand opnd> :
1621 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1622 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1623 let DecoderMethod = "DecodeJumpTarget";
1626 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1627 Register RetReg, RegisterOperand ResRO = RO>:
1628 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1629 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> {
1630 let hasPostISelHook = 1;
1633 class JumpLinkReg<string opstr, RegisterOperand RO>:
1634 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1635 [], II_JALR, FrmR, opstr> {
1636 let hasPostISelHook = 1;
1639 class BGEZAL_FT<string opstr, DAGOperand opnd,
1640 RegisterOperand RO> :
1641 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1642 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1643 let hasDelaySlot = 1;
1648 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1649 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1650 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1651 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1652 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1654 class TailCallReg<Instruction JumpInst, RegisterOperand RO> :
1655 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1656 PseudoInstExpansion<(JumpInst RO:$rs)> {
1657 let hasPostISelHook = 1;
1661 class BAL_BR_Pseudo<Instruction RealInst, DAGOperand opnd> :
1662 PseudoSE<(outs), (ins opnd:$offset), [], II_BCCZAL>,
1663 PseudoInstExpansion<(RealInst ZERO, opnd:$offset)> {
1665 let isTerminator = 1;
1667 let hasDelaySlot = 1;
1674 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1675 InstSE<(outs), (ins ImmOp:$code_),
1676 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1678 class BRK_FT<string opstr> :
1679 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1680 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1684 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1685 InstSE<(outs), (ins),
1686 opstr, [], itin, FrmOther, opstr>;
1689 class WAIT_FT<string opstr> :
1690 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1694 class DEI_FT<string opstr, RegisterOperand RO,
1695 InstrItinClass itin = NoItinerary> :
1696 InstSE<(outs RO:$rt), (ins),
1697 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1700 let hasSideEffects = 1 in
1701 class SYNC_FT<string opstr> :
1702 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1703 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1705 class SYNCI_FT<string opstr, DAGOperand MO> :
1706 InstSE<(outs), (ins MO:$addr), !strconcat(opstr, "\t$addr"), [],
1707 II_SYNCI, FrmOther, opstr> {
1708 let hasSideEffects = 1;
1709 let DecoderMethod = "DecodeSyncI";
1712 let hasSideEffects = 1, isCTI = 1 in {
1713 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1714 InstrItinClass itin = NoItinerary> :
1715 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1716 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1718 class TEQI_FT<string opstr, RegisterOperand RO,
1719 InstrItinClass itin = NoItinerary> :
1720 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1721 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1725 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1726 list<Register> DefRegs> :
1727 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1728 itin, FrmR, opstr> {
1729 let isCommutable = 1;
1731 let hasSideEffects = 0;
1734 // Pseudo multiply/divide instruction with explicit accumulator register
1736 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1737 SDPatternOperator OpNode, InstrItinClass Itin,
1738 bit IsComm = 1, bit HasSideEffects = 0,
1739 bit UsesCustomInserter = 0> :
1740 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1741 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1742 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1743 let isCommutable = IsComm;
1744 let hasSideEffects = HasSideEffects;
1745 let usesCustomInserter = UsesCustomInserter;
1748 // Pseudo multiply add/sub instruction with explicit accumulator register
1750 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1751 InstrItinClass itin>
1752 : PseudoSE<(outs ACC64:$ac),
1753 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1755 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1757 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1758 string Constraints = "$acin = $ac";
1761 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1762 list<Register> DefRegs> :
1763 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1764 [], itin, FrmR, opstr> {
1769 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1770 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1771 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1773 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1774 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1776 let Uses = [UseReg];
1777 let hasSideEffects = 0;
1781 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1782 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1783 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1786 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1787 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1790 let hasSideEffects = 0;
1794 class EffectiveAddress<string opstr, RegisterOperand RO> :
1795 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1796 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1797 !strconcat(opstr, "_lea")> {
1798 let isCodeGenOnly = 1;
1799 let hasNoSchedulingInfo = 1;
1800 let DecoderMethod = "DecodeMem";
1803 // Count Leading Ones/Zeros in Word
1804 class CountLeading0<string opstr, RegisterOperand RO,
1805 InstrItinClass itin = NoItinerary>:
1806 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1807 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1809 class CountLeading1<string opstr, RegisterOperand RO,
1810 InstrItinClass itin = NoItinerary>:
1811 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1812 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1814 // Sign Extend in Register.
1815 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1816 InstrItinClass itin> :
1817 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1818 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1821 class SubwordSwap<string opstr, RegisterOperand RO,
1822 InstrItinClass itin = NoItinerary>:
1823 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1825 let hasSideEffects = 0;
1829 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1830 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd, uimm8:$sel),
1831 "rdhwr\t$rt, $rd, $sel", [], II_RDHWR, FrmR, "rdhwr">;
1834 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1835 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1836 SDPatternOperator Op = null_frag> :
1837 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1838 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1839 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1842 // 'ins' and its' 64 bit variants are matched by C++ code.
1843 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1844 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1845 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1846 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1847 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1849 II_INS, FrmR, opstr> {
1850 let Constraints = "$src = $rt";
1853 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1854 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1855 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1856 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]> {
1857 let hasNoSchedulingInfo = 1;
1860 class Atomic2OpsPostRA<RegisterClass RC> :
1861 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr), []> {
1866 class Atomic2OpsSubwordPostRA<RegisterClass RC> :
1867 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$incr, RC:$mask, RC:$mask2,
1868 RC:$shiftamnt), []>;
1870 // Atomic Compare & Swap.
1871 // Atomic compare and swap is lowered into two stages. The first stage happens
1872 // during ISelLowering, which produces the PostRA version of this instruction.
1873 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1874 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1875 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]> {
1876 let hasNoSchedulingInfo = 1;
1879 class AtomicCmpSwapPostRA<RegisterClass RC> :
1880 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$cmp, RC:$swap), []> {
1885 class AtomicCmpSwapSubwordPostRA<RegisterClass RC> :
1886 PseudoSE<(outs RC:$dst), (ins PtrRC:$ptr, RC:$mask, RC:$ShiftCmpVal,
1887 RC:$mask2, RC:$ShiftNewVal, RC:$ShiftAmt), []> {
1892 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1893 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1894 [], II_LL, FrmI, opstr> {
1895 let DecoderMethod = "DecodeMem";
1899 class SCBase<string opstr, RegisterOperand RO> :
1900 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1901 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1902 let DecoderMethod = "DecodeMem";
1904 let Constraints = "$rt = $dst";
1907 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1908 InstrItinClass itin> :
1909 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1910 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1911 let BaseOpcode = asmstr;
1914 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1915 InstrItinClass itin> :
1916 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1917 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> {
1918 let BaseOpcode = asmstr;
1921 class TrapBase<Instruction RealInst>
1922 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1923 PseudoInstExpansion<(RealInst 0, 0)> {
1925 let isTerminator = 1;
1926 let isCodeGenOnly = 1;
1930 //===----------------------------------------------------------------------===//
1931 // Pseudo instructions
1932 //===----------------------------------------------------------------------===//
1935 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1936 let hasDelaySlot=1 in
1937 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1939 let hasSideEffects=1 in
1940 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1943 let Defs = [SP], Uses = [SP], hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
1944 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1945 [(callseq_start timm:$amt1, timm:$amt2)]>;
1946 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1947 [(callseq_end timm:$amt1, timm:$amt2)]>;
1950 let usesCustomInserter = 1 in {
1951 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1952 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1953 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1954 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1955 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1956 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1957 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1958 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1959 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1960 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1961 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1962 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1963 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1964 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1965 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1966 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1967 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1968 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1970 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1971 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1972 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1974 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1975 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1976 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1980 def ATOMIC_LOAD_ADD_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1981 def ATOMIC_LOAD_ADD_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1982 def ATOMIC_LOAD_ADD_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1983 def ATOMIC_LOAD_SUB_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1984 def ATOMIC_LOAD_SUB_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1985 def ATOMIC_LOAD_SUB_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1986 def ATOMIC_LOAD_AND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1987 def ATOMIC_LOAD_AND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1988 def ATOMIC_LOAD_AND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1989 def ATOMIC_LOAD_OR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1990 def ATOMIC_LOAD_OR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1991 def ATOMIC_LOAD_OR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1992 def ATOMIC_LOAD_XOR_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1993 def ATOMIC_LOAD_XOR_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1994 def ATOMIC_LOAD_XOR_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1995 def ATOMIC_LOAD_NAND_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1996 def ATOMIC_LOAD_NAND_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
1997 def ATOMIC_LOAD_NAND_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
1999 def ATOMIC_SWAP_I8_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2000 def ATOMIC_SWAP_I16_POSTRA : Atomic2OpsSubwordPostRA<GPR32>;
2001 def ATOMIC_SWAP_I32_POSTRA : Atomic2OpsPostRA<GPR32>;
2003 def ATOMIC_CMP_SWAP_I8_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
2004 def ATOMIC_CMP_SWAP_I16_POSTRA : AtomicCmpSwapSubwordPostRA<GPR32>;
2005 def ATOMIC_CMP_SWAP_I32_POSTRA : AtomicCmpSwapPostRA<GPR32>;
2007 /// Pseudo instructions for loading and storing accumulator registers.
2008 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
2009 def LOAD_ACC64 : Load<"", ACC64>;
2010 def STORE_ACC64 : Store<"", ACC64>;
2013 // We need these two pseudo instructions to avoid offset calculation for long
2014 // branches. See the comment in file MipsLongBranch.cpp for detailed
2017 // Expands to: lui $dst, %highest/%higher/%hi/%lo($tgt - $baltgt)
2018 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
2019 (ins brtarget:$tgt, brtarget:$baltgt), []> {
2020 bit hasNoSchedulingInfo = 1;
2022 // Expands to: lui $dst, highest/%higher/%hi/%lo($tgt)
2023 def LONG_BRANCH_LUi2Op : PseudoSE<(outs GPR32Opnd:$dst),
2024 (ins brtarget:$tgt), []> {
2025 bit hasNoSchedulingInfo = 1;
2028 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt - $baltgt)
2029 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
2030 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []> {
2031 bit hasNoSchedulingInfo = 1;
2033 // Expands to: addiu $dst, $src, %highest/%higher/%hi/%lo($tgt)
2034 def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
2035 (ins GPR32Opnd:$src, brtarget:$tgt), []> {
2036 bit hasNoSchedulingInfo = 1;
2039 //===----------------------------------------------------------------------===//
2040 // Instruction definition
2041 //===----------------------------------------------------------------------===//
2042 //===----------------------------------------------------------------------===//
2043 // MipsI Instructions
2044 //===----------------------------------------------------------------------===//
2046 /// Arithmetic Instructions (ALU Immediate)
2047 let AdditionalPredicates = [NotInMicroMips] in {
2048 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
2049 II_ADDIU, immSExt16, add>,
2050 ADDI_FM<0x9>, IsAsCheapAsAMove, ISA_MIPS1;
2052 def ANDi : MMRel, StdMMR6Rel,
2053 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
2054 ADDI_FM<0xc>, ISA_MIPS1;
2055 def ORi : MMRel, StdMMR6Rel,
2056 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
2057 ADDI_FM<0xd>, ISA_MIPS1;
2058 def XORi : MMRel, StdMMR6Rel,
2059 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
2060 ADDI_FM<0xe>, ISA_MIPS1;
2061 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>,
2062 ADDI_FM<0x8>, ISA_MIPS1_NOT_32R6_64R6;
2063 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
2064 SLTI_FM<0xa>, ISA_MIPS1;
2065 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
2066 SLTI_FM<0xb>, ISA_MIPS1;
2068 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM,
2071 /// Arithmetic Instructions (3-Operand, R-Type)
2072 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
2073 ADD_FM<0, 0x21>, ISA_MIPS1;
2074 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
2075 ADD_FM<0, 0x23>, ISA_MIPS1;
2077 let Defs = [HI0, LO0] in
2078 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
2079 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
2081 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>,
2082 ADD_FM<0, 0x20>, ISA_MIPS1;
2083 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>,
2084 ADD_FM<0, 0x22>, ISA_MIPS1;
2086 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>,
2088 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>,
2090 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
2091 ADD_FM<0, 0x24>, ISA_MIPS1;
2092 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
2093 ADD_FM<0, 0x25>, ISA_MIPS1;
2094 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
2095 ADD_FM<0, 0x26>, ISA_MIPS1;
2096 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>,
2100 let AdditionalPredicates = [NotInMicroMips] in {
2101 /// Shift Instructions
2102 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
2103 immZExt5>, SRA_FM<0, 0>, ISA_MIPS1;
2104 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
2105 immZExt5>, SRA_FM<2, 0>, ISA_MIPS1;
2106 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
2107 immZExt5>, SRA_FM<3, 0>, ISA_MIPS1;
2108 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
2109 SRLV_FM<4, 0>, ISA_MIPS1;
2110 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
2111 SRLV_FM<6, 0>, ISA_MIPS1;
2112 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
2113 SRLV_FM<7, 0>, ISA_MIPS1;
2115 // Rotate Instructions
2116 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
2118 SRA_FM<2, 1>, ISA_MIPS32R2;
2119 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
2120 SRLV_FM<6, 1>, ISA_MIPS32R2;
2123 /// Load and Store Instructions
2125 let AdditionalPredicates = [NotInMicroMips] in {
2126 def LB : LoadMemory<"lb", GPR32Opnd, mem_simmptr, sextloadi8, II_LB>, MMRel,
2127 LW_FM<0x20>, ISA_MIPS1;
2128 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simmptr, zextloadi8, II_LBU,
2129 addrDefault>, MMRel, LW_FM<0x24>, ISA_MIPS1;
2130 def LH : LoadMemory<"lh", GPR32Opnd, mem_simmptr, sextloadi16, II_LH,
2131 addrDefault>, MMRel, LW_FM<0x21>, ISA_MIPS1;
2132 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simmptr, zextloadi16, II_LHU>,
2133 MMRel, LW_FM<0x25>, ISA_MIPS1;
2134 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
2135 LW_FM<0x23>, ISA_MIPS1;
2136 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
2137 LW_FM<0x28>, ISA_MIPS1;
2138 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>,
2140 def SW : StdMMR6Rel, Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>, ISA_MIPS1;
2143 /// load/store left/right
2144 let AdditionalPredicates = [NotInMicroMips] in {
2145 def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
2146 ISA_MIPS1_NOT_32R6_64R6;
2147 def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
2148 ISA_MIPS1_NOT_32R6_64R6;
2149 def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
2150 ISA_MIPS1_NOT_32R6_64R6;
2151 def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
2152 ISA_MIPS1_NOT_32R6_64R6;
2154 // COP2 Memory Instructions
2155 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
2156 ISA_MIPS1_NOT_32R6_64R6;
2157 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
2158 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
2159 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
2160 ISA_MIPS2_NOT_32R6_64R6;
2161 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
2162 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
2164 // COP3 Memory Instructions
2165 let DecoderNamespace = "COP3_" in {
2166 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>,
2167 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2168 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>,
2169 ISA_MIPS1_NOT_32R6_64R6, NOT_ASE_CNMIPS;
2170 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
2171 ISA_MIPS2, NOT_ASE_CNMIPS;
2172 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
2173 ISA_MIPS2, NOT_ASE_CNMIPS;
2176 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
2177 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci", mem_simm16>, SYNCI_FM,
2181 let AdditionalPredicates = [NotInMicroMips] in {
2182 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>,
2184 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>,
2186 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>,
2188 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>,
2190 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>,
2192 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>,
2195 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
2196 ISA_MIPS2_NOT_32R6_64R6;
2197 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2198 ISA_MIPS2_NOT_32R6_64R6;
2199 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2200 ISA_MIPS2_NOT_32R6_64R6;
2201 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2202 ISA_MIPS2_NOT_32R6_64R6;
2203 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2204 ISA_MIPS2_NOT_32R6_64R6;
2205 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2206 ISA_MIPS2_NOT_32R6_64R6;
2209 let AdditionalPredicates = [NotInMicroMips] in {
2210 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>, ISA_MIPS1;
2211 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>,
2213 def TRAP : TrapBase<BREAK>, ISA_MIPS1;
2214 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM,
2215 ISA_MIPS32_NOT_32R6_64R6;
2217 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2218 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>,
2220 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2222 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>,
2224 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>,
2227 def WAIT : MMRel, StdMMR6Rel, WAIT_FT<"wait">, WAIT_FM, INSN_MIPS3_32;
2230 let AdditionalPredicates = [NotInMicroMips] in {
2231 /// Load-linked, Store-conditional
2232 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2233 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2235 /// Jump and Branch Instructions
2236 let AdditionalPredicates = [NotInMicroMips, RelocNotPIC] in
2237 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2238 IsBranch, ISA_MIPS1;
2240 let AdditionalPredicates = [NotInMicroMips] in {
2241 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
2242 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>,
2244 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2245 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2246 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>,
2248 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2249 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2250 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2251 BGEZ_FM<1, 1>, ISA_MIPS1;
2252 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2253 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2254 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2255 BGEZ_FM<7, 0>, ISA_MIPS1;
2256 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2257 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2258 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2259 BGEZ_FM<6, 0>, ISA_MIPS1;
2260 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2261 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2262 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2263 BGEZ_FM<1, 0>, ISA_MIPS1;
2264 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2265 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2266 def B : UncondBranch<BEQ, brtarget>, ISA_MIPS1;
2268 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>, ISA_MIPS1;
2272 let AdditionalPredicates = [NotInMicroMips, NoIndirectJumpGuards] in {
2273 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM, ISA_MIPS1;
2274 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>, ISA_MIPS1;
2277 let AdditionalPredicates = [NotInMicroMips] in {
2278 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2279 ISA_MIPS32_NOT_32R6_64R6;
2280 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2281 ISA_MIPS1_NOT_32R6_64R6;
2282 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2283 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2284 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2285 ISA_MIPS1_NOT_32R6_64R6;
2286 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2287 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2288 def BAL_BR : BAL_BR_Pseudo<BGEZAL, brtarget>, ISA_MIPS1;
2290 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2291 def TAILCALL : TailCall<J, jmptarget>, ISA_MIPS1;
2293 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2294 NoIndirectJumpGuards] in
2295 def TAILCALLREG : TailCallReg<JR, GPR32Opnd>, ISA_MIPS1_NOT_32R6_64R6;
2297 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2298 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2299 class PseudoIndirectBranchBase<Instruction JumpInst, RegisterOperand RO> :
2300 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2301 II_IndirectBranchPseudo>,
2302 PseudoInstExpansion<(JumpInst RO:$rs)> {
2305 let hasDelaySlot = 1;
2307 let isIndirectBranch = 1;
2311 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2312 NoIndirectJumpGuards] in
2313 def PseudoIndirectBranch : PseudoIndirectBranchBase<JR, GPR32Opnd>,
2314 ISA_MIPS1_NOT_32R6_64R6;
2316 // Return instructions are matched as a RetRA instruction, then are expanded
2317 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2318 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2320 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2321 [], II_ReturnPseudo> {
2322 let isTerminator = 1;
2324 let hasDelaySlot = 1;
2326 let isCodeGenOnly = 1;
2328 let hasExtraSrcRegAllocReq = 1;
2332 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2334 // Exception handling related node and instructions.
2335 // The conversion sequence is:
2336 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2337 // MIPSeh_return -> (stack change + indirect branch)
2339 // MIPSeh_return takes the place of regular return instruction
2340 // but takes two arguments (V1, V0) which are used for storing
2341 // the offset and return address respectively.
2342 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2344 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2345 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2347 let Uses = [V0, V1], isTerminator = 1, isReturn = 1,
2348 isBarrier = 1, isCTI = 1, hasNoSchedulingInfo = 1 in {
2349 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2350 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2351 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, GPR64:$dst),
2352 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2355 /// Multiply and Divide Instructions.
2356 let AdditionalPredicates = [NotInMicroMips] in {
2357 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2358 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2359 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2360 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2361 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2362 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2363 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2364 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2365 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2366 ISA_MIPS1_NOT_32R6_64R6;
2367 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2368 ISA_MIPS1_NOT_32R6_64R6;
2369 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2370 ISA_MIPS1_NOT_32R6_64R6;
2371 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2372 ISA_MIPS1_NOT_32R6_64R6;
2374 /// Sign Ext In Register Instructions.
2375 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2376 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2377 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2378 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2381 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2382 ISA_MIPS32_NOT_32R6_64R6;
2383 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2384 ISA_MIPS32_NOT_32R6_64R6;
2386 /// Word Swap Bytes Within Halfwords
2387 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2391 def NOP : PseudoSE<(outs), (ins), []>,
2392 PseudoInstExpansion<(SLL ZERO, ZERO, 0)>, ISA_MIPS1;
2394 // FrameIndexes are legalized when they are operands from load/store
2395 // instructions. The same not happens for stack address copies, so an
2396 // add op with mem ComplexPattern is used and the stack address copy
2397 // can be matched. It's similar to Sparc LEA_ADDRi
2398 let AdditionalPredicates = [NotInMicroMips] in
2399 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>, ISA_MIPS1;
2402 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2403 ISA_MIPS32_NOT_32R6_64R6;
2404 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2405 ISA_MIPS32_NOT_32R6_64R6;
2406 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2407 ISA_MIPS32_NOT_32R6_64R6;
2408 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2409 ISA_MIPS32_NOT_32R6_64R6;
2412 let AdditionalPredicates = [NotDSP] in {
2413 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2414 ISA_MIPS1_NOT_32R6_64R6;
2415 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2416 ISA_MIPS1_NOT_32R6_64R6;
2417 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2418 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2419 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2420 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2421 ISA_MIPS32_NOT_32R6_64R6;
2422 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2423 ISA_MIPS32_NOT_32R6_64R6;
2424 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2425 ISA_MIPS32_NOT_32R6_64R6;
2426 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2427 ISA_MIPS32_NOT_32R6_64R6;
2430 let AdditionalPredicates = [NotInMicroMips] in {
2431 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2432 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2433 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2434 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2435 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM, ISA_MIPS1;
2436 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2437 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2438 immZExt5, immZExt5Plus1, MipsExt>,
2439 EXT_FM<0>, ISA_MIPS32R2;
2440 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2441 uimm5_inssize_plus1, immZExt5,
2443 EXT_FM<4>, ISA_MIPS32R2;
2445 /// Move Control Registers From/To CPU Registers
2446 let AdditionalPredicates = [NotInMicroMips] in {
2447 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>,
2448 MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1;
2449 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>,
2450 MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1;
2451 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>,
2452 MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1;
2453 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>,
2454 MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1;
2457 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2458 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2459 let AdditionalPredicates = [NotInMicroMips] in {
2460 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>,
2462 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>, ISA_MIPS1;
2465 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2469 // JR_HB and JALR_HB are defined here using the new style naming
2470 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2471 // and because of that it doesn't follow the naming convention of the
2472 // rest of the file. To avoid a mixture of old vs new style, the new
2473 // style was chosen.
2474 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2475 dag OutOperandList = (outs);
2476 dag InOperandList = (ins GPROpnd:$rs);
2477 string AsmString = !strconcat(instr_asm, "\t$rs");
2478 list<dag> Pattern = [];
2481 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2482 dag OutOperandList = (outs GPROpnd:$rd);
2483 dag InOperandList = (ins GPROpnd:$rs);
2484 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2485 list<dag> Pattern = [];
2488 class JR_HB_DESC<RegisterOperand RO> :
2489 InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, JR_HB_DESC_BASE<"jr.hb", RO> {
2491 let isIndirectBranch=1;
2498 class JALR_HB_DESC<RegisterOperand RO> :
2499 InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, JALR_HB_DESC_BASE<"jalr.hb",
2501 let isIndirectBranch=1;
2506 class JR_HB_ENC : JR_HB_FM<8>;
2507 class JALR_HB_ENC : JALR_HB_FM<9>;
2509 def JR_HB : JR_HB_DESC<GPR32Opnd>, JR_HB_ENC, ISA_MIPS32R2_NOT_32R6_64R6;
2510 def JALR_HB : JALR_HB_DESC<GPR32Opnd>, JALR_HB_ENC, ISA_MIPS32;
2512 let AdditionalPredicates = [NotInMicroMips, UseIndirectJumpsHazard] in
2513 def JALRHBPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR_HB, RA>;
2516 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
2517 UseIndirectJumpsHazard] in {
2518 def TAILCALLREGHB : TailCallReg<JR_HB, GPR32Opnd>, ISA_MIPS32_NOT_32R6_64R6;
2519 def PseudoIndirectHazardBranch : PseudoIndirectBranchBase<JR_HB, GPR32Opnd>,
2520 ISA_MIPS32R2_NOT_32R6_64R6;
2523 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2524 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2525 let AdditionalPredicates = [NotInMicroMips] in {
2526 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>, ISA_MIPS1;
2527 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>, ISA_MIPS1;
2528 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>, ISA_MIPS1;
2529 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>, ISA_MIPS1;
2531 class CacheOp<string instr_asm, Operand MemOpnd,
2532 InstrItinClass itin = NoItinerary> :
2533 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2534 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2536 let DecoderMethod = "DecodeCacheOp";
2539 let AdditionalPredicates = [NotInMicroMips] in {
2540 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2541 INSN_MIPS3_32_NOT_32R6_64R6;
2542 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2543 INSN_MIPS3_32_NOT_32R6_64R6;
2545 // FIXME: We are missing the prefx instruction.
2546 def ROL : MipsAsmPseudoInst<(outs),
2547 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2548 "rol\t$rs, $rt, $rd">;
2549 def ROLImm : MipsAsmPseudoInst<(outs),
2550 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2551 "rol\t$rs, $rt, $imm">;
2552 def : MipsInstAlias<"rol $rd, $rs",
2553 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2554 def : MipsInstAlias<"rol $rd, $imm",
2555 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2557 def ROR : MipsAsmPseudoInst<(outs),
2558 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2559 "ror\t$rs, $rt, $rd">;
2560 def RORImm : MipsAsmPseudoInst<(outs),
2561 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2562 "ror\t$rs, $rt, $imm">;
2563 def : MipsInstAlias<"ror $rd, $rs",
2564 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2565 def : MipsInstAlias<"ror $rd, $imm",
2566 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2568 def DROL : MipsAsmPseudoInst<(outs),
2569 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2570 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2571 def DROLImm : MipsAsmPseudoInst<(outs),
2572 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2573 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2574 def : MipsInstAlias<"drol $rd, $rs",
2575 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2576 def : MipsInstAlias<"drol $rd, $imm",
2577 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2579 def DROR : MipsAsmPseudoInst<(outs),
2580 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2581 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2582 def DRORImm : MipsAsmPseudoInst<(outs),
2583 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2584 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2585 def : MipsInstAlias<"dror $rd, $rs",
2586 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2587 def : MipsInstAlias<"dror $rd, $imm",
2588 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2590 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2593 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2594 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2595 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2597 def : MipsInstAlias<"seq $rd, $rs",
2598 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2601 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2602 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2603 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2605 def : MipsInstAlias<"seq $rd, $imm",
2606 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2609 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2610 simm32_relaxed:$imm),
2611 "mul\t$rd, $rs, $imm">,
2612 ISA_MIPS1_NOT_32R6_64R6;
2613 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2615 "mulo\t$rd, $rs, $rt">,
2616 ISA_MIPS1_NOT_32R6_64R6;
2617 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2619 "mulou\t$rd, $rs, $rt">,
2620 ISA_MIPS1_NOT_32R6_64R6;
2622 // Virtualization ASE
2623 class HYPCALL_FT<string opstr> :
2624 InstSE<(outs), (ins uimm10:$code_),
2625 !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> {
2626 let BaseOpcode = opstr;
2629 let AdditionalPredicates = [NotInMicroMips] in {
2630 def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>,
2631 MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT;
2632 def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>,
2633 MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT;
2634 def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>,
2635 MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT;
2636 def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>,
2637 MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT;
2638 def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>,
2639 ISA_MIPS32R5, ASE_VIRT;
2640 def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>,
2641 ISA_MIPS32R5, ASE_VIRT;
2642 def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>,
2643 ISA_MIPS32R5, ASE_VIRT;
2644 def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>,
2645 ISA_MIPS32R5, ASE_VIRT;
2646 def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>,
2647 ISA_MIPS32R5, ASE_VIRT;
2648 def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>,
2649 ISA_MIPS32R5, ASE_VIRT;
2650 def HYPCALL : MMRel, HYPCALL_FT<"hypcall">,
2651 HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT;
2654 //===----------------------------------------------------------------------===//
2655 // Instruction aliases
2656 //===----------------------------------------------------------------------===//
2658 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2660 RegisterOperand RO = GPR32Opnd,
2661 Operand Imm = simm32_relaxed> {
2662 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2666 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2672 let AdditionalPredicates = [NotInMicroMips] in {
2673 def : MipsInstAlias<"move $dst, $src",
2674 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2676 def : MipsInstAlias<"move $dst, $src",
2677 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2680 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 1>,
2681 ISA_MIPS1_NOT_32R6_64R6;
2683 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>, ISA_MIPS1;
2685 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2687 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>,
2690 def : MipsInstAlias<"neg $rt, $rs",
2691 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2692 def : MipsInstAlias<"neg $rt",
2693 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2694 def : MipsInstAlias<"negu $rt, $rs",
2695 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS1;
2696 def : MipsInstAlias<"negu $rt",
2697 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>, ISA_MIPS1;
2699 def SGE : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2700 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2701 "sge\t$rd, $rs, $rt">, ISA_MIPS1;
2702 def : MipsInstAlias<"sge $rs, $rt",
2703 (SGE GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2705 def SGEImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2706 (ins GPR32Opnd:$rs, simm32:$imm),
2707 "sge\t$rd, $rs, $imm">, GPR_32;
2708 def : MipsInstAlias<"sge $rs, $imm", (SGEImm GPR32Opnd:$rs,
2713 def SGEU : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2714 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2715 "sgeu\t$rd, $rs, $rt">, ISA_MIPS1;
2716 def : MipsInstAlias<"sgeu $rs, $rt",
2717 (SGEU GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2719 def SGEUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2720 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2721 "sgeu\t$rd, $rs, $imm">, GPR_32;
2722 def : MipsInstAlias<"sgeu $rs, $imm", (SGEUImm GPR32Opnd:$rs,
2724 uimm32_coerced:$imm), 0>,
2727 def : MipsInstAlias<
2728 "sgt $rd, $rs, $rt",
2729 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2730 def : MipsInstAlias<
2732 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2734 def SGTImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2735 (ins GPR32Opnd:$rs, simm32:$imm),
2736 "sgt\t$rd, $rs, $imm">, GPR_32;
2737 def : MipsInstAlias<"sgt $rs, $imm", (SGTImm GPR32Opnd:$rs,
2741 def : MipsInstAlias<
2742 "sgtu $rd, $rs, $rt",
2743 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2744 def : MipsInstAlias<
2746 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS1;
2748 def SGTUImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2749 (ins GPR32Opnd:$rs, uimm32_coerced:$imm),
2750 "sgtu\t$rd, $rs, $imm">, GPR_32;
2751 def : MipsInstAlias<"sgtu $rs, $imm", (SGTUImm GPR32Opnd:$rs,
2753 uimm32_coerced:$imm), 0>,
2756 def : MipsInstAlias<
2758 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>, ISA_MIPS1;
2759 def : MipsInstAlias<
2761 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>, ISA_MIPS1;
2763 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>, ISA_MIPS1;
2765 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
2767 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>, ISA_MIPS1;
2769 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, ISA_MIPS1, GPR_32;
2771 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, ISA_MIPS1, GPR_32;
2773 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, ISA_MIPS1, GPR_32;
2775 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, ISA_MIPS1, GPR_32;
2777 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, ISA_MIPS1, GPR_32;
2779 def : MipsInstAlias<"mfgc0 $rt, $rd",
2780 (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2781 ISA_MIPS32R5, ASE_VIRT;
2782 def : MipsInstAlias<"mtgc0 $rt, $rd",
2783 (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2784 ISA_MIPS32R5, ASE_VIRT;
2785 def : MipsInstAlias<"mfhgc0 $rt, $rd",
2786 (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2787 ISA_MIPS32R5, ASE_VIRT;
2788 def : MipsInstAlias<"mthgc0 $rt, $rd",
2789 (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2790 ISA_MIPS32R5, ASE_VIRT;
2791 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>,
2793 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2795 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>,
2797 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>,
2800 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>,
2803 def : MipsInstAlias<"bnez $rs,$offset",
2804 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2806 def : MipsInstAlias<"bnezl $rs, $offset",
2807 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2809 def : MipsInstAlias<"beqz $rs,$offset",
2810 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>,
2812 def : MipsInstAlias<"beqzl $rs, $offset",
2813 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 1>,
2816 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>, ISA_MIPS1;
2818 def : MipsInstAlias<"break", (BREAK 0, 0), 1>, ISA_MIPS1;
2819 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>, ISA_MIPS1;
2820 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2821 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2823 def : MipsInstAlias<"teq $rs, $rt",
2824 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2825 def : MipsInstAlias<"tge $rs, $rt",
2826 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2827 def : MipsInstAlias<"tgeu $rs, $rt",
2828 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2829 def : MipsInstAlias<"tlt $rs, $rt",
2830 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2831 def : MipsInstAlias<"tltu $rs, $rt",
2832 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2833 def : MipsInstAlias<"tne $rs, $rt",
2834 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2835 def : MipsInstAlias<"rdhwr $rt, $rs",
2836 (RDHWR GPR32Opnd:$rt, HWRegsOpnd:$rs, 0), 1>, ISA_MIPS1;
2839 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2840 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2841 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2842 def : MipsInstAlias<"sub $rs, $imm",
2843 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2844 0>, ISA_MIPS1_NOT_32R6_64R6;
2845 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2846 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2847 InvertedImOperand:$imm), 0>;
2848 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2849 InvertedImOperand:$imm), 0>;
2850 let AdditionalPredicates = [NotInMicroMips] in {
2851 def : MipsInstAlias<"sll $rd, $rt, $rs",
2852 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2853 def : MipsInstAlias<"sra $rd, $rt, $rs",
2854 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2855 def : MipsInstAlias<"srl $rd, $rt, $rs",
2856 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2857 def : MipsInstAlias<"sll $rd, $rt",
2858 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2859 def : MipsInstAlias<"sra $rd, $rt",
2860 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2861 def : MipsInstAlias<"srl $rd, $rt",
2862 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2863 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2865 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2868 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2869 let AdditionalPredicates = [NotInMicroMips] in
2870 def : MipsInstAlias<"sync", (SYNC 0), 1>, ISA_MIPS2;
2872 def : MipsInstAlias<"mulo $rs, $rt",
2873 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2874 ISA_MIPS1_NOT_32R6_64R6;
2875 def : MipsInstAlias<"mulou $rs, $rt",
2876 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2877 ISA_MIPS1_NOT_32R6_64R6;
2879 let AdditionalPredicates = [NotInMicroMips] in
2880 def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT;
2882 //===----------------------------------------------------------------------===//
2883 // Assembler Pseudo Instructions
2884 //===----------------------------------------------------------------------===//
2886 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2888 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2889 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2890 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2891 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2893 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2894 RegisterOperand RO> :
2895 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2896 !strconcat(instr_asm, "\t$rt, $addr")> ;
2897 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2899 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2900 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2901 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2902 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2904 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2906 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2909 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2910 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2911 "nor\t$rs, $rt, $imm">;
2912 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2913 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2914 simm32_relaxed:$imm)>, GPR_32;
2916 let hasDelaySlot = 1, isCTI = 1 in {
2917 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2918 (ins imm64:$imm64, brtarget:$offset),
2919 "bne\t$rt, $imm64, $offset">;
2920 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2921 (ins imm64:$imm64, brtarget:$offset),
2922 "beq\t$rt, $imm64, $offset">;
2924 class CondBranchPseudo<string instr_asm> :
2925 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2927 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2930 def BLT : CondBranchPseudo<"blt">;
2931 def BLE : CondBranchPseudo<"ble">;
2932 def BGE : CondBranchPseudo<"bge">;
2933 def BGT : CondBranchPseudo<"bgt">;
2934 def BLTU : CondBranchPseudo<"bltu">;
2935 def BLEU : CondBranchPseudo<"bleu">;
2936 def BGEU : CondBranchPseudo<"bgeu">;
2937 def BGTU : CondBranchPseudo<"bgtu">;
2938 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2939 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2940 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2941 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2942 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2943 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2944 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2945 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2948 class CondBranchImmPseudo<string instr_asm> :
2949 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2950 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2952 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2953 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2955 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2956 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2957 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2958 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2959 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2960 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2961 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2962 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2963 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2964 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2965 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2966 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2967 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2968 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2969 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2970 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2972 // FIXME: Predicates are removed because instructions are matched regardless of
2973 // predicates, because PredicateControl was not in the hierarchy. This was
2974 // done to emit more precise error message from expansion function.
2975 // Once the tablegen-erated errors are made better, this needs to be fixed and
2976 // predicates needs to be restored.
2978 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2979 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2980 "div\t$rd, $rs, $rt">,
2981 ISA_MIPS1_NOT_32R6_64R6;
2982 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2983 (ins GPR32Opnd:$rs, simm32:$imm),
2984 "div\t$rd, $rs, $imm">,
2985 ISA_MIPS1_NOT_32R6_64R6;
2986 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2987 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2988 "divu\t$rd, $rs, $rt">,
2989 ISA_MIPS1_NOT_32R6_64R6;
2990 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2991 (ins GPR32Opnd:$rs, simm32:$imm),
2992 "divu\t$rd, $rs, $imm">,
2993 ISA_MIPS1_NOT_32R6_64R6;
2996 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
2998 ISA_MIPS1_NOT_32R6_64R6;
2999 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
3000 GPR32NonZeroOpnd:$rs,
3002 ISA_MIPS1_NOT_32R6_64R6;
3003 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3005 ISA_MIPS1_NOT_32R6_64R6;
3007 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
3009 ISA_MIPS1_NOT_32R6_64R6;
3010 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
3011 GPR32NonZeroOpnd:$rt,
3013 ISA_MIPS1_NOT_32R6_64R6;
3015 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3017 ISA_MIPS1_NOT_32R6_64R6;
3019 def SRemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3020 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3021 "rem\t$rd, $rs, $rt">,
3022 ISA_MIPS1_NOT_32R6_64R6;
3023 def SRemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3024 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3025 "rem\t$rd, $rs, $imm">,
3026 ISA_MIPS1_NOT_32R6_64R6;
3027 def URemMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3028 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
3029 "remu\t$rd, $rs, $rt">,
3030 ISA_MIPS1_NOT_32R6_64R6;
3031 def URemIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
3032 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
3033 "remu\t$rd, $rs, $imm">,
3034 ISA_MIPS1_NOT_32R6_64R6;
3036 def : MipsInstAlias<"rem $rt, $rs", (SRemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3038 ISA_MIPS1_NOT_32R6_64R6;
3039 def : MipsInstAlias<"rem $rd, $imm", (SRemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3040 simm32_relaxed:$imm), 0>,
3041 ISA_MIPS1_NOT_32R6_64R6;
3042 def : MipsInstAlias<"remu $rt, $rs", (URemMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
3044 ISA_MIPS1_NOT_32R6_64R6;
3045 def : MipsInstAlias<"remu $rd, $imm", (URemIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
3046 simm32_relaxed:$imm), 0>,
3047 ISA_MIPS1_NOT_32R6_64R6;
3049 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3050 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3052 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3053 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3055 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3056 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3058 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3059 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3061 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
3062 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
3064 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3065 (ins mem_simm16:$addr), "ld $rt, $addr">,
3066 ISA_MIPS1_NOT_MIPS3;
3067 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
3068 (ins mem_simm16:$addr), "sd $rt, $addr">,
3069 ISA_MIPS1_NOT_MIPS3;
3070 //===----------------------------------------------------------------------===//
3071 // Arbitrary patterns that map to one or more instructions
3072 //===----------------------------------------------------------------------===//
3074 // Load/store pattern templates.
3075 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
3076 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
3078 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
3079 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
3081 // Materialize constants.
3082 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
3083 Instruction ADDiuOp, Instruction LUiOp,
3084 Instruction ORiOp> {
3086 // Constant synthesis previously relied on the ordering of the patterns below.
3087 // By making the predicates they use non-overlapping, the patterns were
3088 // reordered so that the effect of the newly introduced predicates can be
3091 // Arbitrary immediates
3092 def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
3094 // Bits 32-16 set, sign/zero extended.
3095 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
3098 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
3099 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
3102 let AdditionalPredicates = [NotInMicroMips] in
3103 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>, ISA_MIPS1;
3105 // Carry MipsPatterns
3106 let AdditionalPredicates = [NotInMicroMips] in {
3107 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
3108 (SUBu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1;
3110 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
3111 (ADDu GPR32:$lhs, GPR32:$rhs)>, ISA_MIPS1, ASE_NOT_DSP;
3112 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
3113 (ADDiu GPR32:$src, imm:$imm)>, ISA_MIPS1, ASE_NOT_DSP;
3115 // Support multiplication for pre-Mips32 targets that don't have
3116 // the MUL instruction.
3117 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
3118 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
3119 ISA_MIPS1_NOT_32R6_64R6;
3122 def : MipsPat<(MipsSync (i32 immz)),
3123 (SYNC 0)>, ISA_MIPS2;
3126 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
3127 (JAL texternalsym:$dst)>, ISA_MIPS1;
3128 //def : MipsPat<(MipsJmpLink GPR32:$dst),
3129 // (JALR GPR32:$dst)>;
3132 let AdditionalPredicates = [NotInMicroMips] in {
3133 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
3134 (TAILCALL tglobaladdr:$dst)>, ISA_MIPS1;
3135 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
3136 (TAILCALL texternalsym:$dst)>, ISA_MIPS1;
3139 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
3140 Register ZeroReg, RegisterOperand GPROpnd> {
3141 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
3142 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
3143 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
3144 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
3145 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
3147 def : MipsPat<(MipsLo tglobaladdr:$in),
3148 (Addiu ZeroReg, tglobaladdr:$in)>;
3149 def : MipsPat<(MipsLo tblockaddress:$in),
3150 (Addiu ZeroReg, tblockaddress:$in)>;
3151 def : MipsPat<(MipsLo tjumptable:$in),
3152 (Addiu ZeroReg, tjumptable:$in)>;
3153 def : MipsPat<(MipsLo tconstpool:$in),
3154 (Addiu ZeroReg, tconstpool:$in)>;
3155 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
3156 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
3157 def : MipsPat<(MipsLo texternalsym:$in),
3158 (Addiu ZeroReg, texternalsym:$in)>;
3160 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
3161 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
3162 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
3163 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
3164 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
3165 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
3166 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
3167 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
3168 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
3169 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
3170 def : MipsPat<(add GPROpnd:$hi, (MipsLo texternalsym:$lo)),
3171 (Addiu GPROpnd:$hi, texternalsym:$lo)>;
3175 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
3176 MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>;
3178 let AdditionalPredicates = [NotInMicroMips] in {
3179 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
3181 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
3182 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
3185 def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>,
3189 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
3190 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
3191 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
3192 (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
3194 def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
3195 def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
3196 def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
3197 def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
3198 def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
3199 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
3201 // Mips does not have "not", so we expand our way
3202 def : MipsPat<(not GPR32:$in),
3203 (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
3207 let AdditionalPredicates = [NotInMicroMips] in {
3208 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3209 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>, ISA_MIPS1;
3210 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>, ISA_MIPS1;
3213 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>, ISA_MIPS1;
3217 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
3218 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
3219 Instruction SLTiOp, Instruction SLTiuOp,
3221 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
3222 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
3223 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
3224 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
3226 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
3227 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3228 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
3229 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
3230 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3231 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3232 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
3233 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
3234 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3235 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3236 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
3237 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
3239 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
3240 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3241 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
3242 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
3244 def : MipsPat<(brcond RC:$cond, bb:$dst),
3245 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
3247 let AdditionalPredicates = [NotInMicroMips] in {
3248 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>,
3250 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
3251 (BLEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3252 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
3253 (BGEZ i32:$lhs, bb:$dst)>, ISA_MIPS1;
3257 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
3258 Instruction SLTuOp, Register ZEROReg> {
3259 def : MipsPat<(seteq RC:$lhs, 0),
3260 (SLTiuOp RC:$lhs, 1)>;
3261 def : MipsPat<(setne RC:$lhs, 0),
3262 (SLTuOp ZEROReg, RC:$lhs)>;
3263 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
3264 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
3265 def : MipsPat<(setne RC:$lhs, RC:$rhs),
3266 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
3269 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3270 Instruction SLTuOp> {
3271 def : MipsPat<(setle RC:$lhs, RC:$rhs),
3272 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
3273 def : MipsPat<(setule RC:$lhs, RC:$rhs),
3274 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
3277 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
3278 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
3279 (SLTOp RC:$rhs, RC:$lhs)>;
3280 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
3281 (SLTuOp RC:$rhs, RC:$lhs)>;
3284 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
3285 Instruction SLTuOp> {
3286 def : MipsPat<(setge RC:$lhs, RC:$rhs),
3287 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
3288 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
3289 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
3292 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
3293 Instruction SLTiOp, Instruction SLTiuOp> {
3294 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
3295 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
3296 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
3297 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
3300 let AdditionalPredicates = [NotInMicroMips] in {
3301 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>, ISA_MIPS1;
3302 defm : SetlePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3303 defm : SetgtPats<GPR32, SLT, SLTu>, ISA_MIPS1;
3304 defm : SetgePats<GPR32, XORi, SLT, SLTu>, ISA_MIPS1;
3305 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>, ISA_MIPS1;
3308 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>, ISA_MIPS32R2;
3311 // Load halfword/word patterns.
3312 let AdditionalPredicates = [NotInMicroMips] in {
3313 let AddedComplexity = 40 in {
3314 def : LoadRegImmPat<LBu, i32, zextloadi8>, ISA_MIPS1;
3315 def : LoadRegImmPat<LHu, i32, zextloadi16>, ISA_MIPS1;
3316 def : LoadRegImmPat<LB, i32, sextloadi8>, ISA_MIPS1;
3317 def : LoadRegImmPat<LH, i32, sextloadi16>, ISA_MIPS1;
3318 def : LoadRegImmPat<LW, i32, load>, ISA_MIPS1;
3321 // Atomic load patterns.
3322 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>, ISA_MIPS1;
3323 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>, ISA_MIPS1;
3324 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>, ISA_MIPS1;
3326 // Atomic store patterns.
3327 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>,
3329 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>,
3331 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>,
3335 //===----------------------------------------------------------------------===//
3336 // Floating Point Support
3337 //===----------------------------------------------------------------------===//
3339 include "MipsInstrFPU.td"
3340 include "Mips64InstrInfo.td"
3341 include "MipsCondMov.td"
3343 include "Mips32r6InstrInfo.td"
3344 include "Mips64r6InstrInfo.td"
3349 include "Mips16InstrFormats.td"
3350 include "Mips16InstrInfo.td"
3353 include "MipsDSPInstrFormats.td"
3354 include "MipsDSPInstrInfo.td"
3357 include "MipsMSAInstrFormats.td"
3358 include "MipsMSAInstrInfo.td"
3361 include "MipsEVAInstrFormats.td"
3362 include "MipsEVAInstrInfo.td"
3365 include "MipsMTInstrFormats.td"
3366 include "MipsMTInstrInfo.td"
3369 include "MicroMipsInstrFormats.td"
3370 include "MicroMipsInstrInfo.td"
3371 include "MicroMipsInstrFPU.td"
3374 include "MicroMips32r6InstrFormats.td"
3375 include "MicroMips32r6InstrInfo.td"
3378 include "MicroMipsDSPInstrFormats.td"
3379 include "MicroMipsDSPInstrInfo.td"