1 //===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Mips implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // Mips profiles and nodes
17 //===----------------------------------------------------------------------===//
19 def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
20 def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
24 def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
25 def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
26 def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
27 def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
28 SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
29 def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
31 def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
32 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
33 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
34 def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
36 def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
38 def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
40 def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
41 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
42 def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
43 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
46 def SDTMipsLoadLR : SDTypeProfile<1, 2,
47 [SDTCisInt<0>, SDTCisPtrTy<1>,
51 def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
52 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
56 def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
57 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
59 // Hi and Lo nodes are used to handle global addresses. Used on
60 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
61 // static model. (nothing to do with Mips Registers Hi and Lo)
62 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
63 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
64 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
66 // TlsGd node is used to handle General Dynamic TLS
67 def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
69 // TprelHi and TprelLo nodes are used to handle Local Exec TLS
70 def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>;
71 def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>;
74 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
77 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
78 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
80 // These are target-independent nodes, but have target-specific formats.
81 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
82 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
83 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
84 [SDNPHasChain, SDNPSideEffect,
85 SDNPOptInGlue, SDNPOutGlue]>;
87 // Nodes used to extract LO/HI registers.
88 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
89 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
91 // Node used to insert 32-bit integers to LOHI register pair.
92 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
95 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
96 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
99 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
100 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
101 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
102 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
105 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
106 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
107 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
109 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
112 // Target constant nodes that are not part of any isel patterns and remain
113 // unchanged can cause instructions with illegal operands to be emitted.
114 // Wrapper node patterns give the instruction selector a chance to replace
115 // target constant nodes that would otherwise remain unchanged with ADDiu
116 // nodes. Without these wrapper node patterns, the following conditional move
117 // instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
119 // movn %got(d)($gp), %got(c)($gp), $4
120 // This instruction is illegal since movn can take only register operands.
122 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
124 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
126 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
127 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
129 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
130 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
131 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
132 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
133 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
134 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
135 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
136 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
137 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
138 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
139 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
140 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
141 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
142 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
143 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
144 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146 //===----------------------------------------------------------------------===//
147 // Mips Instruction Predicate Definitions.
148 //===----------------------------------------------------------------------===//
149 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
150 AssemblerPredicate<"FeatureMips2">;
151 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
152 AssemblerPredicate<"FeatureMips3_32">;
153 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
154 AssemblerPredicate<"FeatureMips3_32r2">;
155 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
156 AssemblerPredicate<"FeatureMips3">;
157 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
158 AssemblerPredicate<"FeatureMips4_32">;
159 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
160 AssemblerPredicate<"FeatureMips4_32">;
161 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
162 AssemblerPredicate<"FeatureMips4_32r2">;
163 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
164 AssemblerPredicate<"FeatureMips5_32r2">;
165 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
166 AssemblerPredicate<"FeatureMips32">;
167 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
168 AssemblerPredicate<"FeatureMips32r2">;
169 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
170 AssemblerPredicate<"FeatureMips32r5">;
171 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
172 AssemblerPredicate<"FeatureMips32r6">;
173 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
174 AssemblerPredicate<"!FeatureMips32r6">;
175 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
176 AssemblerPredicate<"FeatureGP64Bit">;
177 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
178 AssemblerPredicate<"!FeatureGP64Bit">;
179 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
180 AssemblerPredicate<"FeatureMips64">;
181 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
182 AssemblerPredicate<"FeatureMips64r2">;
183 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
184 AssemblerPredicate<"FeatureMips64r6">;
185 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
186 AssemblerPredicate<"!FeatureMips64r6">;
187 def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
188 AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
189 def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
190 AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
191 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
192 AssemblerPredicate<"FeatureMips16">;
193 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
194 AssemblerPredicate<"FeatureCnMips">;
195 def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
196 def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">;
197 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
198 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
199 AssemblerPredicate<"!FeatureMips16">;
200 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
201 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
202 AssemblerPredicate<"FeatureMicroMips">;
203 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
204 AssemblerPredicate<"!FeatureMicroMips">;
205 def IsLE : Predicate<"Subtarget->isLittle()">;
206 def IsBE : Predicate<"!Subtarget->isLittle()">;
207 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
208 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
210 //===----------------------------------------------------------------------===//
211 // Mips GPR size adjectives.
212 // They are mutually exclusive.
213 //===----------------------------------------------------------------------===//
215 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
216 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
218 //===----------------------------------------------------------------------===//
219 // Mips ISA/ASE membership and instruction group membership adjectives.
220 // They are mutually exclusive.
221 //===----------------------------------------------------------------------===//
223 // FIXME: I'd prefer to use additive predicates to build the instruction sets
224 // but we are short on assembler feature bits at the moment. Using a
225 // subtractive predicate will hopefully keep us under the 32 predicate
226 // limit long enough to develop an alternative way to handle P1||P2
228 class ISA_MIPS1_NOT_4_32 {
229 list<Predicate> InsnPredicates = [NotMips4_32];
231 class ISA_MIPS1_NOT_32R6_64R6 {
232 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
234 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
235 class ISA_MIPS2_NOT_32R6_64R6 {
236 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
238 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
239 class ISA_MIPS3_NOT_32R6_64R6 {
240 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
242 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
243 class ISA_MIPS32_NOT_32R6_64R6 {
244 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
246 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
247 class ISA_MIPS32R2_NOT_32R6_64R6 {
248 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
250 class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
251 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
252 class ISA_MIPS64_NOT_64R6 {
253 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
255 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
256 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
257 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
258 class ISA_MICROMIPS32R6 {
259 list<Predicate> InsnPredicates = [HasMicroMips32r6];
261 class ISA_MICROMIPS64R6 {
262 list<Predicate> InsnPredicates = [HasMicroMips64r6];
265 // The portions of MIPS-III that were also added to MIPS32
266 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
268 // The portions of MIPS-III that were also added to MIPS32 but were removed in
269 // MIPS32r6 and MIPS64r6.
270 class INSN_MIPS3_32_NOT_32R6_64R6 {
271 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
274 // The portions of MIPS-III that were also added to MIPS32
275 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
277 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
278 // MIPS32r6 and MIPS64r6.
279 class INSN_MIPS4_32_NOT_32R6_64R6 {
280 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
283 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
284 // MIPS32r6 and MIPS64r6.
285 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
286 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
289 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
290 // MIPS32r6 and MIPS64r6.
291 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
292 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
295 //===----------------------------------------------------------------------===//
297 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
298 let EncodingPredicates = [HasStdEnc];
301 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
302 InstAlias<Asm, Result, Emit>, PredicateControl;
305 bit isCommutable = 1;
322 bit isTerminator = 1;
325 bit hasExtraSrcRegAllocReq = 1;
326 bit isCodeGenOnly = 1;
329 class IsAsCheapAsAMove {
330 bit isAsCheapAsAMove = 1;
333 class NeverHasSideEffects {
334 bit hasSideEffects = 0;
337 //===----------------------------------------------------------------------===//
338 // Instruction format superclass
339 //===----------------------------------------------------------------------===//
341 include "MipsInstrFormats.td"
343 //===----------------------------------------------------------------------===//
344 // Mips Operand, Complex Patterns and Transformations Definitions.
345 //===----------------------------------------------------------------------===//
347 def MipsJumpTargetAsmOperand : AsmOperandClass {
348 let Name = "JumpTarget";
349 let ParserMethod = "parseJumpTarget";
350 let PredicateMethod = "isImm";
351 let RenderMethod = "addImmOperands";
354 // Instruction operand types
355 def jmptarget : Operand<OtherVT> {
356 let EncoderMethod = "getJumpTargetOpValue";
357 let ParserMatchClass = MipsJumpTargetAsmOperand;
359 def brtarget : Operand<OtherVT> {
360 let EncoderMethod = "getBranchTargetOpValue";
361 let OperandType = "OPERAND_PCREL";
362 let DecoderMethod = "DecodeBranchTarget";
363 let ParserMatchClass = MipsJumpTargetAsmOperand;
365 def calltarget : Operand<iPTR> {
366 let EncoderMethod = "getJumpTargetOpValue";
367 let ParserMatchClass = MipsJumpTargetAsmOperand;
370 def imm64: Operand<i64>;
372 def simm9 : Operand<i32>;
373 def simm10 : Operand<i32>;
374 def simm11 : Operand<i32>;
376 def simm16 : Operand<i32> {
377 let DecoderMethod= "DecodeSimm16";
380 def simm19_lsl2 : Operand<i32> {
381 let EncoderMethod = "getSimm19Lsl2Encoding";
382 let DecoderMethod = "DecodeSimm19Lsl2";
383 let ParserMatchClass = MipsJumpTargetAsmOperand;
386 def simm18_lsl3 : Operand<i32> {
387 let EncoderMethod = "getSimm18Lsl3Encoding";
388 let DecoderMethod = "DecodeSimm18Lsl3";
389 let ParserMatchClass = MipsJumpTargetAsmOperand;
392 def simm20 : Operand<i32> {
395 def uimm20 : Operand<i32> {
398 def MipsUImm10AsmOperand : AsmOperandClass {
400 let RenderMethod = "addImmOperands";
401 let ParserMethod = "parseImm";
402 let PredicateMethod = "isUImm<10>";
405 def uimm10 : Operand<i32> {
406 let ParserMatchClass = MipsUImm10AsmOperand;
409 def simm16_64 : Operand<i64> {
410 let DecoderMethod = "DecodeSimm16";
414 def uimmz : Operand<i32> {
415 let PrintMethod = "printUnsignedImm";
419 def uimm2 : Operand<i32> {
420 let PrintMethod = "printUnsignedImm";
423 def uimm3 : Operand<i32> {
424 let PrintMethod = "printUnsignedImm";
427 def uimm5 : Operand<i32> {
428 let PrintMethod = "printUnsignedImm";
431 def uimm6 : Operand<i32> {
432 let PrintMethod = "printUnsignedImm";
435 def uimm16 : Operand<i32> {
436 let PrintMethod = "printUnsignedImm";
439 def pcrel16 : Operand<i32> {
442 def MipsMemAsmOperand : AsmOperandClass {
444 let ParserMethod = "parseMemOperand";
447 def MipsMemSimm11AsmOperand : AsmOperandClass {
448 let Name = "MemOffsetSimm11";
449 let SuperClasses = [MipsMemAsmOperand];
450 let RenderMethod = "addMemOperands";
451 let ParserMethod = "parseMemOperand";
452 let PredicateMethod = "isMemWithSimmOffset<11>";
455 def MipsMemSimm16AsmOperand : AsmOperandClass {
456 let Name = "MemOffsetSimm16";
457 let SuperClasses = [MipsMemAsmOperand];
458 let RenderMethod = "addMemOperands";
459 let ParserMethod = "parseMemOperand";
460 let PredicateMethod = "isMemWithSimmOffset<16>";
463 def MipsInvertedImmoperand : AsmOperandClass {
465 let RenderMethod = "addImmOperands";
466 let ParserMethod = "parseInvNum";
469 def InvertedImOperand : Operand<i32> {
470 let ParserMatchClass = MipsInvertedImmoperand;
473 def InvertedImOperand64 : Operand<i64> {
474 let ParserMatchClass = MipsInvertedImmoperand;
477 class mem_generic : Operand<iPTR> {
478 let PrintMethod = "printMemOperand";
479 let MIOperandInfo = (ops ptr_rc, simm16);
480 let EncoderMethod = "getMemEncoding";
481 let ParserMatchClass = MipsMemAsmOperand;
482 let OperandType = "OPERAND_MEMORY";
486 def mem : mem_generic;
488 // MSA specific address operand
489 def mem_msa : mem_generic {
490 let MIOperandInfo = (ops ptr_rc, simm10);
491 let EncoderMethod = "getMSAMemEncoding";
494 def mem_simm9 : mem_generic {
495 let MIOperandInfo = (ops ptr_rc, simm9);
496 let EncoderMethod = "getMemEncoding";
499 def mem_simm11 : mem_generic {
500 let MIOperandInfo = (ops ptr_rc, simm11);
501 let EncoderMethod = "getMemEncoding";
502 let ParserMatchClass = MipsMemSimm11AsmOperand;
505 def mem_simm16 : mem_generic {
506 let MIOperandInfo = (ops ptr_rc, simm16);
507 let EncoderMethod = "getMemEncoding";
508 let ParserMatchClass = MipsMemSimm16AsmOperand;
511 def mem_ea : Operand<iPTR> {
512 let PrintMethod = "printMemOperandEA";
513 let MIOperandInfo = (ops ptr_rc, simm16);
514 let EncoderMethod = "getMemEncoding";
515 let OperandType = "OPERAND_MEMORY";
518 def PtrRC : Operand<iPTR> {
519 let MIOperandInfo = (ops ptr_rc);
520 let DecoderMethod = "DecodePtrRegisterClass";
521 let ParserMatchClass = GPR32AsmOperand;
524 // size operand of ext instruction
525 def size_ext : Operand<i32> {
526 let EncoderMethod = "getSizeExtEncoding";
527 let DecoderMethod = "DecodeExtSize";
530 // size operand of ins instruction
531 def size_ins : Operand<i32> {
532 let EncoderMethod = "getSizeInsEncoding";
533 let DecoderMethod = "DecodeInsSize";
536 // Transformation Function - get the lower 16 bits.
537 def LO16 : SDNodeXForm<imm, [{
538 return getImm(N, N->getZExtValue() & 0xFFFF);
541 // Transformation Function - get the higher 16 bits.
542 def HI16 : SDNodeXForm<imm, [{
543 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
547 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
549 // Node immediate is zero (e.g. insve.d)
550 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
552 // Node immediate fits as 16-bit sign extended on target immediate.
554 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
556 // Node immediate fits as 16-bit sign extended on target immediate.
558 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
560 // Node immediate fits as 15-bit sign extended on target immediate.
562 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
564 // Node immediate fits as 16-bit zero extended on target immediate.
565 // The LO16 param means that only the lower 16 bits of the node
566 // immediate are caught.
568 def immZExt16 : PatLeaf<(imm), [{
569 if (N->getValueType(0) == MVT::i32)
570 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
572 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
575 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
576 def immLow16Zero : PatLeaf<(imm), [{
577 int64_t Val = N->getSExtValue();
578 return isInt<32>(Val) && !(Val & 0xffff);
581 // shamt field must fit in 5 bits.
582 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
584 // True if (N + 1) fits in 16-bit field.
585 def immSExt16Plus1 : PatLeaf<(imm), [{
586 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
589 // Mips Address Mode! SDNode frameindex could possibily be a match
590 // since load and store instructions from stack used it.
592 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
595 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
598 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
601 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
603 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
605 //===----------------------------------------------------------------------===//
606 // Instructions specific format
607 //===----------------------------------------------------------------------===//
609 // Arithmetic and logical instructions with 3 register operands.
610 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
611 InstrItinClass Itin = NoItinerary,
612 SDPatternOperator OpNode = null_frag>:
613 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
614 !strconcat(opstr, "\t$rd, $rs, $rt"),
615 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
616 let isCommutable = isComm;
617 let isReMaterializable = 1;
618 let TwoOperandAliasConstraint = "$rd = $rs";
621 // Arithmetic and logical instructions with 2 register operands.
622 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
623 InstrItinClass Itin = NoItinerary,
624 SDPatternOperator imm_type = null_frag,
625 SDPatternOperator OpNode = null_frag> :
626 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
627 !strconcat(opstr, "\t$rt, $rs, $imm16"),
628 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
630 let isReMaterializable = 1;
631 let TwoOperandAliasConstraint = "$rs = $rt";
634 // Arithmetic Multiply ADD/SUB
635 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
636 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
637 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
638 let Defs = [HI0, LO0];
639 let Uses = [HI0, LO0];
640 let isCommutable = isComm;
644 class LogicNOR<string opstr, RegisterOperand RO>:
645 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
646 !strconcat(opstr, "\t$rd, $rs, $rt"),
647 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
648 let isCommutable = 1;
652 class shift_rotate_imm<string opstr, Operand ImmOpnd,
653 RegisterOperand RO, InstrItinClass itin,
654 SDPatternOperator OpNode = null_frag,
655 SDPatternOperator PF = null_frag> :
656 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
657 !strconcat(opstr, "\t$rd, $rt, $shamt"),
658 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
659 let TwoOperandAliasConstraint = "$rt = $rd";
662 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
663 SDPatternOperator OpNode = null_frag>:
664 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
665 !strconcat(opstr, "\t$rd, $rt, $rs"),
666 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
669 // Load Upper Imediate
670 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
671 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
672 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
673 let hasSideEffects = 0;
674 let isReMaterializable = 1;
678 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
679 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
680 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
681 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
682 let DecoderMethod = "DecodeMem";
683 let canFoldAsLoad = 1;
687 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
688 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
689 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
690 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
691 let DecoderMethod = "DecodeMem";
695 // Load/Store Left/Right
696 let canFoldAsLoad = 1 in
697 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
698 InstrItinClass Itin> :
699 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
700 !strconcat(opstr, "\t$rt, $addr"),
701 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
702 let DecoderMethod = "DecodeMem";
703 string Constraints = "$src = $rt";
706 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
707 InstrItinClass Itin> :
708 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
709 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
710 let DecoderMethod = "DecodeMem";
714 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
715 SDPatternOperator OpNode= null_frag> :
716 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
717 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
718 let DecoderMethod = "DecodeFMem2";
722 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
723 SDPatternOperator OpNode= null_frag> :
724 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
725 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
726 let DecoderMethod = "DecodeFMem2";
731 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
732 SDPatternOperator OpNode= null_frag> :
733 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
734 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
735 let DecoderMethod = "DecodeFMem3";
739 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
740 SDPatternOperator OpNode= null_frag> :
741 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
742 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
743 let DecoderMethod = "DecodeFMem3";
747 // Conditional Branch
748 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
749 RegisterOperand RO, bit DelaySlot = 1> :
750 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
751 !strconcat(opstr, "\t$rs, $rt, $offset"),
752 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
755 let isTerminator = 1;
756 let hasDelaySlot = DelaySlot;
760 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
761 RegisterOperand RO, bit DelaySlot = 1> :
762 InstSE<(outs), (ins RO:$rs, opnd:$offset),
763 !strconcat(opstr, "\t$rs, $offset"),
764 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch,
767 let isTerminator = 1;
768 let hasDelaySlot = DelaySlot;
773 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
774 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
775 !strconcat(opstr, "\t$rd, $rs, $rt"),
776 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
777 II_SLT_SLTU, FrmR, opstr>;
779 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
781 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
782 !strconcat(opstr, "\t$rt, $rs, $imm16"),
783 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
784 II_SLTI_SLTIU, FrmI, opstr>;
787 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
788 SDPatternOperator targetoperator, string bopstr> :
789 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
790 [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> {
793 let hasDelaySlot = 1;
794 let DecoderMethod = "DecodeJumpTarget";
798 // Unconditional branch
799 class UncondBranch<Instruction BEQInst> :
800 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>,
801 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
803 let isTerminator = 1;
805 let hasDelaySlot = 1;
806 let AdditionalPredicates = [RelocPIC];
810 // Base class for indirect branch and return instruction classes.
811 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
812 class JumpFR<string opstr, RegisterOperand RO,
813 SDPatternOperator operator = null_frag>:
814 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch,
818 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
820 let isIndirectBranch = 1;
823 // Jump and Link (Call)
824 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
825 class JumpLink<string opstr, DAGOperand opnd> :
826 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
827 [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> {
828 let DecoderMethod = "DecodeJumpTarget";
831 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
832 Register RetReg, RegisterOperand ResRO = RO>:
833 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
834 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
836 class JumpLinkReg<string opstr, RegisterOperand RO>:
837 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
840 class BGEZAL_FT<string opstr, DAGOperand opnd,
841 RegisterOperand RO, bit DelaySlot = 1> :
842 InstSE<(outs), (ins RO:$rs, opnd:$offset),
843 !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr> {
844 let hasDelaySlot = DelaySlot;
849 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
850 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
851 class TailCall<Instruction JumpInst> :
852 PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>,
853 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
855 class TailCallReg<RegisterOperand RO, Instruction JRInst,
856 RegisterOperand ResRO = RO> :
857 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>,
858 PseudoInstExpansion<(JRInst ResRO:$rs)>;
861 class BAL_BR_Pseudo<Instruction RealInst> :
862 PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
863 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
865 let isTerminator = 1;
867 let hasDelaySlot = 1;
872 class SYS_FT<string opstr> :
873 InstSE<(outs), (ins uimm20:$code_),
874 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
876 class BRK_FT<string opstr> :
877 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
878 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
882 class ER_FT<string opstr> :
883 InstSE<(outs), (ins),
884 opstr, [], NoItinerary, FrmOther, opstr>;
887 class DEI_FT<string opstr, RegisterOperand RO> :
888 InstSE<(outs RO:$rt), (ins),
889 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
892 class WAIT_FT<string opstr> :
893 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
896 let hasSideEffects = 1 in
897 class SYNC_FT<string opstr> :
898 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
899 NoItinerary, FrmOther, opstr>;
901 class SYNCI_FT<string opstr> :
902 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
903 NoItinerary, FrmOther, opstr> {
904 let hasSideEffects = 1;
905 let DecoderMethod = "DecodeSyncI";
908 let hasSideEffects = 1 in
909 class TEQ_FT<string opstr, RegisterOperand RO> :
910 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
911 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
914 class TEQI_FT<string opstr, RegisterOperand RO> :
915 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
916 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
918 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
919 list<Register> DefRegs> :
920 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
922 let isCommutable = 1;
924 let hasSideEffects = 0;
927 // Pseudo multiply/divide instruction with explicit accumulator register
929 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
930 SDPatternOperator OpNode, InstrItinClass Itin,
931 bit IsComm = 1, bit HasSideEffects = 0,
932 bit UsesCustomInserter = 0> :
933 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
934 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
935 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
936 let isCommutable = IsComm;
937 let hasSideEffects = HasSideEffects;
938 let usesCustomInserter = UsesCustomInserter;
941 // Pseudo multiply add/sub instruction with explicit accumulator register
943 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
945 : PseudoSE<(outs ACC64:$ac),
946 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
948 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
950 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
951 string Constraints = "$acin = $ac";
954 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
955 list<Register> DefRegs> :
956 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
957 [], itin, FrmR, opstr> {
962 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
963 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
964 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
966 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
967 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
970 let hasSideEffects = 0;
973 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
974 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
975 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
978 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
979 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
982 let hasSideEffects = 0;
985 class EffectiveAddress<string opstr, RegisterOperand RO> :
986 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
987 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
988 !strconcat(opstr, "_lea")> {
989 let isCodeGenOnly = 1;
990 let DecoderMethod = "DecodeMem";
993 // Count Leading Ones/Zeros in Word
994 class CountLeading0<string opstr, RegisterOperand RO>:
995 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
996 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
998 class CountLeading1<string opstr, RegisterOperand RO>:
999 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1000 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
1002 // Sign Extend in Register.
1003 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1004 InstrItinClass itin> :
1005 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1006 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1009 class SubwordSwap<string opstr, RegisterOperand RO>:
1010 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
1011 NoItinerary, FrmR, opstr> {
1012 let hasSideEffects = 0;
1016 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1017 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1018 II_RDHWR, FrmR, "rdhwr">;
1021 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1022 SDPatternOperator Op = null_frag>:
1023 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
1024 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1025 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT,
1026 FrmR, opstr>, ISA_MIPS32R2;
1028 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1029 SDPatternOperator Op = null_frag>:
1030 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
1031 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1032 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1033 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1034 let Constraints = "$src = $rt";
1037 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1038 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1039 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1040 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1042 // Atomic Compare & Swap.
1043 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1044 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1045 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1047 class LLBase<string opstr, RegisterOperand RO> :
1048 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1049 [], NoItinerary, FrmI> {
1050 let DecoderMethod = "DecodeMem";
1054 class SCBase<string opstr, RegisterOperand RO> :
1055 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1056 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
1057 let DecoderMethod = "DecodeMem";
1059 let Constraints = "$rt = $dst";
1062 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1063 InstSE<(outs RO:$rt), (ins RD:$rd, uimm16:$sel),
1064 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1066 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1067 InstSE<(outs RO:$rd), (ins RD:$rt, uimm16:$sel),
1068 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1070 class TrapBase<Instruction RealInst>
1071 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
1072 PseudoInstExpansion<(RealInst 0, 0)> {
1074 let isTerminator = 1;
1075 let isCodeGenOnly = 1;
1078 //===----------------------------------------------------------------------===//
1079 // Pseudo instructions
1080 //===----------------------------------------------------------------------===//
1083 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
1084 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1086 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1087 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1088 [(callseq_start timm:$amt)]>;
1089 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1090 [(callseq_end timm:$amt1, timm:$amt2)]>;
1093 let usesCustomInserter = 1 in {
1094 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1095 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1096 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1097 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1098 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1099 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1100 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1101 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1102 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1103 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1104 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1105 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1106 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1107 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1108 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1109 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1110 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1111 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1113 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1114 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1115 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1117 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1118 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1119 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1122 /// Pseudo instructions for loading and storing accumulator registers.
1123 let isPseudo = 1, isCodeGenOnly = 1 in {
1124 def LOAD_ACC64 : Load<"", ACC64>;
1125 def STORE_ACC64 : Store<"", ACC64>;
1128 // We need these two pseudo instructions to avoid offset calculation for long
1129 // branches. See the comment in file MipsLongBranch.cpp for detailed
1132 // Expands to: lui $dst, %hi($tgt - $baltgt)
1133 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1134 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1136 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1137 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1138 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1140 //===----------------------------------------------------------------------===//
1141 // Instruction definition
1142 //===----------------------------------------------------------------------===//
1143 //===----------------------------------------------------------------------===//
1144 // MipsI Instructions
1145 //===----------------------------------------------------------------------===//
1147 /// Arithmetic Instructions (ALU Immediate)
1148 let AdditionalPredicates = [NotInMicroMips] in {
1149 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd,
1150 II_ADDIU, immSExt16, add>,
1151 ADDI_FM<0x9>, IsAsCheapAsAMove;
1153 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1154 ISA_MIPS1_NOT_32R6_64R6;
1155 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1157 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1159 let AdditionalPredicates = [NotInMicroMips] in {
1160 def ANDi : MMRel, StdMMR6Rel,
1161 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1164 def ORi : MMRel, StdMMR6Rel,
1165 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1167 def XORi : MMRel, StdMMR6Rel,
1168 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1170 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1171 let AdditionalPredicates = [NotInMicroMips] in {
1172 /// Arithmetic Instructions (3-Operand, R-Type)
1173 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1175 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1178 let Defs = [HI0, LO0] in
1179 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1180 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1181 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1182 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1183 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1184 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1185 let AdditionalPredicates = [NotInMicroMips] in {
1186 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1188 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1190 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1193 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1195 /// Shift Instructions
1196 let AdditionalPredicates = [NotInMicroMips] in {
1197 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1198 immZExt5>, SRA_FM<0, 0>;
1199 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1200 immZExt5>, SRA_FM<2, 0>;
1202 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1203 immZExt5>, SRA_FM<3, 0>;
1204 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1206 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1208 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1211 // Rotate Instructions
1212 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1214 SRA_FM<2, 1>, ISA_MIPS32R2;
1215 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1216 SRLV_FM<6, 1>, ISA_MIPS32R2;
1218 /// Load and Store Instructions
1220 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1221 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1223 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1225 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1226 let AdditionalPredicates = [NotInMicroMips] in {
1227 def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1230 def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>;
1231 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1232 let AdditionalPredicates = [NotInMicroMips] in {
1233 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1236 /// load/store left/right
1237 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1238 AdditionalPredicates = [NotInMicroMips] in {
1239 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1240 ISA_MIPS1_NOT_32R6_64R6;
1241 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1242 ISA_MIPS1_NOT_32R6_64R6;
1243 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1244 ISA_MIPS1_NOT_32R6_64R6;
1245 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1246 ISA_MIPS1_NOT_32R6_64R6;
1249 let AdditionalPredicates = [NotInMicroMips] in {
1250 // COP2 Memory Instructions
1251 def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
1252 ISA_MIPS1_NOT_32R6_64R6;
1253 def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
1254 ISA_MIPS1_NOT_32R6_64R6;
1255 def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
1256 ISA_MIPS2_NOT_32R6_64R6;
1257 def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
1258 ISA_MIPS2_NOT_32R6_64R6;
1260 // COP3 Memory Instructions
1261 let DecoderNamespace = "COP3_" in {
1262 def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>;
1263 def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>;
1264 def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>,
1266 def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
1271 def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
1272 def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1274 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1275 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1276 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1277 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1278 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1279 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1281 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1282 ISA_MIPS2_NOT_32R6_64R6;
1283 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1284 ISA_MIPS2_NOT_32R6_64R6;
1285 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1286 ISA_MIPS2_NOT_32R6_64R6;
1287 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1288 ISA_MIPS2_NOT_32R6_64R6;
1289 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1290 ISA_MIPS2_NOT_32R6_64R6;
1291 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1292 ISA_MIPS2_NOT_32R6_64R6;
1294 let AdditionalPredicates = [NotInMicroMips] in {
1295 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1297 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1298 def TRAP : TrapBase<BREAK>;
1299 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1301 let AdditionalPredicates = [NotInMicroMips] in {
1302 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1303 def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1305 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1307 let AdditionalPredicates = [NotInMicroMips] in {
1308 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1310 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1312 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1313 AdditionalPredicates = [NotInMicroMips] in {
1314 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1316 /// Load-linked, Store-conditional
1317 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1318 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1321 /// Jump and Branch Instructions
1322 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1323 AdditionalRequires<[RelocStatic]>, IsBranch;
1324 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1325 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1326 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1327 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1328 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1329 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1330 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1331 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1333 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1334 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1335 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1337 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1338 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1339 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1341 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1342 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1343 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1345 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1346 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1347 def B : UncondBranch<BEQ>;
1349 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1350 let AdditionalPredicates = [NotInMicroMips] in {
1351 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1352 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1355 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1356 ISA_MIPS32_NOT_32R6_64R6;
1357 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1358 ISA_MIPS1_NOT_32R6_64R6;
1359 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1360 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1361 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1362 ISA_MIPS1_NOT_32R6_64R6;
1363 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1364 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1365 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1366 def TAILCALL : TailCall<J>;
1367 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1369 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1370 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1371 class PseudoIndirectBranchBase<RegisterOperand RO> :
1372 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], IIBranch> {
1375 let hasDelaySlot = 1;
1377 let isIndirectBranch = 1;
1380 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1382 // Return instructions are matched as a RetRA instruction, then ar expanded
1383 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1384 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1386 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1388 let isTerminator = 1;
1390 let hasDelaySlot = 1;
1392 let isCodeGenOnly = 1;
1394 let hasExtraSrcRegAllocReq = 1;
1397 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1399 // Exception handling related node and instructions.
1400 // The conversion sequence is:
1401 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1402 // MIPSeh_return -> (stack change + indirect branch)
1404 // MIPSeh_return takes the place of regular return instruction
1405 // but takes two arguments (V1, V0) which are used for storing
1406 // the offset and return address respectively.
1407 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1409 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1410 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1412 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1413 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1414 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1415 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1417 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1420 /// Multiply and Divide Instructions.
1421 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1422 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1423 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1424 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1425 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1426 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1427 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1428 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1430 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1431 ISA_MIPS1_NOT_32R6_64R6;
1432 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1433 ISA_MIPS1_NOT_32R6_64R6;
1434 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1435 AdditionalPredicates = [NotInMicroMips] in {
1436 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1437 ISA_MIPS1_NOT_32R6_64R6;
1438 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1439 ISA_MIPS1_NOT_32R6_64R6;
1442 /// Sign Ext In Register Instructions.
1443 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1444 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1445 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1446 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1449 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1450 ISA_MIPS32_NOT_32R6_64R6;
1451 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1452 ISA_MIPS32_NOT_32R6_64R6;
1454 /// Word Swap Bytes Within Halfwords
1455 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2;
1458 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1460 // FrameIndexes are legalized when they are operands from load/store
1461 // instructions. The same not happens for stack address copies, so an
1462 // add op with mem ComplexPattern is used and the stack address copy
1463 // can be matched. It's similar to Sparc LEA_ADDRi
1464 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1467 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1468 ISA_MIPS32_NOT_32R6_64R6;
1469 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1470 ISA_MIPS32_NOT_32R6_64R6;
1471 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1472 ISA_MIPS32_NOT_32R6_64R6;
1473 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1474 ISA_MIPS32_NOT_32R6_64R6;
1476 let AdditionalPredicates = [NotDSP] in {
1477 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1478 ISA_MIPS1_NOT_32R6_64R6;
1479 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1480 ISA_MIPS1_NOT_32R6_64R6;
1481 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1482 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1483 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1484 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1485 ISA_MIPS32_NOT_32R6_64R6;
1486 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1487 ISA_MIPS32_NOT_32R6_64R6;
1488 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1489 ISA_MIPS32_NOT_32R6_64R6;
1490 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1491 ISA_MIPS32_NOT_32R6_64R6;
1494 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1495 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1496 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1497 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1499 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1501 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1502 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1504 /// Move Control Registers From/To CPU Registers
1505 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1506 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1507 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
1508 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1510 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1512 def SSNOP : MMRel, Barrier<"ssnop">, BARRIER_FM<1>;
1513 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1514 def PAUSE : MMRel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1516 // JR_HB and JALR_HB are defined here using the new style naming
1517 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1518 // and because of that it doesn't follow the naming convention of the
1519 // rest of the file. To avoid a mixture of old vs new style, the new
1520 // style was chosen.
1521 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1522 dag OutOperandList = (outs);
1523 dag InOperandList = (ins GPROpnd:$rs);
1524 string AsmString = !strconcat(instr_asm, "\t$rs");
1525 list<dag> Pattern = [];
1528 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1529 dag OutOperandList = (outs GPROpnd:$rd);
1530 dag InOperandList = (ins GPROpnd:$rs);
1531 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1532 list<dag> Pattern = [];
1535 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1536 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1538 let isIndirectBranch=1;
1544 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1545 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1546 let isIndirectBranch=1;
1550 class JR_HB_ENC : JR_HB_FM<8>;
1551 class JALR_HB_ENC : JALR_HB_FM<9>;
1553 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1554 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1556 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1558 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1559 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1560 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1561 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1563 class CacheOp<string instr_asm, Operand MemOpnd> :
1564 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1565 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1567 let DecoderMethod = "DecodeCacheOp";
1570 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1571 INSN_MIPS3_32_NOT_32R6_64R6;
1572 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1573 INSN_MIPS3_32_NOT_32R6_64R6;
1575 //===----------------------------------------------------------------------===//
1576 // Instruction aliases
1577 //===----------------------------------------------------------------------===//
1578 def : MipsInstAlias<"move $dst, $src",
1579 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1581 let AdditionalPredicates = [NotInMicroMips];
1583 def : MipsInstAlias<"move $dst, $src",
1584 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1586 let AdditionalPredicates = [NotInMicroMips];
1588 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1589 ISA_MIPS1_NOT_32R6_64R6;
1590 def : MipsInstAlias<"addu $rs, $rt, $imm",
1591 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1592 def : MipsInstAlias<"addu $rs, $imm",
1593 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1594 def : MipsInstAlias<"add $rs, $rt, $imm",
1595 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1596 ISA_MIPS1_NOT_32R6_64R6;
1597 def : MipsInstAlias<"add $rs, $imm",
1598 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1599 ISA_MIPS1_NOT_32R6_64R6;
1600 def : MipsInstAlias<"and $rs, $rt, $imm",
1601 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1602 def : MipsInstAlias<"and $rs, $imm",
1603 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1604 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1605 let Predicates = [NotInMicroMips] in {
1606 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1608 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1609 def : MipsInstAlias<"not $rt, $rs",
1610 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1611 def : MipsInstAlias<"neg $rt, $rs",
1612 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1613 def : MipsInstAlias<"negu $rt",
1614 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1615 def : MipsInstAlias<"negu $rt, $rs",
1616 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1617 def : MipsInstAlias<"slt $rs, $rt, $imm",
1618 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1619 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1620 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1621 def : MipsInstAlias<"xor $rs, $rt, $imm",
1622 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1623 def : MipsInstAlias<"xor $rs, $imm",
1624 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1625 def : MipsInstAlias<"or $rs, $rt, $imm",
1626 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1627 def : MipsInstAlias<"or $rs, $imm",
1628 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1629 let AdditionalPredicates = [NotInMicroMips] in {
1630 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1632 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
1633 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1634 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
1635 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1636 let AdditionalPredicates = [NotInMicroMips] in {
1637 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1639 def : MipsInstAlias<"bnez $rs,$offset",
1640 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1641 def : MipsInstAlias<"bnezl $rs,$offset",
1642 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1643 def : MipsInstAlias<"beqz $rs,$offset",
1644 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1645 def : MipsInstAlias<"beqzl $rs,$offset",
1646 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1647 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1649 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1650 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1651 let AdditionalPredicates = [NotInMicroMips] in {
1652 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1654 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1656 def : MipsInstAlias<"teq $rs, $rt",
1657 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1658 def : MipsInstAlias<"tge $rs, $rt",
1659 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1660 def : MipsInstAlias<"tgeu $rs, $rt",
1661 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1662 def : MipsInstAlias<"tlt $rs, $rt",
1663 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1664 def : MipsInstAlias<"tltu $rs, $rt",
1665 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1666 def : MipsInstAlias<"tne $rs, $rt",
1667 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1669 def : MipsInstAlias<"sll $rd, $rt, $rs",
1670 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1671 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1672 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1673 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1674 def : MipsInstAlias<"sub $rs, $imm",
1675 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1676 0>, ISA_MIPS1_NOT_32R6_64R6;
1677 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1678 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1679 InvertedImOperand:$imm), 0>;
1680 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1681 InvertedImOperand:$imm), 0>;
1682 def : MipsInstAlias<"sra $rd, $rt, $rs",
1683 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1684 def : MipsInstAlias<"srl $rd, $rt, $rs",
1685 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1686 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1687 def : MipsInstAlias<"sync",
1688 (SYNC 0), 1>, ISA_MIPS2;
1689 //===----------------------------------------------------------------------===//
1690 // Assembler Pseudo Instructions
1691 //===----------------------------------------------------------------------===//
1693 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1694 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1695 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1696 def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>;
1698 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1699 RegisterOperand RO> :
1700 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1701 !strconcat(instr_asm, "\t$rt, $addr")> ;
1702 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1704 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1705 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1706 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1707 def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>;
1709 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1711 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1714 let hasDelaySlot = 1 in {
1715 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1716 (ins imm64:$imm64, brtarget:$offset),
1717 "bne\t$rt, $imm64, $offset">;
1718 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1719 (ins imm64:$imm64, brtarget:$offset),
1720 "beq\t$rt, $imm64, $offset">;
1722 class CondBranchPseudo<string instr_asm> :
1723 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
1725 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
1728 def BLT : CondBranchPseudo<"blt">;
1729 def BLE : CondBranchPseudo<"ble">;
1730 def BGE : CondBranchPseudo<"bge">;
1731 def BGT : CondBranchPseudo<"bgt">;
1732 def BLTU : CondBranchPseudo<"bltu">;
1733 def BLEU : CondBranchPseudo<"bleu">;
1734 def BGEU : CondBranchPseudo<"bgeu">;
1735 def BGTU : CondBranchPseudo<"bgtu">;
1737 def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1738 "div\t$rs, $rt">, ISA_MIPS1_NOT_32R6_64R6;
1740 def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1741 "divu\t$rs, $rt">, ISA_MIPS1_NOT_32R6_64R6;
1743 def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1744 "ddiv\t$rs, $rt">, ISA_MIPS64_NOT_64R6;
1746 def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1747 "ddivu\t$rs, $rt">, ISA_MIPS64_NOT_64R6;
1749 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1750 "ulhu\t$rt, $addr">, ISA_MIPS1_NOT_32R6_64R6;
1752 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1753 "ulw\t$rt, $addr">, ISA_MIPS1_NOT_32R6_64R6;
1755 //===----------------------------------------------------------------------===//
1756 // Arbitrary patterns that map to one or more instructions
1757 //===----------------------------------------------------------------------===//
1759 // Load/store pattern templates.
1760 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1761 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1763 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1764 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1767 let AdditionalPredicates = [NotInMicroMips] in {
1768 def : MipsPat<(i32 immSExt16:$in),
1769 (ADDiu ZERO, imm:$in)>;
1770 def : MipsPat<(i32 immZExt16:$in),
1771 (ORi ZERO, imm:$in)>;
1773 def : MipsPat<(i32 immLow16Zero:$in),
1774 (LUi (HI16 imm:$in))>;
1776 // Arbitrary immediates
1777 def : MipsPat<(i32 imm:$imm),
1778 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1780 // Carry MipsPatterns
1781 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1782 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1783 let AdditionalPredicates = [NotDSP] in {
1784 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1785 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1786 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1787 (ADDiu GPR32:$src, imm:$imm)>;
1790 // Support multiplication for pre-Mips32 targets that don't have
1791 // the MUL instruction.
1792 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
1793 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
1794 ISA_MIPS1_NOT_32R6_64R6;
1797 def : MipsPat<(MipsSync (i32 immz)),
1798 (SYNC 0)>, ISA_MIPS2;
1801 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1802 (JAL tglobaladdr:$dst)>;
1803 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1804 (JAL texternalsym:$dst)>;
1805 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1806 // (JALR GPR32:$dst)>;
1809 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1810 (TAILCALL tglobaladdr:$dst)>;
1811 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1812 (TAILCALL texternalsym:$dst)>;
1814 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1815 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1816 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1817 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1818 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1819 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1821 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1822 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1823 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1824 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1825 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1826 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1828 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1829 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1830 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1831 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1832 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1833 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1834 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1835 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1836 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1837 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1840 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1841 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1842 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1843 (ADDiu GPR32:$gp, tconstpool:$in)>;
1846 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1847 MipsPat<(MipsWrapper RC:$gp, node:$in),
1848 (ADDiuOp RC:$gp, node:$in)>;
1850 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1851 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1852 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1853 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1854 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1855 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1857 let AdditionalPredicates = [NotInMicroMips] in {
1858 // Mips does not have "not", so we expand our way
1859 def : MipsPat<(not GPR32:$in),
1860 (NOR GPR32Opnd:$in, ZERO)>;
1864 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1865 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1866 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1869 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1872 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1873 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1874 Instruction SLTiuOp, Register ZEROReg> {
1875 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1876 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1877 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1878 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1880 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1881 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1882 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1883 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1884 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1885 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1886 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1887 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1888 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1889 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1890 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1891 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1893 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1894 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1895 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1896 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1898 def : MipsPat<(brcond RC:$cond, bb:$dst),
1899 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1902 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1904 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1905 (BLEZ i32:$lhs, bb:$dst)>;
1906 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1907 (BGEZ i32:$lhs, bb:$dst)>;
1910 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1911 Instruction SLTuOp, Register ZEROReg> {
1912 def : MipsPat<(seteq RC:$lhs, 0),
1913 (SLTiuOp RC:$lhs, 1)>;
1914 def : MipsPat<(setne RC:$lhs, 0),
1915 (SLTuOp ZEROReg, RC:$lhs)>;
1916 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1917 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1918 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1919 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1922 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1923 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1924 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1925 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1926 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1929 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1930 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1931 (SLTOp RC:$rhs, RC:$lhs)>;
1932 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1933 (SLTuOp RC:$rhs, RC:$lhs)>;
1936 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1937 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1938 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1939 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1940 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
1943 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
1944 Instruction SLTiuOp> {
1945 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
1946 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
1947 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
1948 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
1951 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
1952 defm : SetlePats<GPR32, SLT, SLTu>;
1953 defm : SetgtPats<GPR32, SLT, SLTu>;
1954 defm : SetgePats<GPR32, SLT, SLTu>;
1955 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
1958 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
1960 // Load halfword/word patterns.
1961 let AddedComplexity = 40 in {
1962 def : LoadRegImmPat<LBu, i32, zextloadi8>;
1963 def : LoadRegImmPat<LH, i32, sextloadi16>;
1964 let AdditionalPredicates = [NotInMicroMips] in {
1965 def : LoadRegImmPat<LW, i32, load>;
1969 //===----------------------------------------------------------------------===//
1970 // Floating Point Support
1971 //===----------------------------------------------------------------------===//
1973 include "MipsInstrFPU.td"
1974 include "Mips64InstrInfo.td"
1975 include "MipsCondMov.td"
1977 include "Mips32r6InstrInfo.td"
1978 include "Mips64r6InstrInfo.td"
1983 include "Mips16InstrFormats.td"
1984 include "Mips16InstrInfo.td"
1987 include "MipsDSPInstrFormats.td"
1988 include "MipsDSPInstrInfo.td"
1991 include "MipsMSAInstrFormats.td"
1992 include "MipsMSAInstrInfo.td"
1995 include "MicroMipsInstrFormats.td"
1996 include "MicroMipsInstrInfo.td"
1997 include "MicroMipsInstrFPU.td"
2000 include "MicroMips32r6InstrFormats.td"
2001 include "MicroMips32r6InstrInfo.td"
2004 include "MicroMips64r6InstrFormats.td"
2005 include "MicroMips64r6InstrInfo.td"