1//===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Mips implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14 15//===----------------------------------------------------------------------===// 16// Mips profiles and nodes 17//===----------------------------------------------------------------------===// 18 19def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; 20def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, 21 SDTCisSameAs<1, 2>, 22 SDTCisSameAs<3, 4>, 23 SDTCisInt<4>]>; 24def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; 25def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 26def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>; 27def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, 28 SDTCisInt<1>, SDTCisSameAs<1, 2>]>; 29def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>, 30 SDTCisSameAs<1, 2>]>; 31def SDT_MipsMAddMSub : SDTypeProfile<1, 3, 32 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>, 33 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; 34def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; 35 36def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 37 38def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 39 40def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 41 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>; 42def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 43 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>, 44 SDTCisSameAs<0, 4>]>; 45 46def SDTMipsLoadLR : SDTypeProfile<1, 2, 47 [SDTCisInt<0>, SDTCisPtrTy<1>, 48 SDTCisSameAs<0, 2>]>; 49 50// Call 51def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, 52 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 53 SDNPVariadic]>; 54 55// Tail call 56def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink, 57 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 58 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) 62def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>; 63def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>; 64def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>; 65 66// TlsGd node is used to handle General Dynamic TLS 67def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>; 68 69// TprelHi and TprelLo nodes are used to handle Local Exec TLS 70def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>; 71def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>; 72 73// Thread pointer 74def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>; 75 76// Return 77def MipsRet : SDNode<"MipsISD::Ret", SDTNone, 78 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 79 80def MipsERet : SDNode<"MipsISD::ERet", SDTNone, 81 [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>; 82 83// These are target-independent nodes, but have target-specific formats. 84def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart, 85 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 86def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd, 87 [SDNPHasChain, SDNPSideEffect, 88 SDNPOptInGlue, SDNPOutGlue]>; 89 90// Nodes used to extract LO/HI registers. 91def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>; 92def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>; 93 94// Node used to insert 32-bit integers to LOHI register pair. 95def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>; 96 97// Mult nodes. 98def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>; 99def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>; 100 101// MAdd*/MSub* nodes 102def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>; 103def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>; 104def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>; 105def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>; 106 107// DivRem(u) nodes 108def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>; 109def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>; 110def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16, 111 [SDNPOutGlue]>; 112def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16, 113 [SDNPOutGlue]>; 114 115// Target constant nodes that are not part of any isel patterns and remain 116// unchanged can cause instructions with illegal operands to be emitted. 117// Wrapper node patterns give the instruction selector a chance to replace 118// target constant nodes that would otherwise remain unchanged with ADDiu 119// nodes. Without these wrapper node patterns, the following conditional move 120// instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is 121// compiled: 122// movn %got(d)($gp), %got(c)($gp), $4 123// This instruction is illegal since movn can take only register operands. 124 125def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>; 126 127def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>; 128 129def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>; 130def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>; 131 132def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR, 133 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 134def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR, 135 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 136def MipsSWL : SDNode<"MipsISD::SWL", SDTStore, 137 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 138def MipsSWR : SDNode<"MipsISD::SWR", SDTStore, 139 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 140def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR, 141 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 142def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR, 143 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 144def MipsSDL : SDNode<"MipsISD::SDL", SDTStore, 145 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 146def MipsSDR : SDNode<"MipsISD::SDR", SDTStore, 147 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 148 149//===----------------------------------------------------------------------===// 150// Mips Instruction Predicate Definitions. 151//===----------------------------------------------------------------------===// 152def HasMips2 : Predicate<"Subtarget->hasMips2()">, 153 AssemblerPredicate<"FeatureMips2">; 154def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">, 155 AssemblerPredicate<"FeatureMips3_32">; 156def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">, 157 AssemblerPredicate<"FeatureMips3_32r2">; 158def HasMips3 : Predicate<"Subtarget->hasMips3()">, 159 AssemblerPredicate<"FeatureMips3">; 160def NotMips3 : Predicate<"!Subtarget->hasMips3()">, 161 AssemblerPredicate<"!FeatureMips3">; 162def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">, 163 AssemblerPredicate<"FeatureMips4_32">; 164def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">, 165 AssemblerPredicate<"!FeatureMips4_32">; 166def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">, 167 AssemblerPredicate<"FeatureMips4_32r2">; 168def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">, 169 AssemblerPredicate<"FeatureMips5_32r2">; 170def HasMips32 : Predicate<"Subtarget->hasMips32()">, 171 AssemblerPredicate<"FeatureMips32">; 172def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">, 173 AssemblerPredicate<"FeatureMips32r2">; 174def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">, 175 AssemblerPredicate<"FeatureMips32r5">; 176def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">, 177 AssemblerPredicate<"FeatureMips32r6">; 178def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">, 179 AssemblerPredicate<"!FeatureMips32r6">; 180def IsGP64bit : Predicate<"Subtarget->isGP64bit()">, 181 AssemblerPredicate<"FeatureGP64Bit">; 182def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">, 183 AssemblerPredicate<"!FeatureGP64Bit">; 184def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">, 185 AssemblerPredicate<"FeaturePTR64Bit">; 186def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">, 187 AssemblerPredicate<"!FeaturePTR64Bit">; 188def HasMips64 : Predicate<"Subtarget->hasMips64()">, 189 AssemblerPredicate<"FeatureMips64">; 190def NotMips64 : Predicate<"!Subtarget->hasMips64()">, 191 AssemblerPredicate<"!FeatureMips64">; 192def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">, 193 AssemblerPredicate<"FeatureMips64r2">; 194def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">, 195 AssemblerPredicate<"FeatureMips64r6">; 196def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">, 197 AssemblerPredicate<"!FeatureMips64r6">; 198def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">, 199 AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">; 200def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">, 201 AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">; 202def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">, 203 AssemblerPredicate<"FeatureMips16">; 204def HasCnMips : Predicate<"Subtarget->hasCnMips()">, 205 AssemblerPredicate<"FeatureCnMips">; 206def NotCnMips : Predicate<"!Subtarget->hasCnMips()">, 207 AssemblerPredicate<"!FeatureCnMips">; 208def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">; 209def RelocPIC : Predicate<"TM.isPositionIndependent()">; 210def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">; 211def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">, 212 AssemblerPredicate<"!FeatureMips16">; 213def NotDSP : Predicate<"!Subtarget->hasDSP()">; 214def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">, 215 AssemblerPredicate<"FeatureMicroMips">; 216def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">, 217 AssemblerPredicate<"!FeatureMicroMips">; 218def IsLE : Predicate<"Subtarget->isLittle()">; 219def IsBE : Predicate<"!Subtarget->isLittle()">; 220def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">; 221def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">; 222def HasEVA : Predicate<"Subtarget->hasEVA()">, 223 AssemblerPredicate<"FeatureEVA,FeatureMips32r2">; 224def HasMSA : Predicate<"Subtarget->hasMSA()">, 225 AssemblerPredicate<"FeatureMSA">; 226 227 228//===----------------------------------------------------------------------===// 229// Mips GPR size adjectives. 230// They are mutually exclusive. 231//===----------------------------------------------------------------------===// 232 233class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; } 234class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; } 235 236class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; } 237class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; } 238 239//===----------------------------------------------------------------------===// 240// Mips ISA/ASE membership and instruction group membership adjectives. 241// They are mutually exclusive. 242//===----------------------------------------------------------------------===// 243 244// FIXME: I'd prefer to use additive predicates to build the instruction sets 245// but we are short on assembler feature bits at the moment. Using a 246// subtractive predicate will hopefully keep us under the 32 predicate 247// limit long enough to develop an alternative way to handle P1||P2 248// predicates. 249class ISA_MIPS1_NOT_MIPS3 { 250 list<Predicate> InsnPredicates = [NotMips3]; 251} 252class ISA_MIPS1_NOT_4_32 { 253 list<Predicate> InsnPredicates = [NotMips4_32]; 254} 255class ISA_MIPS1_NOT_32R6_64R6 { 256 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6]; 257} 258class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; } 259class ISA_MIPS2_NOT_32R6_64R6 { 260 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6]; 261} 262class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; } 263class ISA_MIPS3_NOT_32R6_64R6 { 264 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6]; 265} 266class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; } 267class ISA_MIPS32_NOT_32R6_64R6 { 268 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6]; 269} 270class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; } 271class ISA_MIPS32R2_NOT_32R6_64R6 { 272 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6]; 273} 274class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; } 275class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; } 276class ISA_MIPS64_NOT_64R6 { 277 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6]; 278} 279class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; } 280class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; } 281class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; } 282class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; } 283class ISA_MICROMIPS32R6 { 284 list<Predicate> InsnPredicates = [HasMicroMips32r6]; 285} 286class ISA_MICROMIPS64R6 { 287 list<Predicate> InsnPredicates = [HasMicroMips64r6]; 288} 289class ISA_MICROMIPS32_NOT_MIPS32R6 { 290 list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6]; 291} 292 293class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; } 294class INSN_EVA_NOT_32R6_64R6 { 295 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA]; 296} 297 298// The portions of MIPS-III that were also added to MIPS32 299class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; } 300 301// The portions of MIPS-III that were also added to MIPS32 but were removed in 302// MIPS32r6 and MIPS64r6. 303class INSN_MIPS3_32_NOT_32R6_64R6 { 304 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6]; 305} 306 307// The portions of MIPS-III that were also added to MIPS32 308class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; } 309 310// The portions of MIPS-IV that were also added to MIPS32. 311class INSN_MIPS4_32 { list <Predicate> InsnPredicates = [HasMips4_32]; } 312 313// The portions of MIPS-IV that were also added to MIPS32 but were removed in 314// MIPS32r6 and MIPS64r6. 315class INSN_MIPS4_32_NOT_32R6_64R6 { 316 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6]; 317} 318 319// The portions of MIPS-IV that were also added to MIPS32r2 but were removed in 320// MIPS32r6 and MIPS64r6. 321class INSN_MIPS4_32R2_NOT_32R6_64R6 { 322 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6]; 323} 324 325// The portions of MIPS-IV that were also added to MIPS32r2. 326class INSN_MIPS4_32R2 { 327 list<Predicate> InsnPredicates = [HasMips4_32r2]; 328} 329 330// The portions of MIPS-V that were also added to MIPS32r2 but were removed in 331// MIPS32r6 and MIPS64r6. 332class INSN_MIPS5_32R2_NOT_32R6_64R6 { 333 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6]; 334} 335 336class ASE_CNMIPS { 337 list<Predicate> InsnPredicates = [HasCnMips]; 338} 339 340class NOT_ASE_CNMIPS { 341 list<Predicate> InsnPredicates = [NotCnMips]; 342} 343 344class ASE_MIPS64_CNMIPS { 345 list<Predicate> InsnPredicates = [HasMips64, HasCnMips]; 346} 347 348class ASE_MSA { 349 list<Predicate> InsnPredicates = [HasMSA]; 350} 351 352class ASE_MSA_NOT_MSA64 { 353 list<Predicate> InsnPredicates = [HasMSA, NotMips64]; 354} 355 356class ASE_MSA64 { 357 list<Predicate> InsnPredicates = [HasMSA, HasMips64]; 358} 359 360// Class used for separating microMIPSr6 and microMIPS (r3) instruction. 361// It can be used only on instructions that doesn't inherit PredicateControl. 362class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl { 363 let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6]; 364} 365 366class ASE_NOT_DSP { 367 list<Predicate> InsnPredicates = [NotDSP]; 368} 369 370//===----------------------------------------------------------------------===// 371 372class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl { 373 let EncodingPredicates = [HasStdEnc]; 374} 375 376class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> : 377 InstAlias<Asm, Result, Emit>, PredicateControl; 378 379class IsCommutable { 380 bit isCommutable = 1; 381} 382 383class IsBranch { 384 bit isBranch = 1; 385 bit isCTI = 1; 386} 387 388class IsReturn { 389 bit isReturn = 1; 390 bit isCTI = 1; 391} 392 393class IsCall { 394 bit isCall = 1; 395 bit isCTI = 1; 396} 397 398class IsTailCall { 399 bit isCall = 1; 400 bit isTerminator = 1; 401 bit isReturn = 1; 402 bit isBarrier = 1; 403 bit hasExtraSrcRegAllocReq = 1; 404 bit isCodeGenOnly = 1; 405 bit isCTI = 1; 406} 407 408class IsAsCheapAsAMove { 409 bit isAsCheapAsAMove = 1; 410} 411 412class NeverHasSideEffects { 413 bit hasSideEffects = 0; 414} 415 416//===----------------------------------------------------------------------===// 417// Instruction format superclass 418//===----------------------------------------------------------------------===// 419 420include "MipsInstrFormats.td" 421 422//===----------------------------------------------------------------------===// 423// Mips Operand, Complex Patterns and Transformations Definitions. 424//===----------------------------------------------------------------------===// 425 426class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [], 427 int Offset = 0> : AsmOperandClass { 428 let Name = "ConstantSImm" # Bits # "_" # Offset; 429 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">"; 430 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">"; 431 let SuperClasses = Supers; 432 let DiagnosticType = "SImm" # Bits # "_" # Offset; 433} 434 435class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [], 436 int Shift = 0> : AsmOperandClass { 437 let Name = "Simm" # Bits # "_Lsl" # Shift; 438 let RenderMethod = "addImmOperands"; 439 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">"; 440 let SuperClasses = Supers; 441 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift; 442} 443 444class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [], 445 int Offset = 0> : AsmOperandClass { 446 let Name = "ConstantUImm" # Bits # "_" # Offset; 447 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">"; 448 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">"; 449 let SuperClasses = Supers; 450 let DiagnosticType = "UImm" # Bits # "_" # Offset; 451} 452 453class ConstantUImmRangeAsmOperandClass<int Bottom, int Top, 454 list<AsmOperandClass> Supers = []> 455 : AsmOperandClass { 456 let Name = "ConstantUImmRange" # Bottom # "_" # Top; 457 let RenderMethod = "addImmOperands"; 458 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">"; 459 let SuperClasses = Supers; 460 let DiagnosticType = "UImmRange" # Bottom # "_" # Top; 461} 462 463class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []> 464 : AsmOperandClass { 465 let Name = "SImm" # Bits; 466 let RenderMethod = "addSImmOperands<" # Bits # ">"; 467 let PredicateMethod = "isSImm<" # Bits # ">"; 468 let SuperClasses = Supers; 469 let DiagnosticType = "SImm" # Bits; 470} 471 472class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []> 473 : AsmOperandClass { 474 let Name = "UImm" # Bits; 475 let RenderMethod = "addUImmOperands<" # Bits # ">"; 476 let PredicateMethod = "isUImm<" # Bits # ">"; 477 let SuperClasses = Supers; 478 let DiagnosticType = "UImm" # Bits; 479} 480 481// Generic case - only to support certain assembly pseudo instructions. 482class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []> 483 : AsmOperandClass { 484 let Name = "ImmAny"; 485 let RenderMethod = "addConstantUImmOperands<32>"; 486 let PredicateMethod = "isSImm<" # Bits # ">"; 487 let SuperClasses = Supers; 488 let DiagnosticType = "ImmAny"; 489} 490 491// AsmOperandClasses require a strict ordering which is difficult to manage 492// as a hierarchy. Instead, we use a linear ordering and impose an order that 493// is in some places arbitrary. 494// 495// Here the rules that are in use: 496// * Wider immediates are a superset of narrower immediates: 497// uimm4 < uimm5 < uimm6 498// * For the same bit-width, unsigned immediates are a superset of signed 499// immediates:: 500// simm4 < uimm4 < simm5 < uimm5 501// * For the same upper-bound, signed immediates are a superset of unsigned 502// immediates: 503// uimm3 < simm4 < uimm4 < simm4 504// * Modified immediates are a superset of ordinary immediates: 505// uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6 506// The term 'superset' starts to break down here since the uimm5_plus* classes 507// are not true supersets of uimm5 (but they are still subsets of uimm6). 508// * 'Relaxed' immediates are supersets of the corresponding unsigned immediate. 509// uimm16 < uimm16_relaxed 510// * The codeGen pattern type is arbitrarily ordered. 511// uimm5 < uimm5_64, and uimm5 < vsplat_uimm5 512// This is entirely arbitrary. We need an ordering and what we pick is 513// unimportant since only one is possible for a given mnemonic. 514 515def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> { 516 let Name = "UImm32_Coerced"; 517 let DiagnosticType = "UImm32_Coerced"; 518} 519def SImm32RelaxedAsmOperandClass 520 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> { 521 let Name = "SImm32_Relaxed"; 522 let PredicateMethod = "isAnyImm<32>"; 523 let DiagnosticType = "SImm32_Relaxed"; 524} 525def SImm32AsmOperandClass 526 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>; 527def ConstantUImm26AsmOperandClass 528 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>; 529def ConstantUImm20AsmOperandClass 530 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>; 531def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass { 532 let Name = "SImm19Lsl2"; 533 let RenderMethod = "addImmOperands"; 534 let PredicateMethod = "isScaledSImm<19, 2>"; 535 let SuperClasses = [ConstantUImm20AsmOperandClass]; 536 let DiagnosticType = "SImm19_Lsl2"; 537} 538def UImm16RelaxedAsmOperandClass 539 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> { 540 let Name = "UImm16_Relaxed"; 541 let PredicateMethod = "isAnyImm<16>"; 542 let DiagnosticType = "UImm16_Relaxed"; 543} 544// Similar to the relaxed classes which take an SImm and render it as 545// an UImm, this takes a UImm and renders it as an SImm. 546def UImm16AltRelaxedAsmOperandClass 547 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> { 548 let Name = "UImm16_AltRelaxed"; 549 let PredicateMethod = "isUImm<16>"; 550 let DiagnosticType = "UImm16_AltRelaxed"; 551} 552// FIXME: One of these should probably have UImm16AsmOperandClass as the 553// superclass instead of UImm16RelaxedasmOPerandClass. 554def UImm16AsmOperandClass 555 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>; 556def SImm16RelaxedAsmOperandClass 557 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> { 558 let Name = "SImm16_Relaxed"; 559 let PredicateMethod = "isAnyImm<16>"; 560 let DiagnosticType = "SImm16_Relaxed"; 561} 562def SImm16AsmOperandClass 563 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>; 564def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass { 565 let Name = "SImm10Lsl3"; 566 let RenderMethod = "addImmOperands"; 567 let PredicateMethod = "isScaledSImm<10, 3>"; 568 let SuperClasses = [SImm16AsmOperandClass]; 569 let DiagnosticType = "SImm10_Lsl3"; 570} 571def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass { 572 let Name = "SImm10Lsl2"; 573 let RenderMethod = "addImmOperands"; 574 let PredicateMethod = "isScaledSImm<10, 2>"; 575 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass]; 576 let DiagnosticType = "SImm10_Lsl2"; 577} 578def ConstantSImm11AsmOperandClass 579 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>; 580def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass { 581 let Name = "SImm10Lsl1"; 582 let RenderMethod = "addImmOperands"; 583 let PredicateMethod = "isScaledSImm<10, 1>"; 584 let SuperClasses = [ConstantSImm11AsmOperandClass]; 585 let DiagnosticType = "SImm10_Lsl1"; 586} 587def ConstantUImm10AsmOperandClass 588 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>; 589def ConstantSImm10AsmOperandClass 590 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>; 591def ConstantSImm9AsmOperandClass 592 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>; 593def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass { 594 let Name = "SImm7Lsl2"; 595 let RenderMethod = "addImmOperands"; 596 let PredicateMethod = "isScaledSImm<7, 2>"; 597 let SuperClasses = [ConstantSImm9AsmOperandClass]; 598 let DiagnosticType = "SImm7_Lsl2"; 599} 600def ConstantUImm8AsmOperandClass 601 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>; 602def ConstantUImm7Sub1AsmOperandClass 603 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> { 604 // Specify the names since the -1 offset causes invalid identifiers otherwise. 605 let Name = "UImm7_N1"; 606 let DiagnosticType = "UImm7_N1"; 607} 608def ConstantUImm7AsmOperandClass 609 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>; 610def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass { 611 let Name = "UImm6Lsl2"; 612 let RenderMethod = "addImmOperands"; 613 let PredicateMethod = "isScaledUImm<6, 2>"; 614 let SuperClasses = [ConstantUImm7AsmOperandClass]; 615 let DiagnosticType = "UImm6_Lsl2"; 616} 617def ConstantUImm6AsmOperandClass 618 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>; 619def ConstantSImm6AsmOperandClass 620 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>; 621def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass { 622 let Name = "UImm5Lsl2"; 623 let RenderMethod = "addImmOperands"; 624 let PredicateMethod = "isScaledUImm<5, 2>"; 625 let SuperClasses = [ConstantSImm6AsmOperandClass]; 626 let DiagnosticType = "UImm5_Lsl2"; 627} 628def ConstantUImm5_Range2_64AsmOperandClass 629 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>; 630def ConstantUImm5Plus33AsmOperandClass 631 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass], 632 33>; 633def ConstantUImm5ReportUImm6AsmOperandClass 634 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> { 635 let Name = "ConstantUImm5_0_Report_UImm6"; 636 let DiagnosticType = "UImm5_0_Report_UImm6"; 637} 638def ConstantUImm5Plus32AsmOperandClass 639 : ConstantUImmAsmOperandClass< 640 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>; 641def ConstantUImm5Plus32NormalizeAsmOperandClass 642 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> { 643 let Name = "ConstantUImm5_32_Norm"; 644 // We must also subtract 32 when we render the operand. 645 let RenderMethod = "addConstantUImmOperands<5, 32, -32>"; 646} 647def ConstantUImm5Plus1AsmOperandClass 648 : ConstantUImmAsmOperandClass< 649 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>; 650def ConstantUImm5AsmOperandClass 651 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>; 652def ConstantSImm5AsmOperandClass 653 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>; 654def ConstantUImm4AsmOperandClass 655 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>; 656def ConstantSImm4AsmOperandClass 657 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>; 658def ConstantUImm3AsmOperandClass 659 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>; 660def ConstantUImm2Plus1AsmOperandClass 661 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>; 662def ConstantUImm2AsmOperandClass 663 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>; 664def ConstantUImm1AsmOperandClass 665 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>; 666def ConstantImmzAsmOperandClass : AsmOperandClass { 667 let Name = "ConstantImmz"; 668 let RenderMethod = "addConstantUImmOperands<1>"; 669 let PredicateMethod = "isConstantImmz"; 670 let SuperClasses = [ConstantUImm1AsmOperandClass]; 671 let DiagnosticType = "Immz"; 672} 673 674def Simm19Lsl2AsmOperand 675 : SimmLslAsmOperandClass<19, [], 2>; 676 677def MipsJumpTargetAsmOperand : AsmOperandClass { 678 let Name = "JumpTarget"; 679 let ParserMethod = "parseJumpTarget"; 680 let PredicateMethod = "isImm"; 681 let RenderMethod = "addImmOperands"; 682} 683 684// Instruction operand types 685def jmptarget : Operand<OtherVT> { 686 let EncoderMethod = "getJumpTargetOpValue"; 687 let ParserMatchClass = MipsJumpTargetAsmOperand; 688} 689def brtarget : Operand<OtherVT> { 690 let EncoderMethod = "getBranchTargetOpValue"; 691 let OperandType = "OPERAND_PCREL"; 692 let DecoderMethod = "DecodeBranchTarget"; 693 let ParserMatchClass = MipsJumpTargetAsmOperand; 694} 695def brtarget1SImm16 : Operand<OtherVT> { 696 let EncoderMethod = "getBranchTargetOpValue1SImm16"; 697 let OperandType = "OPERAND_PCREL"; 698 let DecoderMethod = "DecodeBranchTarget1SImm16"; 699 let ParserMatchClass = MipsJumpTargetAsmOperand; 700} 701def calltarget : Operand<iPTR> { 702 let EncoderMethod = "getJumpTargetOpValue"; 703 let ParserMatchClass = MipsJumpTargetAsmOperand; 704} 705 706def imm64: Operand<i64>; 707 708def simm19_lsl2 : Operand<i32> { 709 let EncoderMethod = "getSimm19Lsl2Encoding"; 710 let DecoderMethod = "DecodeSimm19Lsl2"; 711 let ParserMatchClass = Simm19Lsl2AsmOperand; 712} 713 714def simm18_lsl3 : Operand<i32> { 715 let EncoderMethod = "getSimm18Lsl3Encoding"; 716 let DecoderMethod = "DecodeSimm18Lsl3"; 717 let ParserMatchClass = MipsJumpTargetAsmOperand; 718} 719 720// Zero 721def uimmz : Operand<i32> { 722 let PrintMethod = "printUImm<0>"; 723 let ParserMatchClass = ConstantImmzAsmOperandClass; 724} 725 726// size operand of ins instruction 727def uimm_range_2_64 : Operand<i32> { 728 let PrintMethod = "printUImm<6, 2>"; 729 let EncoderMethod = "getSizeInsEncoding"; 730 let DecoderMethod = "DecodeInsSize"; 731 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass; 732} 733 734// Unsigned Operands 735foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in 736 def uimm # I : Operand<i32> { 737 let PrintMethod = "printUImm<" # I # ">"; 738 let ParserMatchClass = 739 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass"); 740 } 741 742def uimm2_plus1 : Operand<i32> { 743 let PrintMethod = "printUImm<2, 1>"; 744 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>"; 745 let DecoderMethod = "DecodeUImmWithOffset<2, 1>"; 746 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass; 747} 748 749def uimm5_plus1 : Operand<i32> { 750 let PrintMethod = "printUImm<5, 1>"; 751 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>"; 752 let DecoderMethod = "DecodeUImmWithOffset<5, 1>"; 753 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass; 754} 755 756def uimm5_plus32 : Operand<i32> { 757 let PrintMethod = "printUImm<5, 32>"; 758 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass; 759} 760 761def uimm5_plus33 : Operand<i32> { 762 let PrintMethod = "printUImm<5, 33>"; 763 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>"; 764 let DecoderMethod = "DecodeUImmWithOffset<5, 1>"; 765 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass; 766} 767 768def uimm5_inssize_plus1 : Operand<i32> { 769 let PrintMethod = "printUImm<6>"; 770 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass; 771 let EncoderMethod = "getSizeInsEncoding"; 772 let DecoderMethod = "DecodeInsSize"; 773} 774 775def uimm5_plus32_normalize : Operand<i32> { 776 let PrintMethod = "printUImm<5>"; 777 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass; 778} 779 780def uimm5_lsl2 : Operand<OtherVT> { 781 let EncoderMethod = "getUImm5Lsl2Encoding"; 782 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>"; 783 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass; 784} 785 786def uimm5_plus32_normalize_64 : Operand<i64> { 787 let PrintMethod = "printUImm<5>"; 788 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass; 789} 790 791def uimm6_lsl2 : Operand<OtherVT> { 792 let EncoderMethod = "getUImm6Lsl2Encoding"; 793 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>"; 794 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass; 795} 796 797foreach I = {16} in 798 def uimm # I : Operand<i32> { 799 let PrintMethod = "printUImm<" # I # ">"; 800 let ParserMatchClass = 801 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass"); 802 } 803 804// Like uimm16_64 but coerces simm16 to uimm16. 805def uimm16_relaxed : Operand<i32> { 806 let PrintMethod = "printUImm<16>"; 807 let ParserMatchClass = 808 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass"); 809} 810 811foreach I = {5} in 812 def uimm # I # _64 : Operand<i64> { 813 let PrintMethod = "printUImm<" # I # ">"; 814 let ParserMatchClass = 815 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass"); 816 } 817 818foreach I = {16} in 819 def uimm # I # _64 : Operand<i64> { 820 let PrintMethod = "printUImm<" # I # ">"; 821 let ParserMatchClass = 822 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass"); 823 } 824 825// Like uimm16_64 but coerces simm16 to uimm16. 826def uimm16_64_relaxed : Operand<i64> { 827 let PrintMethod = "printUImm<16>"; 828 let ParserMatchClass = 829 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass"); 830} 831 832def uimm16_altrelaxed : Operand<i32> { 833 let PrintMethod = "printUImm<16>"; 834 let ParserMatchClass = 835 !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass"); 836} 837// Like uimm5 but reports a less confusing error for 32-63 when 838// an instruction alias permits that. 839def uimm5_report_uimm6 : Operand<i32> { 840 let PrintMethod = "printUImm<5>"; 841 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass; 842} 843 844// Like uimm5_64 but reports a less confusing error for 32-63 when 845// an instruction alias permits that. 846def uimm5_64_report_uimm6 : Operand<i64> { 847 let PrintMethod = "printUImm<5>"; 848 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass; 849} 850 851foreach I = {1, 2, 3, 4} in 852 def uimm # I # _ptr : Operand<iPTR> { 853 let PrintMethod = "printUImm<" # I # ">"; 854 let ParserMatchClass = 855 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass"); 856 } 857 858foreach I = {1, 2, 3, 4, 5, 6, 8} in 859 def vsplat_uimm # I : Operand<vAny> { 860 let PrintMethod = "printUImm<" # I # ">"; 861 let ParserMatchClass = 862 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass"); 863 } 864 865// Signed operands 866foreach I = {4, 5, 6, 9, 10, 11} in 867 def simm # I : Operand<i32> { 868 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">"; 869 let ParserMatchClass = 870 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass"); 871 } 872 873foreach I = {1, 2, 3} in 874 def simm10_lsl # I : Operand<i32> { 875 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">"; 876 let ParserMatchClass = 877 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass"); 878 } 879 880foreach I = {10} in 881 def simm # I # _64 : Operand<i64> { 882 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">"; 883 let ParserMatchClass = 884 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass"); 885 } 886 887foreach I = {5, 10} in 888 def vsplat_simm # I : Operand<vAny> { 889 let ParserMatchClass = 890 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass"); 891 } 892 893def simm7_lsl2 : Operand<OtherVT> { 894 let EncoderMethod = "getSImm7Lsl2Encoding"; 895 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>"; 896 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass; 897} 898 899foreach I = {16, 32} in 900 def simm # I : Operand<i32> { 901 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">"; 902 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass"); 903 } 904 905// Like simm16 but coerces uimm16 to simm16. 906def simm16_relaxed : Operand<i32> { 907 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; 908 let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass"); 909} 910 911def simm16_64 : Operand<i64> { 912 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; 913 let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass"); 914} 915 916// like simm32 but coerces simm32 to uimm32. 917def uimm32_coerced : Operand<i32> { 918 let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass"); 919} 920// Like simm32 but coerces uimm32 to simm32. 921def simm32_relaxed : Operand<i32> { 922 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>"; 923 let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass"); 924} 925 926// This is almost the same as a uimm7 but 0x7f is interpreted as -1. 927def li16_imm : Operand<i32> { 928 let DecoderMethod = "DecodeLi16Imm"; 929 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass; 930} 931 932def MipsMemAsmOperand : AsmOperandClass { 933 let Name = "Mem"; 934 let ParserMethod = "parseMemOperand"; 935} 936 937def MipsMemSimm9AsmOperand : AsmOperandClass { 938 let Name = "MemOffsetSimm9"; 939 let SuperClasses = [MipsMemAsmOperand]; 940 let RenderMethod = "addMemOperands"; 941 let ParserMethod = "parseMemOperand"; 942 let PredicateMethod = "isMemWithSimmOffset<9>"; 943 let DiagnosticType = "MemSImm9"; 944} 945 946def MipsMemSimm10AsmOperand : AsmOperandClass { 947 let Name = "MemOffsetSimm10"; 948 let SuperClasses = [MipsMemAsmOperand]; 949 let RenderMethod = "addMemOperands"; 950 let ParserMethod = "parseMemOperand"; 951 let PredicateMethod = "isMemWithSimmOffset<10>"; 952 let DiagnosticType = "MemSImm10"; 953} 954 955def MipsMemSimm12AsmOperand : AsmOperandClass { 956 let Name = "MemOffsetSimm12"; 957 let SuperClasses = [MipsMemAsmOperand]; 958 let RenderMethod = "addMemOperands"; 959 let ParserMethod = "parseMemOperand"; 960 let PredicateMethod = "isMemWithSimmOffset<12>"; 961 let DiagnosticType = "MemSImm12"; 962} 963 964foreach I = {1, 2, 3} in 965 def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass { 966 let Name = "MemOffsetSimm10_" # I; 967 let SuperClasses = [MipsMemAsmOperand]; 968 let RenderMethod = "addMemOperands"; 969 let ParserMethod = "parseMemOperand"; 970 let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">"; 971 let DiagnosticType = "MemSImm10Lsl" # I; 972 } 973 974def MipsMemSimm11AsmOperand : AsmOperandClass { 975 let Name = "MemOffsetSimm11"; 976 let SuperClasses = [MipsMemAsmOperand]; 977 let RenderMethod = "addMemOperands"; 978 let ParserMethod = "parseMemOperand"; 979 let PredicateMethod = "isMemWithSimmOffset<11>"; 980 let DiagnosticType = "MemSImm11"; 981} 982 983def MipsMemSimm16AsmOperand : AsmOperandClass { 984 let Name = "MemOffsetSimm16"; 985 let SuperClasses = [MipsMemAsmOperand]; 986 let RenderMethod = "addMemOperands"; 987 let ParserMethod = "parseMemOperand"; 988 let PredicateMethod = "isMemWithSimmOffset<16>"; 989 let DiagnosticType = "MemSImm16"; 990} 991 992def MipsInvertedImmoperand : AsmOperandClass { 993 let Name = "InvNum"; 994 let RenderMethod = "addImmOperands"; 995 let ParserMethod = "parseInvNum"; 996} 997 998def InvertedImOperand : Operand<i32> { 999 let ParserMatchClass = MipsInvertedImmoperand; 1000} 1001 1002def InvertedImOperand64 : Operand<i64> { 1003 let ParserMatchClass = MipsInvertedImmoperand; 1004} 1005 1006class mem_generic : Operand<iPTR> { 1007 let PrintMethod = "printMemOperand"; 1008 let MIOperandInfo = (ops ptr_rc, simm16); 1009 let EncoderMethod = "getMemEncoding"; 1010 let ParserMatchClass = MipsMemAsmOperand; 1011 let OperandType = "OPERAND_MEMORY"; 1012} 1013 1014// Address operand 1015def mem : mem_generic; 1016 1017// MSA specific address operand 1018def mem_msa : mem_generic { 1019 let MIOperandInfo = (ops ptr_rc, simm10); 1020 let EncoderMethod = "getMSAMemEncoding"; 1021} 1022 1023def simm12 : Operand<i32> { 1024 let DecoderMethod = "DecodeSimm12"; 1025} 1026 1027def mem_simm9 : mem_generic { 1028 let MIOperandInfo = (ops ptr_rc, simm9); 1029 let EncoderMethod = "getMemEncoding"; 1030 let ParserMatchClass = MipsMemSimm9AsmOperand; 1031} 1032 1033def mem_simm10 : mem_generic { 1034 let MIOperandInfo = (ops ptr_rc, simm10); 1035 let EncoderMethod = "getMemEncoding"; 1036 let ParserMatchClass = MipsMemSimm10AsmOperand; 1037} 1038 1039foreach I = {1, 2, 3} in 1040 def mem_simm10_lsl # I : mem_generic { 1041 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I)); 1042 let EncoderMethod = "getMemEncoding<" # I # ">"; 1043 let ParserMatchClass = 1044 !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand"); 1045 } 1046 1047def mem_simm11 : mem_generic { 1048 let MIOperandInfo = (ops ptr_rc, simm11); 1049 let EncoderMethod = "getMemEncoding"; 1050 let ParserMatchClass = MipsMemSimm11AsmOperand; 1051} 1052 1053def mem_simm12 : mem_generic { 1054 let MIOperandInfo = (ops ptr_rc, simm12); 1055 let EncoderMethod = "getMemEncoding"; 1056 let ParserMatchClass = MipsMemSimm12AsmOperand; 1057} 1058 1059def mem_simm16 : mem_generic { 1060 let MIOperandInfo = (ops ptr_rc, simm16); 1061 let EncoderMethod = "getMemEncoding"; 1062 let ParserMatchClass = MipsMemSimm16AsmOperand; 1063} 1064 1065def mem_ea : Operand<iPTR> { 1066 let PrintMethod = "printMemOperandEA"; 1067 let MIOperandInfo = (ops ptr_rc, simm16); 1068 let EncoderMethod = "getMemEncoding"; 1069 let OperandType = "OPERAND_MEMORY"; 1070} 1071 1072def PtrRC : Operand<iPTR> { 1073 let MIOperandInfo = (ops ptr_rc); 1074 let DecoderMethod = "DecodePtrRegisterClass"; 1075 let ParserMatchClass = GPR32AsmOperand; 1076} 1077 1078// size operand of ins instruction 1079def size_ins : Operand<i32> { 1080 let EncoderMethod = "getSizeInsEncoding"; 1081 let DecoderMethod = "DecodeInsSize"; 1082} 1083 1084// Transformation Function - get the lower 16 bits. 1085def LO16 : SDNodeXForm<imm, [{ 1086 return getImm(N, N->getZExtValue() & 0xFFFF); 1087}]>; 1088 1089// Transformation Function - get the higher 16 bits. 1090def HI16 : SDNodeXForm<imm, [{ 1091 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF); 1092}]>; 1093 1094// Plus 1. 1095def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>; 1096 1097// Node immediate is zero (e.g. insve.d) 1098def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>; 1099 1100// Node immediate fits as 16-bit sign extended on target immediate. 1101// e.g. addi, andi 1102def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>; 1103 1104// Node immediate fits as 16-bit sign extended on target immediate. 1105// e.g. addi, andi 1106def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>; 1107 1108// Node immediate fits as 7-bit zero extended on target immediate. 1109def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>; 1110 1111// Node immediate fits as 16-bit zero extended on target immediate. 1112// The LO16 param means that only the lower 16 bits of the node 1113// immediate are caught. 1114// e.g. addiu, sltiu 1115def immZExt16 : PatLeaf<(imm), [{ 1116 if (N->getValueType(0) == MVT::i32) 1117 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue(); 1118 else 1119 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue(); 1120}], LO16>; 1121 1122// Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared). 1123def immSExt32Low16Zero : PatLeaf<(imm), [{ 1124 int64_t Val = N->getSExtValue(); 1125 return isInt<32>(Val) && !(Val & 0xffff); 1126}]>; 1127 1128// Zero-extended 32-bit unsigned int with lower 16-bit cleared. 1129def immZExt32Low16Zero : PatLeaf<(imm), [{ 1130 uint64_t Val = N->getZExtValue(); 1131 return isUInt<32>(Val) && !(Val & 0xffff); 1132}]>; 1133 1134// Note immediate fits as a 32 bit signed extended on target immediate. 1135def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>; 1136 1137// Note immediate fits as a 32 bit zero extended on target immediate. 1138def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>; 1139 1140// shamt field must fit in 5 bits. 1141def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>; 1142 1143def immZExt5Plus1 : PatLeaf<(imm), [{ 1144 return isUInt<5>(N->getZExtValue() - 1); 1145}]>; 1146def immZExt5Plus32 : PatLeaf<(imm), [{ 1147 return isUInt<5>(N->getZExtValue() - 32); 1148}]>; 1149def immZExt5Plus33 : PatLeaf<(imm), [{ 1150 return isUInt<5>(N->getZExtValue() - 33); 1151}]>; 1152 1153// True if (N + 1) fits in 16-bit field. 1154def immSExt16Plus1 : PatLeaf<(imm), [{ 1155 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1); 1156}]>; 1157 1158// Mips Address Mode! SDNode frameindex could possibily be a match 1159// since load and store instructions from stack used it. 1160def addr : 1161 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>; 1162 1163def addrRegImm : 1164 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>; 1165 1166def addrDefault : 1167 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>; 1168 1169def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>; 1170def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1", 1171 [frameindex]>; 1172def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2", 1173 [frameindex]>; 1174def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3", 1175 [frameindex]>; 1176 1177//===----------------------------------------------------------------------===// 1178// Instructions specific format 1179//===----------------------------------------------------------------------===// 1180 1181// Arithmetic and logical instructions with 3 register operands. 1182class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0, 1183 InstrItinClass Itin = NoItinerary, 1184 SDPatternOperator OpNode = null_frag>: 1185 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), 1186 !strconcat(opstr, "\t$rd, $rs, $rt"), 1187 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> { 1188 let isCommutable = isComm; 1189 let isReMaterializable = 1; 1190 let TwoOperandAliasConstraint = "$rd = $rs"; 1191} 1192 1193// Arithmetic and logical instructions with 2 register operands. 1194class ArithLogicI<string opstr, Operand Od, RegisterOperand RO, 1195 InstrItinClass Itin = NoItinerary, 1196 SDPatternOperator imm_type = null_frag, 1197 SDPatternOperator OpNode = null_frag> : 1198 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16), 1199 !strconcat(opstr, "\t$rt, $rs, $imm16"), 1200 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], 1201 Itin, FrmI, opstr> { 1202 let isReMaterializable = 1; 1203 let TwoOperandAliasConstraint = "$rs = $rt"; 1204} 1205 1206// Arithmetic Multiply ADD/SUB 1207class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> : 1208 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), 1209 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> { 1210 let Defs = [HI0, LO0]; 1211 let Uses = [HI0, LO0]; 1212 let isCommutable = isComm; 1213} 1214 1215// Logical 1216class LogicNOR<string opstr, RegisterOperand RO>: 1217 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), 1218 !strconcat(opstr, "\t$rd, $rs, $rt"), 1219 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> { 1220 let isCommutable = 1; 1221} 1222 1223// Shifts 1224class shift_rotate_imm<string opstr, Operand ImmOpnd, 1225 RegisterOperand RO, InstrItinClass itin, 1226 SDPatternOperator OpNode = null_frag, 1227 SDPatternOperator PF = null_frag> : 1228 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt), 1229 !strconcat(opstr, "\t$rd, $rt, $shamt"), 1230 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> { 1231 let TwoOperandAliasConstraint = "$rt = $rd"; 1232} 1233 1234class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin, 1235 SDPatternOperator OpNode = null_frag>: 1236 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs), 1237 !strconcat(opstr, "\t$rd, $rt, $rs"), 1238 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR, 1239 opstr>; 1240 1241// Load Upper Immediate 1242class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>: 1243 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), 1244 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove { 1245 let hasSideEffects = 0; 1246 let isReMaterializable = 1; 1247} 1248 1249// Memory Load/Store 1250class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO, 1251 SDPatternOperator OpNode = null_frag, 1252 InstrItinClass Itin = NoItinerary, 1253 ComplexPattern Addr = addr> : 1254 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), 1255 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> { 1256 let DecoderMethod = "DecodeMem"; 1257 let canFoldAsLoad = 1; 1258 let mayLoad = 1; 1259} 1260 1261class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag, 1262 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : 1263 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>; 1264 1265class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO, 1266 SDPatternOperator OpNode = null_frag, 1267 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : 1268 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"), 1269 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> { 1270 let DecoderMethod = "DecodeMem"; 1271 let mayStore = 1; 1272} 1273 1274class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag, 1275 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr, 1276 DAGOperand MO = mem> : 1277 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>; 1278 1279// Load/Store Left/Right 1280let canFoldAsLoad = 1 in 1281class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO, 1282 InstrItinClass Itin> : 1283 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src), 1284 !strconcat(opstr, "\t$rt, $addr"), 1285 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> { 1286 let DecoderMethod = "DecodeMem"; 1287 string Constraints = "$src = $rt"; 1288} 1289 1290class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO, 1291 InstrItinClass Itin> : 1292 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), 1293 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> { 1294 let DecoderMethod = "DecodeMem"; 1295} 1296 1297// COP2 Load/Store 1298class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin, 1299 SDPatternOperator OpNode= null_frag> : 1300 InstSE<(outs RC:$rt), (ins mem_simm16:$addr), 1301 !strconcat(opstr, "\t$rt, $addr"), 1302 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { 1303 let DecoderMethod = "DecodeFMem2"; 1304 let mayLoad = 1; 1305} 1306 1307class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin, 1308 SDPatternOperator OpNode= null_frag> : 1309 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr), 1310 !strconcat(opstr, "\t$rt, $addr"), 1311 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { 1312 let DecoderMethod = "DecodeFMem2"; 1313 let mayStore = 1; 1314} 1315 1316// COP3 Load/Store 1317class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin, 1318 SDPatternOperator OpNode= null_frag> : 1319 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), 1320 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { 1321 let DecoderMethod = "DecodeFMem3"; 1322 let mayLoad = 1; 1323} 1324 1325class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin, 1326 SDPatternOperator OpNode= null_frag> : 1327 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), 1328 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { 1329 let DecoderMethod = "DecodeFMem3"; 1330 let mayStore = 1; 1331} 1332 1333// Conditional Branch 1334class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op, 1335 RegisterOperand RO, bit DelaySlot = 1> : 1336 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset), 1337 !strconcat(opstr, "\t$rs, $rt, $offset"), 1338 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC, 1339 FrmI, opstr> { 1340 let isBranch = 1; 1341 let isTerminator = 1; 1342 let hasDelaySlot = DelaySlot; 1343 let Defs = [AT]; 1344 bit isCTI = 1; 1345} 1346 1347class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op, 1348 RegisterOperand RO, bit DelaySlot = 1> : 1349 InstSE<(outs), (ins RO:$rs, opnd:$offset), 1350 !strconcat(opstr, "\t$rs, $offset"), 1351 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ, 1352 FrmI, opstr> { 1353 let isBranch = 1; 1354 let isTerminator = 1; 1355 let hasDelaySlot = DelaySlot; 1356 let Defs = [AT]; 1357 bit isCTI = 1; 1358} 1359 1360// SetCC 1361class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> : 1362 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt), 1363 !strconcat(opstr, "\t$rd, $rs, $rt"), 1364 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))], 1365 II_SLT_SLTU, FrmR, opstr>; 1366 1367class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type, 1368 RegisterOperand RO>: 1369 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16), 1370 !strconcat(opstr, "\t$rt, $rs, $imm16"), 1371 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))], 1372 II_SLTI_SLTIU, FrmI, opstr>; 1373 1374// Jump 1375class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator, 1376 SDPatternOperator targetoperator, string bopstr> : 1377 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), 1378 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> { 1379 let isTerminator=1; 1380 let isBarrier=1; 1381 let hasDelaySlot = 1; 1382 let DecoderMethod = "DecodeJumpTarget"; 1383 let Defs = [AT]; 1384 bit isCTI = 1; 1385} 1386 1387// Unconditional branch 1388class UncondBranch<Instruction BEQInst> : 1389 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>, 1390 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> { 1391 let isBranch = 1; 1392 let isTerminator = 1; 1393 let isBarrier = 1; 1394 let hasDelaySlot = 1; 1395 let AdditionalPredicates = [RelocPIC]; 1396 let Defs = [AT]; 1397 bit isCTI = 1; 1398} 1399 1400// Base class for indirect branch and return instruction classes. 1401let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in 1402class JumpFR<string opstr, RegisterOperand RO, 1403 SDPatternOperator operator = null_frag>: 1404 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR, 1405 FrmR, opstr>; 1406 1407// Indirect branch 1408class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> { 1409 let isBranch = 1; 1410 let isIndirectBranch = 1; 1411} 1412 1413// Jump and Link (Call) 1414let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in { 1415 class JumpLink<string opstr, DAGOperand opnd> : 1416 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), 1417 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> { 1418 let DecoderMethod = "DecodeJumpTarget"; 1419 } 1420 1421 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst, 1422 Register RetReg, RegisterOperand ResRO = RO>: 1423 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>, 1424 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>; 1425 1426 class JumpLinkReg<string opstr, RegisterOperand RO>: 1427 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), 1428 [], II_JALR, FrmR, opstr>; 1429 1430 class BGEZAL_FT<string opstr, DAGOperand opnd, 1431 RegisterOperand RO, bit DelaySlot = 1> : 1432 InstSE<(outs), (ins RO:$rs, opnd:$offset), 1433 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> { 1434 let hasDelaySlot = DelaySlot; 1435 } 1436 1437} 1438 1439let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, 1440 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in { 1441 class TailCall<Instruction JumpInst, DAGOperand Opnd> : 1442 PseudoSE<(outs), (ins calltarget:$target), [], II_J>, 1443 PseudoInstExpansion<(JumpInst Opnd:$target)>; 1444 1445 class TailCallReg<RegisterOperand RO> : 1446 MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>; 1447} 1448 1449class BAL_BR_Pseudo<Instruction RealInst> : 1450 PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>, 1451 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> { 1452 let isBranch = 1; 1453 let isTerminator = 1; 1454 let isBarrier = 1; 1455 let hasDelaySlot = 1; 1456 let Defs = [RA]; 1457 bit isCTI = 1; 1458} 1459 1460let isCTI = 1 in { 1461// Syscall 1462class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> : 1463 InstSE<(outs), (ins ImmOp:$code_), 1464 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>; 1465// Break 1466class BRK_FT<string opstr> : 1467 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2), 1468 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK, 1469 FrmOther, opstr>; 1470 1471// (D)Eret 1472class ER_FT<string opstr, InstrItinClass itin = NoItinerary> : 1473 InstSE<(outs), (ins), 1474 opstr, [], itin, FrmOther, opstr>; 1475 1476// Wait 1477class WAIT_FT<string opstr> : 1478 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>; 1479} 1480 1481// Interrupts 1482class DEI_FT<string opstr, RegisterOperand RO, 1483 InstrItinClass itin = NoItinerary> : 1484 InstSE<(outs RO:$rt), (ins), 1485 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>; 1486 1487// Sync 1488let hasSideEffects = 1 in 1489class SYNC_FT<string opstr> : 1490 InstSE<(outs), (ins uimm5:$stype), "sync $stype", 1491 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>; 1492 1493class SYNCI_FT<string opstr> : 1494 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [], 1495 II_SYNCI, FrmOther, opstr> { 1496 let hasSideEffects = 1; 1497 let DecoderMethod = "DecodeSyncI"; 1498} 1499 1500let hasSideEffects = 1, isCTI = 1 in { 1501class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp, 1502 InstrItinClass itin = NoItinerary> : 1503 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_), 1504 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>; 1505 1506class TEQI_FT<string opstr, RegisterOperand RO, 1507 InstrItinClass itin = NoItinerary> : 1508 InstSE<(outs), (ins RO:$rs, simm16:$imm16), 1509 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>; 1510} 1511 1512// Mul, Div 1513class Mult<string opstr, InstrItinClass itin, RegisterOperand RO, 1514 list<Register> DefRegs> : 1515 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [], 1516 itin, FrmR, opstr> { 1517 let isCommutable = 1; 1518 let Defs = DefRegs; 1519 let hasSideEffects = 0; 1520} 1521 1522// Pseudo multiply/divide instruction with explicit accumulator register 1523// operands. 1524class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1, 1525 SDPatternOperator OpNode, InstrItinClass Itin, 1526 bit IsComm = 1, bit HasSideEffects = 0, 1527 bit UsesCustomInserter = 0> : 1528 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt), 1529 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>, 1530 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> { 1531 let isCommutable = IsComm; 1532 let hasSideEffects = HasSideEffects; 1533 let usesCustomInserter = UsesCustomInserter; 1534} 1535 1536// Pseudo multiply add/sub instruction with explicit accumulator register 1537// operands. 1538class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode, 1539 InstrItinClass itin> 1540 : PseudoSE<(outs ACC64:$ac), 1541 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin), 1542 [(set ACC64:$ac, 1543 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))], 1544 itin>, 1545 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> { 1546 string Constraints = "$acin = $ac"; 1547} 1548 1549class Div<string opstr, InstrItinClass itin, RegisterOperand RO, 1550 list<Register> DefRegs> : 1551 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"), 1552 [], itin, FrmR, opstr> { 1553 let Defs = DefRegs; 1554} 1555 1556// Move from Hi/Lo 1557class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode> 1558 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo), 1559 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>; 1560 1561class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>: 1562 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO, 1563 FrmR, opstr> { 1564 let Uses = [UseReg]; 1565 let hasSideEffects = 0; 1566} 1567 1568class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC> 1569 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi), 1570 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))], 1571 II_MTHI_MTLO>; 1572 1573class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>: 1574 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO, 1575 FrmR, opstr> { 1576 let Defs = DefRegs; 1577 let hasSideEffects = 0; 1578} 1579 1580class EffectiveAddress<string opstr, RegisterOperand RO> : 1581 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"), 1582 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI, 1583 !strconcat(opstr, "_lea")> { 1584 let isCodeGenOnly = 1; 1585 let hasNoSchedulingInfo = 1; 1586 let DecoderMethod = "DecodeMem"; 1587} 1588 1589// Count Leading Ones/Zeros in Word 1590class CountLeading0<string opstr, RegisterOperand RO, 1591 InstrItinClass itin = NoItinerary>: 1592 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), 1593 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>; 1594 1595class CountLeading1<string opstr, RegisterOperand RO, 1596 InstrItinClass itin = NoItinerary>: 1597 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), 1598 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>; 1599 1600// Sign Extend in Register. 1601class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO, 1602 InstrItinClass itin> : 1603 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), 1604 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>; 1605 1606// Subword Swap 1607class SubwordSwap<string opstr, RegisterOperand RO, 1608 InstrItinClass itin = NoItinerary>: 1609 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin, 1610 FrmR, opstr> { 1611 let hasSideEffects = 0; 1612} 1613 1614// Read Hardware 1615class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> : 1616 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], 1617 II_RDHWR, FrmR, "rdhwr">; 1618 1619// Ext and Ins 1620class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd, 1621 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm, 1622 SDPatternOperator Op = null_frag> : 1623 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size), 1624 !strconcat(opstr, " $rt, $rs, $pos, $size"), 1625 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT, 1626 FrmR, opstr>, ISA_MIPS32R2; 1627 1628class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd, 1629 Operand SizeOpnd, SDPatternOperator Op = null_frag>: 1630 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src), 1631 !strconcat(opstr, " $rt, $rs, $pos, $size"), 1632 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))], 1633 II_INS, FrmR, opstr>, ISA_MIPS32R2 { 1634 let Constraints = "$src = $rt"; 1635} 1636 1637// Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*). 1638class Atomic2Ops<PatFrag Op, RegisterClass DRC> : 1639 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr), 1640 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>; 1641 1642// Atomic Compare & Swap. 1643class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> : 1644 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap), 1645 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>; 1646 1647class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> : 1648 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"), 1649 [], II_LL, FrmI, opstr> { 1650 let DecoderMethod = "DecodeMem"; 1651 let mayLoad = 1; 1652} 1653 1654class SCBase<string opstr, RegisterOperand RO> : 1655 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr), 1656 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> { 1657 let DecoderMethod = "DecodeMem"; 1658 let mayStore = 1; 1659 let Constraints = "$rt = $dst"; 1660} 1661 1662class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD, 1663 InstrItinClass itin> : 1664 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel), 1665 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>; 1666 1667class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD, 1668 InstrItinClass itin> : 1669 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel), 1670 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>; 1671 1672class TrapBase<Instruction RealInst> 1673 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>, 1674 PseudoInstExpansion<(RealInst 0, 0)> { 1675 let isBarrier = 1; 1676 let isTerminator = 1; 1677 let isCodeGenOnly = 1; 1678 let isCTI = 1; 1679} 1680 1681//===----------------------------------------------------------------------===// 1682// Pseudo instructions 1683//===----------------------------------------------------------------------===// 1684 1685// Return RA. 1686let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in { 1687 let hasDelaySlot=1 in 1688 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>; 1689 1690 let hasSideEffects=1 in 1691 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>; 1692} 1693 1694let Defs = [SP], Uses = [SP], hasSideEffects = 1 in { 1695def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt), 1696 [(callseq_start timm:$amt)]>; 1697def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 1698 [(callseq_end timm:$amt1, timm:$amt2)]>; 1699} 1700 1701let usesCustomInserter = 1 in { 1702 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>; 1703 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>; 1704 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>; 1705 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>; 1706 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>; 1707 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>; 1708 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>; 1709 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>; 1710 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>; 1711 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>; 1712 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>; 1713 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>; 1714 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>; 1715 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>; 1716 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>; 1717 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>; 1718 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>; 1719 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>; 1720 1721 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>; 1722 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>; 1723 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>; 1724 1725 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>; 1726 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>; 1727 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>; 1728} 1729 1730/// Pseudo instructions for loading and storing accumulator registers. 1731let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in { 1732 def LOAD_ACC64 : Load<"", ACC64>; 1733 def STORE_ACC64 : Store<"", ACC64>; 1734} 1735 1736// We need these two pseudo instructions to avoid offset calculation for long 1737// branches. See the comment in file MipsLongBranch.cpp for detailed 1738// explanation. 1739 1740// Expands to: lui $dst, %hi($tgt - $baltgt) 1741def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst), 1742 (ins brtarget:$tgt, brtarget:$baltgt), []>; 1743 1744// Expands to: addiu $dst, $src, %lo($tgt - $baltgt) 1745def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst), 1746 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>; 1747 1748//===----------------------------------------------------------------------===// 1749// Instruction definition 1750//===----------------------------------------------------------------------===// 1751//===----------------------------------------------------------------------===// 1752// MipsI Instructions 1753//===----------------------------------------------------------------------===// 1754 1755/// Arithmetic Instructions (ALU Immediate) 1756let AdditionalPredicates = [NotInMicroMips] in { 1757 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd, 1758 II_ADDIU, immSExt16, add>, 1759 ADDI_FM<0x9>, IsAsCheapAsAMove; 1760 1761 def ANDi : MMRel, StdMMR6Rel, 1762 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>, 1763 ADDI_FM<0xc>; 1764 def ORi : MMRel, StdMMR6Rel, 1765 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>, 1766 ADDI_FM<0xd>; 1767 def XORi : MMRel, StdMMR6Rel, 1768 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>, 1769 ADDI_FM<0xe>; 1770} 1771def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>, ADDI_FM<0x8>, 1772 ISA_MIPS1_NOT_32R6_64R6; 1773let AdditionalPredicates = [NotInMicroMips] in { 1774 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, 1775 SLTI_FM<0xa>; 1776 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>, 1777 SLTI_FM<0xb>; 1778} 1779def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM; 1780let AdditionalPredicates = [NotInMicroMips] in { 1781 /// Arithmetic Instructions (3-Operand, R-Type) 1782 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, 1783 ADD_FM<0, 0x21>; 1784 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>, 1785 ADD_FM<0, 0x23>; 1786} 1787let Defs = [HI0, LO0] in 1788def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>, 1789 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6; 1790def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>, ADD_FM<0, 0x20>; 1791def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>, ADD_FM<0, 0x22>; 1792let AdditionalPredicates = [NotInMicroMips] in { 1793 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>; 1794 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>; 1795 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>, 1796 ADD_FM<0, 0x24>; 1797 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>, 1798 ADD_FM<0, 0x25>; 1799 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>, 1800 ADD_FM<0, 0x26>; 1801 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>; 1802} 1803 1804/// Shift Instructions 1805let AdditionalPredicates = [NotInMicroMips] in { 1806def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl, 1807 immZExt5>, SRA_FM<0, 0>; 1808def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl, 1809 immZExt5>, SRA_FM<2, 0>; 1810def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra, 1811 immZExt5>, SRA_FM<3, 0>; 1812def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>, 1813 SRLV_FM<4, 0>; 1814def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>, 1815 SRLV_FM<6, 0>; 1816def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>, 1817 SRLV_FM<7, 0>; 1818} 1819 1820// Rotate Instructions 1821let AdditionalPredicates = [NotInMicroMips] in { 1822 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr, 1823 immZExt5>, 1824 SRA_FM<2, 1>, ISA_MIPS32R2; 1825 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>, 1826 SRLV_FM<6, 1>, ISA_MIPS32R2; 1827} 1828 1829/// Load and Store Instructions 1830/// aligned 1831def LB : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel, 1832 LW_FM<0x20>; 1833def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU, 1834 addrDefault>, MMRel, LW_FM<0x24>; 1835let AdditionalPredicates = [NotInMicroMips] in { 1836 def LH : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH, 1837 addrDefault>, MMRel, LW_FM<0x21>; 1838 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simm16, zextloadi16, II_LHU>, 1839 MMRel, LW_FM<0x25>; 1840 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel, 1841 LW_FM<0x23>; 1842} 1843def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, 1844 LW_FM<0x28>; 1845def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>; 1846let AdditionalPredicates = [NotInMicroMips] in { 1847def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>; 1848} 1849 1850/// load/store left/right 1851let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug 1852 AdditionalPredicates = [NotInMicroMips] in { 1853def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>, 1854 ISA_MIPS1_NOT_32R6_64R6; 1855def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>, 1856 ISA_MIPS1_NOT_32R6_64R6; 1857def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>, 1858 ISA_MIPS1_NOT_32R6_64R6; 1859def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>, 1860 ISA_MIPS1_NOT_32R6_64R6; 1861} 1862 1863let AdditionalPredicates = [NotInMicroMips] in { 1864// COP2 Memory Instructions 1865def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>, 1866 ISA_MIPS1_NOT_32R6_64R6; 1867def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>, 1868 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6; 1869def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>, 1870 ISA_MIPS2_NOT_32R6_64R6; 1871def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>, 1872 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6; 1873 1874// COP3 Memory Instructions 1875let DecoderNamespace = "COP3_" in { 1876 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>; 1877 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>; 1878 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>, 1879 ISA_MIPS2; 1880 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>, 1881 ISA_MIPS2; 1882} 1883 1884 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2; 1885 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2; 1886} 1887 1888let AdditionalPredicates = [NotInMicroMips] in { 1889 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>, ISA_MIPS2; 1890 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>, ISA_MIPS2; 1891 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>, ISA_MIPS2; 1892 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>, ISA_MIPS2; 1893 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>, ISA_MIPS2; 1894 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>, ISA_MIPS2; 1895} 1896 1897def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>, 1898 ISA_MIPS2_NOT_32R6_64R6; 1899def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>, 1900 ISA_MIPS2_NOT_32R6_64R6; 1901def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>, 1902 ISA_MIPS2_NOT_32R6_64R6; 1903def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>, 1904 ISA_MIPS2_NOT_32R6_64R6; 1905def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>, 1906 ISA_MIPS2_NOT_32R6_64R6; 1907def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>, 1908 ISA_MIPS2_NOT_32R6_64R6; 1909 1910let AdditionalPredicates = [NotInMicroMips] in { 1911def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>; 1912def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>; 1913} 1914def TRAP : TrapBase<BREAK>; 1915let AdditionalPredicates = [NotInMicroMips] in { 1916def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6; 1917} 1918 1919let AdditionalPredicates = [NotInMicroMips] in { 1920 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32; 1921 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>, ISA_MIPS32R5; 1922 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32; 1923} 1924 1925let AdditionalPredicates = [NotInMicroMips] in { 1926 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>, ISA_MIPS32R2; 1927 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>, ISA_MIPS32R2; 1928} 1929 1930let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug 1931 AdditionalPredicates = [NotInMicroMips] in { 1932def WAIT : WAIT_FT<"wait">, WAIT_FM; 1933} 1934 1935let AdditionalPredicates = [NotInMicroMips] in { 1936/// Load-linked, Store-conditional 1937def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6; 1938def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6; 1939} 1940 1941/// Jump and Branch Instructions 1942def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>, 1943 AdditionalRequires<[RelocNotPIC]>, IsBranch; 1944def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6; 1945def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>; 1946def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>, 1947 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6; 1948def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>; 1949def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>, 1950 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6; 1951def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>, 1952 BGEZ_FM<1, 1>; 1953def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>, 1954 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6; 1955def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>, 1956 BGEZ_FM<7, 0>; 1957def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>, 1958 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6; 1959def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>, 1960 BGEZ_FM<6, 0>; 1961def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>, 1962 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6; 1963def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, 1964 BGEZ_FM<1, 0>; 1965def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>, 1966 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6; 1967def B : UncondBranch<BEQ>; 1968 1969def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>; 1970let AdditionalPredicates = [NotInMicroMips] in { 1971 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM; 1972 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>; 1973} 1974 1975def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>, 1976 ISA_MIPS32_NOT_32R6_64R6; 1977def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>, 1978 ISA_MIPS1_NOT_32R6_64R6; 1979def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>, 1980 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6; 1981def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>, 1982 ISA_MIPS1_NOT_32R6_64R6; 1983def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>, 1984 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6; 1985def BAL_BR : BAL_BR_Pseudo<BGEZAL>; 1986 1987let Predicates = [NotInMicroMips] in { 1988 def TAILCALL : TailCall<J, jmptarget>; 1989} 1990 1991def TAILCALLREG : TailCallReg<GPR32Opnd>; 1992 1993// Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64 1994// then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA. 1995class PseudoIndirectBranchBase<RegisterOperand RO> : 1996 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], 1997 II_IndirectBranchPseudo> { 1998 let isTerminator=1; 1999 let isBarrier=1; 2000 let hasDelaySlot = 1; 2001 let isBranch = 1; 2002 let isIndirectBranch = 1; 2003 bit isCTI = 1; 2004} 2005 2006def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>; 2007 2008// Return instructions are matched as a RetRA instruction, then are expanded 2009// into PseudoReturn/PseudoReturn64 after register allocation. Finally, 2010// MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the 2011// ISA. 2012class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs), 2013 [], II_ReturnPseudo> { 2014 let isTerminator = 1; 2015 let isBarrier = 1; 2016 let hasDelaySlot = 1; 2017 let isReturn = 1; 2018 let isCodeGenOnly = 1; 2019 let hasCtrlDep = 1; 2020 let hasExtraSrcRegAllocReq = 1; 2021 bit isCTI = 1; 2022} 2023 2024def PseudoReturn : PseudoReturnBase<GPR32Opnd>; 2025 2026// Exception handling related node and instructions. 2027// The conversion sequence is: 2028// ISD::EH_RETURN -> MipsISD::EH_RETURN -> 2029// MIPSeh_return -> (stack change + indirect branch) 2030// 2031// MIPSeh_return takes the place of regular return instruction 2032// but takes two arguments (V1, V0) which are used for storing 2033// the offset and return address respectively. 2034def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>; 2035 2036def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET, 2037 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 2038 2039let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in { 2040 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst), 2041 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>; 2042 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, 2043 GPR64:$dst), 2044 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>; 2045} 2046 2047/// Multiply and Divide Instructions. 2048def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>, 2049 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6; 2050def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, 2051 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6; 2052let AdditionalPredicates = [NotInMicroMips] in { 2053 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, 2054 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6; 2055 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, 2056 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6; 2057} 2058def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>, 2059 ISA_MIPS1_NOT_32R6_64R6; 2060def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>, 2061 ISA_MIPS1_NOT_32R6_64R6; 2062let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug 2063 AdditionalPredicates = [NotInMicroMips] in { 2064def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>, 2065 ISA_MIPS1_NOT_32R6_64R6; 2066def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>, 2067 ISA_MIPS1_NOT_32R6_64R6; 2068} 2069 2070/// Sign Ext In Register Instructions. 2071def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, 2072 SEB_FM<0x10, 0x20>, ISA_MIPS32R2; 2073def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>, 2074 SEB_FM<0x18, 0x20>, ISA_MIPS32R2; 2075 2076/// Count Leading 2077def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>, 2078 ISA_MIPS32_NOT_32R6_64R6; 2079def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>, 2080 ISA_MIPS32_NOT_32R6_64R6; 2081 2082let AdditionalPredicates = [NotInMicroMips] in { 2083 /// Word Swap Bytes Within Halfwords 2084 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>, 2085 ISA_MIPS32R2; 2086} 2087 2088/// No operation. 2089def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>; 2090 2091// FrameIndexes are legalized when they are operands from load/store 2092// instructions. The same not happens for stack address copies, so an 2093// add op with mem ComplexPattern is used and the stack address copy 2094// can be matched. It's similar to Sparc LEA_ADDRi 2095def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>; 2096 2097// MADD*/MSUB* 2098def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>, 2099 ISA_MIPS32_NOT_32R6_64R6; 2100def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>, 2101 ISA_MIPS32_NOT_32R6_64R6; 2102def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>, 2103 ISA_MIPS32_NOT_32R6_64R6; 2104def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>, 2105 ISA_MIPS32_NOT_32R6_64R6; 2106 2107let AdditionalPredicates = [NotDSP] in { 2108def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>, 2109 ISA_MIPS1_NOT_32R6_64R6; 2110def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>, 2111 ISA_MIPS1_NOT_32R6_64R6; 2112def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6; 2113def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6; 2114def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6; 2115def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>, 2116 ISA_MIPS32_NOT_32R6_64R6; 2117def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>, 2118 ISA_MIPS32_NOT_32R6_64R6; 2119def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>, 2120 ISA_MIPS32_NOT_32R6_64R6; 2121def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>, 2122 ISA_MIPS32_NOT_32R6_64R6; 2123} 2124 2125let AdditionalPredicates = [NotInMicroMips] in { 2126 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV, 2127 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; 2128 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU, 2129 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6; 2130 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM; 2131 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction 2132 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, 2133 immZExt5, immZExt5Plus1, MipsExt>, 2134 EXT_FM<0>; 2135 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5, 2136 uimm5_inssize_plus1, MipsIns>, 2137 EXT_FM<4>; 2138} 2139/// Move Control Registers From/To CPU Registers 2140let AdditionalPredicates = [NotInMicroMips] in { 2141 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, MFC3OP_FM<0x10, 4>, 2142 ISA_MIPS32; 2143 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, MFC3OP_FM<0x10, 0>, 2144 ISA_MIPS32; 2145} 2146def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, MFC3OP_FM<0x12, 0>; 2147def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, MFC3OP_FM<0x12, 4>; 2148 2149class Barrier<string asmstr, InstrItinClass itin = NoItinerary> : 2150 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>; 2151 2152def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>; 2153def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>; 2154 2155let isCTI = 1 in 2156def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>, 2157 ISA_MIPS32R2; 2158 2159// JR_HB and JALR_HB are defined here using the new style naming 2160// scheme because some of this code is shared with Mips32r6InstrInfo.td 2161// and because of that it doesn't follow the naming convention of the 2162// rest of the file. To avoid a mixture of old vs new style, the new 2163// style was chosen. 2164class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> { 2165 dag OutOperandList = (outs); 2166 dag InOperandList = (ins GPROpnd:$rs); 2167 string AsmString = !strconcat(instr_asm, "\t$rs"); 2168 list<dag> Pattern = []; 2169} 2170 2171class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> { 2172 dag OutOperandList = (outs GPROpnd:$rd); 2173 dag InOperandList = (ins GPROpnd:$rs); 2174 string AsmString = !strconcat(instr_asm, "\t$rd, $rs"); 2175 list<dag> Pattern = []; 2176} 2177 2178class JR_HB_DESC : InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>, 2179 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> { 2180 let isBranch=1; 2181 let isIndirectBranch=1; 2182 let hasDelaySlot=1; 2183 let isTerminator=1; 2184 let isBarrier=1; 2185 bit isCTI = 1; 2186} 2187 2188class JALR_HB_DESC : InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>, 2189 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> { 2190 let isIndirectBranch=1; 2191 let hasDelaySlot=1; 2192 bit isCTI = 1; 2193} 2194 2195class JR_HB_ENC : JR_HB_FM<8>; 2196class JALR_HB_ENC : JALR_HB_FM<9>; 2197 2198def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6; 2199def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32; 2200 2201class TLB<string asmstr, InstrItinClass itin = NoItinerary> : 2202 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>; 2203let AdditionalPredicates = [NotInMicroMips] in { 2204def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>; 2205def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>; 2206def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>; 2207def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>; 2208} 2209class CacheOp<string instr_asm, Operand MemOpnd, 2210 InstrItinClass itin = NoItinerary> : 2211 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint), 2212 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther, 2213 instr_asm> { 2214 let DecoderMethod = "DecodeCacheOp"; 2215} 2216 2217def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>, 2218 INSN_MIPS3_32_NOT_32R6_64R6; 2219def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>, 2220 INSN_MIPS3_32_NOT_32R6_64R6; 2221 2222def ROL : MipsAsmPseudoInst<(outs), 2223 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd), 2224 "rol\t$rs, $rt, $rd">; 2225def ROLImm : MipsAsmPseudoInst<(outs), 2226 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 2227 "rol\t$rs, $rt, $imm">; 2228def : MipsInstAlias<"rol $rd, $rs", 2229 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>; 2230def : MipsInstAlias<"rol $rd, $imm", 2231 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>; 2232 2233def ROR : MipsAsmPseudoInst<(outs), 2234 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd), 2235 "ror\t$rs, $rt, $rd">; 2236def RORImm : MipsAsmPseudoInst<(outs), 2237 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 2238 "ror\t$rs, $rt, $imm">; 2239def : MipsInstAlias<"ror $rd, $rs", 2240 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>; 2241def : MipsInstAlias<"ror $rd, $imm", 2242 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>; 2243 2244def DROL : MipsAsmPseudoInst<(outs), 2245 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd), 2246 "drol\t$rs, $rt, $rd">, ISA_MIPS64; 2247def DROLImm : MipsAsmPseudoInst<(outs), 2248 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 2249 "drol\t$rs, $rt, $imm">, ISA_MIPS64; 2250def : MipsInstAlias<"drol $rd, $rs", 2251 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64; 2252def : MipsInstAlias<"drol $rd, $imm", 2253 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64; 2254 2255def DROR : MipsAsmPseudoInst<(outs), 2256 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd), 2257 "dror\t$rs, $rt, $rd">, ISA_MIPS64; 2258def DRORImm : MipsAsmPseudoInst<(outs), 2259 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 2260 "dror\t$rs, $rt, $imm">, ISA_MIPS64; 2261def : MipsInstAlias<"dror $rd, $rs", 2262 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64; 2263def : MipsInstAlias<"dror $rd, $imm", 2264 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64; 2265 2266def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs), 2267 "abs\t$rd, $rs">; 2268 2269def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), 2270 (ins GPR32Opnd:$rs, GPR32Opnd:$rt), 2271 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS; 2272 2273def : MipsInstAlias<"seq $rd, $rs", 2274 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, 2275 NOT_ASE_CNMIPS; 2276 2277def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), 2278 (ins GPR32Opnd:$rs, simm32_relaxed:$imm), 2279 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS; 2280 2281def : MipsInstAlias<"seq $rd, $imm", 2282 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>, 2283 NOT_ASE_CNMIPS; 2284//===----------------------------------------------------------------------===// 2285// Instruction aliases 2286//===----------------------------------------------------------------------===// 2287def : MipsInstAlias<"move $dst, $src", 2288 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>, 2289 GPR_32 { 2290 let AdditionalPredicates = [NotInMicroMips]; 2291} 2292def : MipsInstAlias<"move $dst, $src", 2293 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>, 2294 GPR_32 { 2295 let AdditionalPredicates = [NotInMicroMips]; 2296} 2297def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>, 2298 ISA_MIPS1_NOT_32R6_64R6; 2299def : MipsInstAlias< 2300 "addu $rs, $rt, $imm", 2301 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; 2302def : MipsInstAlias< 2303 "addu $rs, $imm", 2304 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; 2305def : MipsInstAlias< 2306 "add $rs, $rt, $imm", 2307 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>, 2308 ISA_MIPS1_NOT_32R6_64R6; 2309def : MipsInstAlias< 2310 "add $rs, $imm", 2311 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>, 2312 ISA_MIPS1_NOT_32R6_64R6; 2313def : MipsInstAlias< 2314 "and $rs, $rt, $imm", 2315 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; 2316def : MipsInstAlias< 2317 "and $rs, $imm", 2318 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; 2319def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>; 2320let Predicates = [NotInMicroMips] in { 2321def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>; 2322} 2323def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32; 2324def : MipsInstAlias<"neg $rt, $rs", 2325 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; 2326def : MipsInstAlias<"neg $rt", 2327 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>; 2328def : MipsInstAlias<"negu $rt, $rs", 2329 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; 2330def : MipsInstAlias<"negu $rt", 2331 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>; 2332let AdditionalPredicates = [NotInMicroMips] in { 2333 def : MipsInstAlias< 2334 "sgt $rd, $rs, $rt", 2335 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; 2336 def : MipsInstAlias< 2337 "sgt $rs, $rt", 2338 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; 2339 def : MipsInstAlias< 2340 "sgtu $rd, $rs, $rt", 2341 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; 2342 def : MipsInstAlias< 2343 "sgtu $$rs, $rt", 2344 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; 2345 def : MipsInstAlias< 2346 "slt $rs, $rt, $imm", 2347 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; 2348 def : MipsInstAlias< 2349 "sltu $rt, $rs, $imm", 2350 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; 2351 def : MipsInstAlias< 2352 "and $rs, $rt, $imm", 2353 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; 2354 def : MipsInstAlias< 2355 "and $rs, $imm", 2356 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; 2357 def : MipsInstAlias< 2358 "xor $rs, $rt, $imm", 2359 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; 2360 def : MipsInstAlias< 2361 "xor $rs, $imm", 2362 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; 2363 def : MipsInstAlias< 2364 "or $rs, $rt, $imm", 2365 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; 2366 def : MipsInstAlias< 2367 "or $rs, $imm", 2368 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; 2369 def : MipsInstAlias< 2370 "not $rt, $rs", 2371 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>; 2372 def : MipsInstAlias< 2373 "not $rt", 2374 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>; 2375 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; 2376} 2377def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>; 2378def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>; 2379def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>; 2380def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>; 2381let AdditionalPredicates = [NotInMicroMips] in { 2382def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>; 2383} 2384def : MipsInstAlias<"bnez $rs,$offset", 2385 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; 2386def : MipsInstAlias<"bnezl $rs,$offset", 2387 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; 2388def : MipsInstAlias<"beqz $rs,$offset", 2389 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; 2390def : MipsInstAlias<"beqzl $rs,$offset", 2391 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; 2392let AdditionalPredicates = [NotInMicroMips] in { 2393 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>; 2394} 2395 2396def : MipsInstAlias<"break", (BREAK 0, 0), 1>; 2397def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>; 2398let AdditionalPredicates = [NotInMicroMips] in { 2399 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2; 2400 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2; 2401} 2402let AdditionalPredicates = [NotInMicroMips] in { 2403 def : MipsInstAlias<"teq $rs, $rt", 2404 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; 2405 def : MipsInstAlias<"tge $rs, $rt", 2406 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; 2407 def : MipsInstAlias<"tgeu $rs, $rt", 2408 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; 2409 def : MipsInstAlias<"tlt $rs, $rt", 2410 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; 2411 def : MipsInstAlias<"tltu $rs, $rt", 2412 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; 2413 def : MipsInstAlias<"tne $rs, $rt", 2414 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2; 2415} 2416def : MipsInstAlias<"sub, $rd, $rs, $imm", 2417 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs, 2418 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6; 2419def : MipsInstAlias<"sub $rs, $imm", 2420 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm), 2421 0>, ISA_MIPS1_NOT_32R6_64R6; 2422def : MipsInstAlias<"subu, $rd, $rs, $imm", 2423 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs, 2424 InvertedImOperand:$imm), 0>; 2425def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, 2426 InvertedImOperand:$imm), 0>; 2427let AdditionalPredicates = [NotInMicroMips] in { 2428 def : MipsInstAlias<"sll $rd, $rt, $rs", 2429 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; 2430 def : MipsInstAlias<"sra $rd, $rt, $rs", 2431 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; 2432 def : MipsInstAlias<"srl $rd, $rt, $rs", 2433 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>; 2434 def : MipsInstAlias<"sll $rd, $rt", 2435 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>; 2436 def : MipsInstAlias<"sra $rd, $rt", 2437 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>; 2438 def : MipsInstAlias<"srl $rd, $rt", 2439 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>; 2440 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>, 2441 ISA_MIPS32R2; 2442 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>, 2443 ISA_MIPS32R2; 2444} 2445def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6; 2446def : MipsInstAlias<"sync", 2447 (SYNC 0), 1>, ISA_MIPS2; 2448//===----------------------------------------------------------------------===// 2449// Assembler Pseudo Instructions 2450//===----------------------------------------------------------------------===// 2451 2452// We use uimm32_coerced to accept a 33 bit signed number that is rendered into 2453// a 32 bit number. 2454class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> : 2455 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), 2456 !strconcat(instr_asm, "\t$rt, $imm32")> ; 2457def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>; 2458 2459class LoadAddressFromReg32<string instr_asm, Operand MemOpnd, 2460 RegisterOperand RO> : 2461 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr), 2462 !strconcat(instr_asm, "\t$rt, $addr")> ; 2463def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>; 2464 2465class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> : 2466 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), 2467 !strconcat(instr_asm, "\t$rt, $imm32")> ; 2468def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>; 2469 2470def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs), 2471 "jal\t$rd, $rs"> ; 2472def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs), 2473 "jal\t$rs"> ; 2474 2475def NORImm : MipsAsmPseudoInst< 2476 (outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 2477 "nor\t$rs, $rt, $imm"> ; 2478 2479let hasDelaySlot = 1, isCTI = 1 in { 2480def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), 2481 (ins imm64:$imm64, brtarget:$offset), 2482 "bne\t$rt, $imm64, $offset">; 2483def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), 2484 (ins imm64:$imm64, brtarget:$offset), 2485 "beq\t$rt, $imm64, $offset">; 2486 2487class CondBranchPseudo<string instr_asm> : 2488 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, 2489 brtarget:$offset), 2490 !strconcat(instr_asm, "\t$rs, $rt, $offset")>; 2491} 2492 2493def BLT : CondBranchPseudo<"blt">; 2494def BLE : CondBranchPseudo<"ble">; 2495def BGE : CondBranchPseudo<"bge">; 2496def BGT : CondBranchPseudo<"bgt">; 2497def BLTU : CondBranchPseudo<"bltu">; 2498def BLEU : CondBranchPseudo<"bleu">; 2499def BGEU : CondBranchPseudo<"bgeu">; 2500def BGTU : CondBranchPseudo<"bgtu">; 2501def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6; 2502def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6; 2503def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6; 2504def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6; 2505def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6; 2506def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6; 2507def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6; 2508def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6; 2509 2510let isCTI = 1 in 2511class CondBranchImmPseudo<string instr_asm> : 2512 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset), 2513 !strconcat(instr_asm, "\t$rs, $imm, $offset")>; 2514 2515def BLTImmMacro : CondBranchImmPseudo<"blt">; 2516def BLEImmMacro : CondBranchImmPseudo<"ble">; 2517def BGEImmMacro : CondBranchImmPseudo<"bge">; 2518def BGTImmMacro : CondBranchImmPseudo<"bgt">; 2519def BLTUImmMacro : CondBranchImmPseudo<"bltu">; 2520def BLEUImmMacro : CondBranchImmPseudo<"bleu">; 2521def BGEUImmMacro : CondBranchImmPseudo<"bgeu">; 2522def BGTUImmMacro : CondBranchImmPseudo<"bgtu">; 2523def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6; 2524def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6; 2525def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6; 2526def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6; 2527def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6; 2528def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6; 2529def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6; 2530def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6; 2531 2532// FIXME: Predicates are removed because instructions are matched regardless of 2533// predicates, because PredicateControl was not in the hierarchy. This was 2534// done to emit more precise error message from expansion function. 2535// Once the tablegen-erated errors are made better, this needs to be fixed and 2536// predicates needs to be restored. 2537 2538def SDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), 2539 (ins GPR32Opnd:$rs, GPR32Opnd:$rt), 2540 "div\t$rd, $rs, $rt">, 2541 ISA_MIPS1_NOT_32R6_64R6; 2542def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), 2543 (ins GPR32Opnd:$rs, GPR32Opnd:$rt), 2544 "divu\t$rd, $rs, $rt">, 2545 ISA_MIPS1_NOT_32R6_64R6; 2546def : MipsInstAlias<"div $rt, $rs", (SDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt, 2547 GPR32Opnd:$rs), 0>, 2548 ISA_MIPS1_NOT_32R6_64R6; 2549def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt, 2550 GPR32Opnd:$rs), 0>, 2551 ISA_MIPS1_NOT_32R6_64R6; 2552def DSDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), 2553 (ins GPR32Opnd:$rs, GPR32Opnd:$rt), 2554 "ddiv\t$rd, $rs, $rt">, 2555 ISA_MIPS64_NOT_64R6; 2556def DUDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), 2557 (ins GPR32Opnd:$rs, GPR32Opnd:$rt), 2558 "ddivu\t$rd, $rs, $rt">, 2559 ISA_MIPS64_NOT_64R6; 2560def : MipsInstAlias<"ddiv $rt, $rs", (DSDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt, 2561 GPR32Opnd:$rs), 0>, 2562 ISA_MIPS64_NOT_64R6; 2563def : MipsInstAlias<"ddivu $rt, $rs", (DUDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt, 2564 GPR32Opnd:$rs), 0>, 2565 ISA_MIPS64_NOT_64R6; 2566 2567def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), 2568 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; 2569 2570def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), 2571 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; 2572 2573def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), 2574 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; 2575 2576def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), 2577 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; 2578 2579def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), 2580 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; 2581 2582def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), 2583 (ins mem_simm16:$addr), "ld $rt, $addr">, 2584 ISA_MIPS1_NOT_MIPS3; 2585def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), 2586 (ins mem_simm16:$addr), "sd $rt, $addr">, 2587 ISA_MIPS1_NOT_MIPS3; 2588//===----------------------------------------------------------------------===// 2589// Arbitrary patterns that map to one or more instructions 2590//===----------------------------------------------------------------------===// 2591 2592// Load/store pattern templates. 2593class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> : 2594 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>; 2595 2596class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> : 2597 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>; 2598 2599// Materialize constants. 2600multiclass MaterializeImms<ValueType VT, Register ZEROReg, 2601 Instruction ADDiuOp, Instruction LUiOp, 2602 Instruction ORiOp> { 2603 2604// Small immediates 2605def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>; 2606def : MipsPat<(VT immZExt16:$imm), (ORiOp ZEROReg, imm:$imm)>; 2607 2608// Bits 32-16 set, sign/zero extended. 2609def : MipsPat<(VT immSExt32Low16Zero:$imm), (LUiOp (HI16 imm:$imm))>; 2610 2611// Arbitrary immediates 2612def : MipsPat<(VT immSExt32:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>; 2613} 2614 2615let AdditionalPredicates = [NotInMicroMips] in 2616 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>; 2617 2618// Carry MipsPatterns 2619let AdditionalPredicates = [NotInMicroMips] in { 2620 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs), 2621 (SUBu GPR32:$lhs, GPR32:$rhs)>; 2622} 2623def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs), 2624 (ADDu GPR32:$lhs, GPR32:$rhs)>, ASE_NOT_DSP; 2625def : MipsPat<(addc GPR32:$src, immSExt16:$imm), 2626 (ADDiu GPR32:$src, imm:$imm)>, ASE_NOT_DSP; 2627 2628// Support multiplication for pre-Mips32 targets that don't have 2629// the MUL instruction. 2630def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs), 2631 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>, 2632 ISA_MIPS1_NOT_32R6_64R6; 2633 2634// SYNC 2635def : MipsPat<(MipsSync (i32 immz)), 2636 (SYNC 0)>, ISA_MIPS2; 2637 2638// Call 2639def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)), 2640 (JAL texternalsym:$dst)>; 2641//def : MipsPat<(MipsJmpLink GPR32:$dst), 2642// (JALR GPR32:$dst)>; 2643 2644// Tail call 2645def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)), 2646 (TAILCALL tglobaladdr:$dst)>; 2647def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)), 2648 (TAILCALL texternalsym:$dst)>; 2649// hi/lo relocs 2650def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>; 2651def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>; 2652def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>; 2653def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>; 2654def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>; 2655def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>; 2656 2657def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>; 2658def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>; 2659def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>; 2660def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>; 2661def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>; 2662def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>; 2663 2664def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)), 2665 (ADDiu GPR32:$hi, tglobaladdr:$lo)>; 2666def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)), 2667 (ADDiu GPR32:$hi, tblockaddress:$lo)>; 2668def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)), 2669 (ADDiu GPR32:$hi, tjumptable:$lo)>; 2670def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)), 2671 (ADDiu GPR32:$hi, tconstpool:$lo)>; 2672def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)), 2673 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>; 2674 2675// gp_rel relocs 2676def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)), 2677 (ADDiu GPR32:$gp, tglobaladdr:$in)>; 2678def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)), 2679 (ADDiu GPR32:$gp, tconstpool:$in)>; 2680 2681// wrapper_pic 2682class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>: 2683 MipsPat<(MipsWrapper RC:$gp, node:$in), 2684 (ADDiuOp RC:$gp, node:$in)>; 2685 2686def : WrapperPat<tglobaladdr, ADDiu, GPR32>; 2687def : WrapperPat<tconstpool, ADDiu, GPR32>; 2688def : WrapperPat<texternalsym, ADDiu, GPR32>; 2689def : WrapperPat<tblockaddress, ADDiu, GPR32>; 2690def : WrapperPat<tjumptable, ADDiu, GPR32>; 2691def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>; 2692 2693let AdditionalPredicates = [NotInMicroMips] in { 2694// Mips does not have "not", so we expand our way 2695def : MipsPat<(not GPR32:$in), 2696 (NOR GPR32Opnd:$in, ZERO)>; 2697} 2698 2699// extended loads 2700def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>; 2701def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>; 2702let AdditionalPredicates = [NotInMicroMips] in { 2703 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>; 2704} 2705 2706// peepholes 2707def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>; 2708 2709// brcond patterns 2710multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1, 2711 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp, 2712 Instruction SLTiOp, Instruction SLTiuOp, 2713 Register ZEROReg> { 2714def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst), 2715 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>; 2716def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst), 2717 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>; 2718 2719def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst), 2720 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>; 2721def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst), 2722 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>; 2723def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst), 2724 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; 2725def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst), 2726 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; 2727def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), 2728 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; 2729def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), 2730 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; 2731 2732def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst), 2733 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; 2734def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst), 2735 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; 2736 2737def : MipsPat<(brcond RC:$cond, bb:$dst), 2738 (BNEOp RC:$cond, ZEROReg, bb:$dst)>; 2739} 2740let AdditionalPredicates = [NotInMicroMips] in { 2741 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>; 2742} 2743def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst), 2744 (BLEZ i32:$lhs, bb:$dst)>; 2745def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst), 2746 (BGEZ i32:$lhs, bb:$dst)>; 2747 2748// setcc patterns 2749multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp, 2750 Instruction SLTuOp, Register ZEROReg> { 2751 def : MipsPat<(seteq RC:$lhs, 0), 2752 (SLTiuOp RC:$lhs, 1)>; 2753 def : MipsPat<(setne RC:$lhs, 0), 2754 (SLTuOp ZEROReg, RC:$lhs)>; 2755 def : MipsPat<(seteq RC:$lhs, RC:$rhs), 2756 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>; 2757 def : MipsPat<(setne RC:$lhs, RC:$rhs), 2758 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>; 2759} 2760 2761multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp, 2762 Instruction SLTuOp> { 2763 def : MipsPat<(setle RC:$lhs, RC:$rhs), 2764 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>; 2765 def : MipsPat<(setule RC:$lhs, RC:$rhs), 2766 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>; 2767} 2768 2769multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> { 2770 def : MipsPat<(setgt RC:$lhs, RC:$rhs), 2771 (SLTOp RC:$rhs, RC:$lhs)>; 2772 def : MipsPat<(setugt RC:$lhs, RC:$rhs), 2773 (SLTuOp RC:$rhs, RC:$lhs)>; 2774} 2775 2776multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp, 2777 Instruction SLTuOp> { 2778 def : MipsPat<(setge RC:$lhs, RC:$rhs), 2779 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>; 2780 def : MipsPat<(setuge RC:$lhs, RC:$rhs), 2781 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>; 2782} 2783 2784multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp, 2785 Instruction SLTiOp, Instruction SLTiuOp> { 2786 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs), 2787 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>; 2788 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs), 2789 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>; 2790} 2791 2792let AdditionalPredicates = [NotInMicroMips] in { 2793 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>; 2794 defm : SetlePats<GPR32, XORi, SLT, SLTu>; 2795 defm : SetgtPats<GPR32, SLT, SLTu>; 2796 defm : SetgePats<GPR32, XORi, SLT, SLTu>; 2797 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>; 2798} 2799 2800// bswap pattern 2801def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>; 2802 2803// Load halfword/word patterns. 2804let AddedComplexity = 40 in { 2805 def : LoadRegImmPat<LBu, i32, zextloadi8>; 2806 let AdditionalPredicates = [NotInMicroMips] in { 2807 def : LoadRegImmPat<LH, i32, sextloadi16>; 2808 def : LoadRegImmPat<LW, i32, load>; 2809 } 2810} 2811 2812// Atomic load patterns. 2813def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>; 2814let AdditionalPredicates = [NotInMicroMips] in { 2815 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>; 2816} 2817def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>; 2818 2819// Atomic store patterns. 2820def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>; 2821def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>; 2822def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>; 2823 2824//===----------------------------------------------------------------------===// 2825// Floating Point Support 2826//===----------------------------------------------------------------------===// 2827 2828include "MipsInstrFPU.td" 2829include "Mips64InstrInfo.td" 2830include "MipsCondMov.td" 2831 2832include "Mips32r6InstrInfo.td" 2833include "Mips64r6InstrInfo.td" 2834 2835// 2836// Mips16 2837 2838include "Mips16InstrFormats.td" 2839include "Mips16InstrInfo.td" 2840 2841// DSP 2842include "MipsDSPInstrFormats.td" 2843include "MipsDSPInstrInfo.td" 2844 2845// MSA 2846include "MipsMSAInstrFormats.td" 2847include "MipsMSAInstrInfo.td" 2848 2849// EVA 2850include "MipsEVAInstrFormats.td" 2851include "MipsEVAInstrInfo.td" 2852 2853// Micromips 2854include "MicroMipsInstrFormats.td" 2855include "MicroMipsInstrInfo.td" 2856include "MicroMipsInstrFPU.td" 2857 2858// Micromips r6 2859include "MicroMips32r6InstrFormats.td" 2860include "MicroMips32r6InstrInfo.td" 2861 2862// Micromips64 r6 2863include "MicroMips64r6InstrFormats.td" 2864include "MicroMips64r6InstrInfo.td" 2865 2866// Micromips DSP 2867include "MicroMipsDSPInstrFormats.td" 2868include "MicroMipsDSPInstrInfo.td" 2869