MipsInstrInfo.td revision a6d6ef6dac9407840aadf1e657ba58989946173e
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_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 20def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; 21def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, 22 SDTCisSameAs<1, 2>, 23 SDTCisSameAs<3, 4>, 24 SDTCisInt<4>]>; 25def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; 26def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 27def SDT_MipsMAddMSub : SDTypeProfile<0, 4, 28 [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, 29 SDTCisSameAs<1, 2>, 30 SDTCisSameAs<2, 3>]>; 31def SDT_MipsDivRem : SDTypeProfile<0, 2, 32 [SDTCisInt<0>, 33 SDTCisSameAs<0, 1>]>; 34 35def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 36 37def SDT_MipsDynAlloc : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, 38 SDTCisSameAs<0, 1>]>; 39def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 40 41def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 42 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>; 43def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 44 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>, 45 SDTCisSameAs<0, 4>]>; 46 47def SDTMipsLoadLR : SDTypeProfile<1, 2, 48 [SDTCisInt<0>, SDTCisPtrTy<1>, 49 SDTCisSameAs<0, 2>]>; 50 51// Call 52def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, 53 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 54 SDNPVariadic]>; 55 56// Hi and Lo nodes are used to handle global addresses. Used on 57// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol 58// static model. (nothing to do with Mips Registers Hi and Lo) 59def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>; 60def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>; 61def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>; 62 63// TlsGd node is used to handle General Dynamic TLS 64def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>; 65 66// TprelHi and TprelLo nodes are used to handle Local Exec TLS 67def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>; 68def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>; 69 70// Thread pointer 71def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>; 72 73// Return 74def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, 75 SDNPOptInGlue]>; 76 77// These are target-independent nodes, but have target-specific formats. 78def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart, 79 [SDNPHasChain, SDNPOutGlue]>; 80def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd, 81 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 82 83// MAdd*/MSub* nodes 84def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub, 85 [SDNPOptInGlue, SDNPOutGlue]>; 86def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub, 87 [SDNPOptInGlue, SDNPOutGlue]>; 88def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub, 89 [SDNPOptInGlue, SDNPOutGlue]>; 90def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub, 91 [SDNPOptInGlue, SDNPOutGlue]>; 92 93// DivRem(u) nodes 94def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsDivRem, 95 [SDNPOutGlue]>; 96def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsDivRem, 97 [SDNPOutGlue]>; 98 99// Target constant nodes that are not part of any isel patterns and remain 100// unchanged can cause instructions with illegal operands to be emitted. 101// Wrapper node patterns give the instruction selector a chance to replace 102// target constant nodes that would otherwise remain unchanged with ADDiu 103// nodes. Without these wrapper node patterns, the following conditional move 104// instrucion is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is 105// compiled: 106// movn %got(d)($gp), %got(c)($gp), $4 107// This instruction is illegal since movn can take only register operands. 108 109def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>; 110 111// Pointer to dynamically allocated stack area. 112def MipsDynAlloc : SDNode<"MipsISD::DynAlloc", SDT_MipsDynAlloc, 113 [SDNPHasChain, SDNPInGlue]>; 114 115def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain]>; 116 117def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>; 118def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>; 119 120def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR, 121 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 122def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR, 123 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 124def MipsSWL : SDNode<"MipsISD::SWL", SDTStore, 125 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 126def MipsSWR : SDNode<"MipsISD::SWR", SDTStore, 127 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 128def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR, 129 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 130def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR, 131 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 132def MipsSDL : SDNode<"MipsISD::SDL", SDTStore, 133 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 134def MipsSDR : SDNode<"MipsISD::SDR", SDTStore, 135 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 136 137//===----------------------------------------------------------------------===// 138// Mips Instruction Predicate Definitions. 139//===----------------------------------------------------------------------===// 140def HasSEInReg : Predicate<"Subtarget.hasSEInReg()">, 141 AssemblerPredicate<"FeatureSEInReg">; 142def HasBitCount : Predicate<"Subtarget.hasBitCount()">, 143 AssemblerPredicate<"FeatureBitCount">; 144def HasSwap : Predicate<"Subtarget.hasSwap()">, 145 AssemblerPredicate<"FeatureSwap">; 146def HasCondMov : Predicate<"Subtarget.hasCondMov()">, 147 AssemblerPredicate<"FeatureCondMov">; 148def HasMips32 : Predicate<"Subtarget.hasMips32()">, 149 AssemblerPredicate<"FeatureMips32">; 150def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">, 151 AssemblerPredicate<"FeatureMips32r2">; 152def HasMips64 : Predicate<"Subtarget.hasMips64()">, 153 AssemblerPredicate<"FeatureMips64">; 154def HasMips32r2Or64 : Predicate<"Subtarget.hasMips32r2Or64()">, 155 AssemblerPredicate<"FeatureMips32r2,FeatureMips64">; 156def NotMips64 : Predicate<"!Subtarget.hasMips64()">, 157 AssemblerPredicate<"!FeatureMips64">; 158def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">, 159 AssemblerPredicate<"FeatureMips64r2">; 160def IsN64 : Predicate<"Subtarget.isABI_N64()">, 161 AssemblerPredicate<"FeatureN64">; 162def NotN64 : Predicate<"!Subtarget.isABI_N64()">, 163 AssemblerPredicate<"!FeatureN64">; 164def InMips16Mode : Predicate<"Subtarget.inMips16Mode()">, 165 AssemblerPredicate<"FeatureMips16">; 166def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">, 167 AssemblerPredicate<"FeatureMips32">; 168def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">, 169 AssemblerPredicate<"FeatureMips32">; 170def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">, 171 AssemblerPredicate<"FeatureMips32">; 172def HasStandardEncoding : Predicate<"Subtarget.hasStandardEncoding()">, 173 AssemblerPredicate<"!FeatureMips16">; 174 175class MipsPat<dag pattern, dag result> : Pat<pattern, result> { 176 let Predicates = [HasStandardEncoding]; 177} 178 179//===----------------------------------------------------------------------===// 180// Instruction format superclass 181//===----------------------------------------------------------------------===// 182 183include "MipsInstrFormats.td" 184 185//===----------------------------------------------------------------------===// 186// Mips Operand, Complex Patterns and Transformations Definitions. 187//===----------------------------------------------------------------------===// 188 189// Instruction operand types 190def jmptarget : Operand<OtherVT> { 191 let EncoderMethod = "getJumpTargetOpValue"; 192} 193def brtarget : Operand<OtherVT> { 194 let EncoderMethod = "getBranchTargetOpValue"; 195 let OperandType = "OPERAND_PCREL"; 196 let DecoderMethod = "DecodeBranchTarget"; 197} 198def calltarget : Operand<iPTR> { 199 let EncoderMethod = "getJumpTargetOpValue"; 200} 201def calltarget64: Operand<i64>; 202def simm16 : Operand<i32> { 203 let DecoderMethod= "DecodeSimm16"; 204} 205def simm16_64 : Operand<i64>; 206def shamt : Operand<i32>; 207 208// Unsigned Operand 209def uimm16 : Operand<i32> { 210 let PrintMethod = "printUnsignedImm"; 211} 212 213// Address operand 214def mem : Operand<i32> { 215 let PrintMethod = "printMemOperand"; 216 let MIOperandInfo = (ops CPURegs, simm16); 217 let EncoderMethod = "getMemEncoding"; 218} 219 220def mem64 : Operand<i64> { 221 let PrintMethod = "printMemOperand"; 222 let MIOperandInfo = (ops CPU64Regs, simm16_64); 223 let EncoderMethod = "getMemEncoding"; 224} 225 226def mem_ea : Operand<i32> { 227 let PrintMethod = "printMemOperandEA"; 228 let MIOperandInfo = (ops CPURegs, simm16); 229 let EncoderMethod = "getMemEncoding"; 230} 231 232def mem_ea_64 : Operand<i64> { 233 let PrintMethod = "printMemOperandEA"; 234 let MIOperandInfo = (ops CPU64Regs, simm16_64); 235 let EncoderMethod = "getMemEncoding"; 236} 237 238// size operand of ext instruction 239def size_ext : Operand<i32> { 240 let EncoderMethod = "getSizeExtEncoding"; 241 let DecoderMethod = "DecodeExtSize"; 242} 243 244// size operand of ins instruction 245def size_ins : Operand<i32> { 246 let EncoderMethod = "getSizeInsEncoding"; 247 let DecoderMethod = "DecodeInsSize"; 248} 249 250// Transformation Function - get the lower 16 bits. 251def LO16 : SDNodeXForm<imm, [{ 252 return getImm(N, N->getZExtValue() & 0xFFFF); 253}]>; 254 255// Transformation Function - get the higher 16 bits. 256def HI16 : SDNodeXForm<imm, [{ 257 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF); 258}]>; 259 260// Node immediate fits as 16-bit sign extended on target immediate. 261// e.g. addi, andi 262def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>; 263 264// Node immediate fits as 16-bit zero extended on target immediate. 265// The LO16 param means that only the lower 16 bits of the node 266// immediate are caught. 267// e.g. addiu, sltiu 268def immZExt16 : PatLeaf<(imm), [{ 269 if (N->getValueType(0) == MVT::i32) 270 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue(); 271 else 272 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue(); 273}], LO16>; 274 275// Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared). 276def immLow16Zero : PatLeaf<(imm), [{ 277 int64_t Val = N->getSExtValue(); 278 return isInt<32>(Val) && !(Val & 0xffff); 279}]>; 280 281// shamt field must fit in 5 bits. 282def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>; 283 284// Mips Address Mode! SDNode frameindex could possibily be a match 285// since load and store instructions from stack used it. 286def addr : 287 ComplexPattern<iPTR, 2, "SelectAddr", [frameindex], [SDNPWantParent]>; 288 289//===----------------------------------------------------------------------===// 290// Pattern fragment for load/store 291//===----------------------------------------------------------------------===// 292class UnalignedLoad<PatFrag Node> : 293 PatFrag<(ops node:$ptr), (Node node:$ptr), [{ 294 LoadSDNode *LD = cast<LoadSDNode>(N); 295 return LD->getMemoryVT().getSizeInBits()/8 > LD->getAlignment(); 296}]>; 297 298class AlignedLoad<PatFrag Node> : 299 PatFrag<(ops node:$ptr), (Node node:$ptr), [{ 300 LoadSDNode *LD = cast<LoadSDNode>(N); 301 return LD->getMemoryVT().getSizeInBits()/8 <= LD->getAlignment(); 302}]>; 303 304class UnalignedStore<PatFrag Node> : 305 PatFrag<(ops node:$val, node:$ptr), (Node node:$val, node:$ptr), [{ 306 StoreSDNode *SD = cast<StoreSDNode>(N); 307 return SD->getMemoryVT().getSizeInBits()/8 > SD->getAlignment(); 308}]>; 309 310class AlignedStore<PatFrag Node> : 311 PatFrag<(ops node:$val, node:$ptr), (Node node:$val, node:$ptr), [{ 312 StoreSDNode *SD = cast<StoreSDNode>(N); 313 return SD->getMemoryVT().getSizeInBits()/8 <= SD->getAlignment(); 314}]>; 315 316// Load/Store PatFrags. 317def sextloadi16_a : AlignedLoad<sextloadi16>; 318def zextloadi16_a : AlignedLoad<zextloadi16>; 319def extloadi16_a : AlignedLoad<extloadi16>; 320def load_a : AlignedLoad<load>; 321def sextloadi32_a : AlignedLoad<sextloadi32>; 322def zextloadi32_a : AlignedLoad<zextloadi32>; 323def extloadi32_a : AlignedLoad<extloadi32>; 324def truncstorei16_a : AlignedStore<truncstorei16>; 325def store_a : AlignedStore<store>; 326def truncstorei32_a : AlignedStore<truncstorei32>; 327def sextloadi16_u : UnalignedLoad<sextloadi16>; 328def zextloadi16_u : UnalignedLoad<zextloadi16>; 329def extloadi16_u : UnalignedLoad<extloadi16>; 330def load_u : UnalignedLoad<load>; 331def sextloadi32_u : UnalignedLoad<sextloadi32>; 332def zextloadi32_u : UnalignedLoad<zextloadi32>; 333def extloadi32_u : UnalignedLoad<extloadi32>; 334def truncstorei16_u : UnalignedStore<truncstorei16>; 335def store_u : UnalignedStore<store>; 336def truncstorei32_u : UnalignedStore<truncstorei32>; 337 338//===----------------------------------------------------------------------===// 339// Instructions specific format 340//===----------------------------------------------------------------------===// 341 342// Arithmetic and logical instructions with 3 register operands. 343class ArithLogicR<bits<6> op, bits<6> func, string instr_asm, SDNode OpNode, 344 InstrItinClass itin, RegisterClass RC, bit isComm = 0>: 345 FR<op, func, (outs RC:$rd), (ins RC:$rs, RC:$rt), 346 !strconcat(instr_asm, "\t$rd, $rs, $rt"), 347 [(set RC:$rd, (OpNode RC:$rs, RC:$rt))], itin> { 348 let shamt = 0; 349 let isCommutable = isComm; 350 let isReMaterializable = 1; 351} 352 353class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm, 354 InstrItinClass itin, RegisterClass RC, bit isComm = 0>: 355 FR<op, func, (outs RC:$rd), (ins RC:$rs, RC:$rt), 356 !strconcat(instr_asm, "\t$rd, $rs, $rt"), [], itin> { 357 let shamt = 0; 358 let isCommutable = isComm; 359} 360 361// Arithmetic and logical instructions with 2 register operands. 362class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode, 363 Operand Od, PatLeaf imm_type, RegisterClass RC> : 364 FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16), 365 !strconcat(instr_asm, "\t$rt, $rs, $imm16"), 366 [(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu> { 367 let isReMaterializable = 1; 368} 369 370class ArithOverflowI<bits<6> op, string instr_asm, SDNode OpNode, 371 Operand Od, PatLeaf imm_type, RegisterClass RC> : 372 FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16), 373 !strconcat(instr_asm, "\t$rt, $rs, $imm16"), [], IIAlu>; 374 375// Arithmetic Multiply ADD/SUB 376let rd = 0, shamt = 0, Defs = [HI, LO], Uses = [HI, LO] in 377class MArithR<bits<6> func, string instr_asm, SDNode op, bit isComm = 0> : 378 FR<0x1c, func, (outs), (ins CPURegs:$rs, CPURegs:$rt), 379 !strconcat(instr_asm, "\t$rs, $rt"), 380 [(op CPURegs:$rs, CPURegs:$rt, LO, HI)], IIImul> { 381 let rd = 0; 382 let shamt = 0; 383 let isCommutable = isComm; 384} 385 386// Logical 387class LogicNOR<bits<6> op, bits<6> func, string instr_asm, RegisterClass RC>: 388 FR<op, func, (outs RC:$rd), (ins RC:$rs, RC:$rt), 389 !strconcat(instr_asm, "\t$rd, $rs, $rt"), 390 [(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu> { 391 let shamt = 0; 392 let isCommutable = 1; 393} 394 395// Shifts 396class shift_rotate_imm<bits<6> func, bits<5> isRotate, string instr_asm, 397 SDNode OpNode, PatFrag PF, Operand ImmOpnd, 398 RegisterClass RC>: 399 FR<0x00, func, (outs RC:$rd), (ins RC:$rt, ImmOpnd:$shamt), 400 !strconcat(instr_asm, "\t$rd, $rt, $shamt"), 401 [(set RC:$rd, (OpNode RC:$rt, PF:$shamt))], IIAlu> { 402 let rs = isRotate; 403} 404 405// 32-bit shift instructions. 406class shift_rotate_imm32<bits<6> func, bits<5> isRotate, string instr_asm, 407 SDNode OpNode>: 408 shift_rotate_imm<func, isRotate, instr_asm, OpNode, immZExt5, shamt, CPURegs>; 409 410class shift_rotate_reg<bits<6> func, bits<5> isRotate, string instr_asm, 411 SDNode OpNode, RegisterClass RC>: 412 FR<0x00, func, (outs RC:$rd), (ins CPURegs:$rs, RC:$rt), 413 !strconcat(instr_asm, "\t$rd, $rt, $rs"), 414 [(set RC:$rd, (OpNode RC:$rt, CPURegs:$rs))], IIAlu> { 415 let shamt = isRotate; 416} 417 418// Load Upper Imediate 419class LoadUpper<bits<6> op, string instr_asm, RegisterClass RC, Operand Imm>: 420 FI<op, (outs RC:$rt), (ins Imm:$imm16), 421 !strconcat(instr_asm, "\t$rt, $imm16"), [], IIAlu> { 422 let rs = 0; 423 let neverHasSideEffects = 1; 424 let isReMaterializable = 1; 425} 426 427class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, 428 InstrItinClass itin>: FFI<op, outs, ins, asmstr, pattern> { 429 bits<21> addr; 430 let Inst{25-21} = addr{20-16}; 431 let Inst{15-0} = addr{15-0}; 432 let DecoderMethod = "DecodeMem"; 433} 434 435// Memory Load/Store 436let canFoldAsLoad = 1 in 437class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC, 438 Operand MemOpnd, bit Pseudo>: 439 FMem<op, (outs RC:$rt), (ins MemOpnd:$addr), 440 !strconcat(instr_asm, "\t$rt, $addr"), 441 [(set RC:$rt, (OpNode addr:$addr))], IILoad> { 442 let isPseudo = Pseudo; 443} 444 445class StoreM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC, 446 Operand MemOpnd, bit Pseudo>: 447 FMem<op, (outs), (ins RC:$rt, MemOpnd:$addr), 448 !strconcat(instr_asm, "\t$rt, $addr"), 449 [(OpNode RC:$rt, addr:$addr)], IIStore> { 450 let isPseudo = Pseudo; 451} 452 453// 32-bit load. 454multiclass LoadM32<bits<6> op, string instr_asm, PatFrag OpNode, 455 bit Pseudo = 0> { 456 def #NAME# : LoadM<op, instr_asm, OpNode, CPURegs, mem, Pseudo>, 457 Requires<[NotN64, HasStandardEncoding]>; 458 def _P8 : LoadM<op, instr_asm, OpNode, CPURegs, mem64, Pseudo>, 459 Requires<[IsN64, HasStandardEncoding]> { 460 let DecoderNamespace = "Mips64"; 461 let isCodeGenOnly = 1; 462 } 463} 464 465// 64-bit load. 466multiclass LoadM64<bits<6> op, string instr_asm, PatFrag OpNode, 467 bit Pseudo = 0> { 468 def #NAME# : LoadM<op, instr_asm, OpNode, CPU64Regs, mem, Pseudo>, 469 Requires<[NotN64, HasStandardEncoding]>; 470 def _P8 : LoadM<op, instr_asm, OpNode, CPU64Regs, mem64, Pseudo>, 471 Requires<[IsN64, HasStandardEncoding]> { 472 let DecoderNamespace = "Mips64"; 473 let isCodeGenOnly = 1; 474 } 475} 476 477// 32-bit store. 478multiclass StoreM32<bits<6> op, string instr_asm, PatFrag OpNode, 479 bit Pseudo = 0> { 480 def #NAME# : StoreM<op, instr_asm, OpNode, CPURegs, mem, Pseudo>, 481 Requires<[NotN64, HasStandardEncoding]>; 482 def _P8 : StoreM<op, instr_asm, OpNode, CPURegs, mem64, Pseudo>, 483 Requires<[IsN64, HasStandardEncoding]> { 484 let DecoderNamespace = "Mips64"; 485 let isCodeGenOnly = 1; 486 } 487} 488 489// 64-bit store. 490multiclass StoreM64<bits<6> op, string instr_asm, PatFrag OpNode, 491 bit Pseudo = 0> { 492 def #NAME# : StoreM<op, instr_asm, OpNode, CPU64Regs, mem, Pseudo>, 493 Requires<[NotN64, HasStandardEncoding]>; 494 def _P8 : StoreM<op, instr_asm, OpNode, CPU64Regs, mem64, Pseudo>, 495 Requires<[IsN64, HasStandardEncoding]> { 496 let DecoderNamespace = "Mips64"; 497 let isCodeGenOnly = 1; 498 } 499} 500 501// Load/Store Left/Right 502let canFoldAsLoad = 1 in 503class LoadLeftRight<bits<6> op, string instr_asm, SDNode OpNode, 504 RegisterClass RC, Operand MemOpnd> : 505 FMem<op, (outs RC:$rt), (ins MemOpnd:$addr, RC:$src), 506 !strconcat(instr_asm, "\t$rt, $addr"), 507 [(set RC:$rt, (OpNode addr:$addr, RC:$src))], IILoad> { 508 string Constraints = "$src = $rt"; 509} 510 511class StoreLeftRight<bits<6> op, string instr_asm, SDNode OpNode, 512 RegisterClass RC, Operand MemOpnd>: 513 FMem<op, (outs), (ins RC:$rt, MemOpnd:$addr), 514 !strconcat(instr_asm, "\t$rt, $addr"), [(OpNode RC:$rt, addr:$addr)], 515 IIStore>; 516 517// 32-bit load left/right. 518multiclass LoadLeftRightM32<bits<6> op, string instr_asm, SDNode OpNode> { 519 def #NAME# : LoadLeftRight<op, instr_asm, OpNode, CPURegs, mem>, 520 Requires<[NotN64, HasStandardEncoding]>; 521 def _P8 : LoadLeftRight<op, instr_asm, OpNode, CPURegs, mem64>, 522 Requires<[IsN64, HasStandardEncoding]> { 523 let DecoderNamespace = "Mips64"; 524 let isCodeGenOnly = 1; 525 } 526} 527 528// 64-bit load left/right. 529multiclass LoadLeftRightM64<bits<6> op, string instr_asm, SDNode OpNode> { 530 def #NAME# : LoadLeftRight<op, instr_asm, OpNode, CPU64Regs, mem>, 531 Requires<[NotN64, HasStandardEncoding]>; 532 def _P8 : LoadLeftRight<op, instr_asm, OpNode, CPU64Regs, mem64>, 533 Requires<[IsN64, HasStandardEncoding]> { 534 let DecoderNamespace = "Mips64"; 535 let isCodeGenOnly = 1; 536 } 537} 538 539// 32-bit store left/right. 540multiclass StoreLeftRightM32<bits<6> op, string instr_asm, SDNode OpNode> { 541 def #NAME# : StoreLeftRight<op, instr_asm, OpNode, CPURegs, mem>, 542 Requires<[NotN64, HasStandardEncoding]>; 543 def _P8 : StoreLeftRight<op, instr_asm, OpNode, CPURegs, mem64>, 544 Requires<[IsN64, HasStandardEncoding]> { 545 let DecoderNamespace = "Mips64"; 546 let isCodeGenOnly = 1; 547 } 548} 549 550// 64-bit store left/right. 551multiclass StoreLeftRightM64<bits<6> op, string instr_asm, SDNode OpNode> { 552 def #NAME# : StoreLeftRight<op, instr_asm, OpNode, CPU64Regs, mem>, 553 Requires<[NotN64, HasStandardEncoding]>; 554 def _P8 : StoreLeftRight<op, instr_asm, OpNode, CPU64Regs, mem64>, 555 Requires<[IsN64, HasStandardEncoding]> { 556 let DecoderNamespace = "Mips64"; 557 let isCodeGenOnly = 1; 558 } 559} 560 561// Conditional Branch 562class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>: 563 BranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$imm16), 564 !strconcat(instr_asm, "\t$rs, $rt, $imm16"), 565 [(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$imm16)], IIBranch> { 566 let isBranch = 1; 567 let isTerminator = 1; 568 let hasDelaySlot = 1; 569 let Defs = [AT]; 570} 571 572class CBranchZero<bits<6> op, bits<5> _rt, string instr_asm, PatFrag cond_op, 573 RegisterClass RC>: 574 BranchBase<op, (outs), (ins RC:$rs, brtarget:$imm16), 575 !strconcat(instr_asm, "\t$rs, $imm16"), 576 [(brcond (i32 (cond_op RC:$rs, 0)), bb:$imm16)], IIBranch> { 577 let rt = _rt; 578 let isBranch = 1; 579 let isTerminator = 1; 580 let hasDelaySlot = 1; 581 let Defs = [AT]; 582} 583 584// SetCC 585class SetCC_R<bits<6> op, bits<6> func, string instr_asm, PatFrag cond_op, 586 RegisterClass RC>: 587 FR<op, func, (outs CPURegs:$rd), (ins RC:$rs, RC:$rt), 588 !strconcat(instr_asm, "\t$rd, $rs, $rt"), 589 [(set CPURegs:$rd, (cond_op RC:$rs, RC:$rt))], 590 IIAlu> { 591 let shamt = 0; 592} 593 594class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, Operand Od, 595 PatLeaf imm_type, RegisterClass RC>: 596 FI<op, (outs CPURegs:$rt), (ins RC:$rs, Od:$imm16), 597 !strconcat(instr_asm, "\t$rt, $rs, $imm16"), 598 [(set CPURegs:$rt, (cond_op RC:$rs, imm_type:$imm16))], 599 IIAlu>; 600 601// Jump 602class JumpFJ<bits<6> op, string instr_asm>: 603 FJ<op, (outs), (ins jmptarget:$target), 604 !strconcat(instr_asm, "\t$target"), [(br bb:$target)], IIBranch> { 605 let isBranch=1; 606 let isTerminator=1; 607 let isBarrier=1; 608 let hasDelaySlot = 1; 609 let Predicates = [RelocStatic, HasStandardEncoding]; 610 let DecoderMethod = "DecodeJumpTarget"; 611 let Defs = [AT]; 612} 613 614// Unconditional branch 615class UncondBranch<bits<6> op, string instr_asm>: 616 BranchBase<op, (outs), (ins brtarget:$imm16), 617 !strconcat(instr_asm, "\t$imm16"), [(br bb:$imm16)], IIBranch> { 618 let rs = 0; 619 let rt = 0; 620 let isBranch = 1; 621 let isTerminator = 1; 622 let isBarrier = 1; 623 let hasDelaySlot = 1; 624 let Predicates = [RelocPIC, HasStandardEncoding]; 625 let Defs = [AT]; 626} 627 628let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1, 629 isIndirectBranch = 1 in 630class JumpFR<bits<6> op, bits<6> func, string instr_asm, RegisterClass RC>: 631 FR<op, func, (outs), (ins RC:$rs), 632 !strconcat(instr_asm, "\t$rs"), [(brind RC:$rs)], IIBranch> { 633 let rt = 0; 634 let rd = 0; 635 let shamt = 0; 636} 637 638// Jump and Link (Call) 639let isCall=1, hasDelaySlot=1 in { 640 class JumpLink<bits<6> op, string instr_asm>: 641 FJ<op, (outs), (ins calltarget:$target, variable_ops), 642 !strconcat(instr_asm, "\t$target"), [(MipsJmpLink imm:$target)], 643 IIBranch> { 644 let DecoderMethod = "DecodeJumpTarget"; 645 } 646 647 class JumpLinkReg<bits<6> op, bits<6> func, string instr_asm, 648 RegisterClass RC>: 649 FR<op, func, (outs), (ins RC:$rs, variable_ops), 650 !strconcat(instr_asm, "\t$rs"), [(MipsJmpLink RC:$rs)], IIBranch> { 651 let rt = 0; 652 let rd = 31; 653 let shamt = 0; 654 } 655 656 class BranchLink<string instr_asm, bits<5> _rt, RegisterClass RC>: 657 FI<0x1, (outs), (ins RC:$rs, brtarget:$imm16, variable_ops), 658 !strconcat(instr_asm, "\t$rs, $imm16"), [], IIBranch> { 659 let rt = _rt; 660 } 661} 662 663// Mul, Div 664class Mult<bits<6> func, string instr_asm, InstrItinClass itin, 665 RegisterClass RC, list<Register> DefRegs>: 666 FR<0x00, func, (outs), (ins RC:$rs, RC:$rt), 667 !strconcat(instr_asm, "\t$rs, $rt"), [], itin> { 668 let rd = 0; 669 let shamt = 0; 670 let isCommutable = 1; 671 let Defs = DefRegs; 672 let neverHasSideEffects = 1; 673} 674 675class Mult32<bits<6> func, string instr_asm, InstrItinClass itin>: 676 Mult<func, instr_asm, itin, CPURegs, [HI, LO]>; 677 678class Div<SDNode op, bits<6> func, string instr_asm, InstrItinClass itin, 679 RegisterClass RC, list<Register> DefRegs>: 680 FR<0x00, func, (outs), (ins RC:$rs, RC:$rt), 681 !strconcat(instr_asm, "\t$$zero, $rs, $rt"), 682 [(op RC:$rs, RC:$rt)], itin> { 683 let rd = 0; 684 let shamt = 0; 685 let Defs = DefRegs; 686} 687 688class Div32<SDNode op, bits<6> func, string instr_asm, InstrItinClass itin>: 689 Div<op, func, instr_asm, itin, CPURegs, [HI, LO]>; 690 691// Move from Hi/Lo 692class MoveFromLOHI<bits<6> func, string instr_asm, RegisterClass RC, 693 list<Register> UseRegs>: 694 FR<0x00, func, (outs RC:$rd), (ins), 695 !strconcat(instr_asm, "\t$rd"), [], IIHiLo> { 696 let rs = 0; 697 let rt = 0; 698 let shamt = 0; 699 let Uses = UseRegs; 700 let neverHasSideEffects = 1; 701} 702 703class MoveToLOHI<bits<6> func, string instr_asm, RegisterClass RC, 704 list<Register> DefRegs>: 705 FR<0x00, func, (outs), (ins RC:$rs), 706 !strconcat(instr_asm, "\t$rs"), [], IIHiLo> { 707 let rt = 0; 708 let rd = 0; 709 let shamt = 0; 710 let Defs = DefRegs; 711 let neverHasSideEffects = 1; 712} 713 714class EffectiveAddress<string instr_asm, RegisterClass RC, Operand Mem> : 715 FMem<0x09, (outs RC:$rt), (ins Mem:$addr), 716 instr_asm, [(set RC:$rt, addr:$addr)], IIAlu>; 717 718// Count Leading Ones/Zeros in Word 719class CountLeading0<bits<6> func, string instr_asm, RegisterClass RC>: 720 FR<0x1c, func, (outs RC:$rd), (ins RC:$rs), 721 !strconcat(instr_asm, "\t$rd, $rs"), 722 [(set RC:$rd, (ctlz RC:$rs))], IIAlu>, 723 Requires<[HasBitCount, HasStandardEncoding]> { 724 let shamt = 0; 725 let rt = rd; 726} 727 728class CountLeading1<bits<6> func, string instr_asm, RegisterClass RC>: 729 FR<0x1c, func, (outs RC:$rd), (ins RC:$rs), 730 !strconcat(instr_asm, "\t$rd, $rs"), 731 [(set RC:$rd, (ctlz (not RC:$rs)))], IIAlu>, 732 Requires<[HasBitCount, HasStandardEncoding]> { 733 let shamt = 0; 734 let rt = rd; 735} 736 737// Sign Extend in Register. 738class SignExtInReg<bits<5> sa, string instr_asm, ValueType vt, 739 RegisterClass RC>: 740 FR<0x1f, 0x20, (outs RC:$rd), (ins RC:$rt), 741 !strconcat(instr_asm, "\t$rd, $rt"), 742 [(set RC:$rd, (sext_inreg RC:$rt, vt))], NoItinerary> { 743 let rs = 0; 744 let shamt = sa; 745 let Predicates = [HasSEInReg, HasStandardEncoding]; 746} 747 748// Subword Swap 749class SubwordSwap<bits<6> func, bits<5> sa, string instr_asm, RegisterClass RC>: 750 FR<0x1f, func, (outs RC:$rd), (ins RC:$rt), 751 !strconcat(instr_asm, "\t$rd, $rt"), [], NoItinerary> { 752 let rs = 0; 753 let shamt = sa; 754 let Predicates = [HasSwap, HasStandardEncoding]; 755 let neverHasSideEffects = 1; 756} 757 758// Read Hardware 759class ReadHardware<RegisterClass CPURegClass, RegisterClass HWRegClass> 760 : FR<0x1f, 0x3b, (outs CPURegClass:$rt), (ins HWRegClass:$rd), 761 "rdhwr\t$rt, $rd", [], IIAlu> { 762 let rs = 0; 763 let shamt = 0; 764} 765 766// Ext and Ins 767class ExtBase<bits<6> _funct, string instr_asm, RegisterClass RC>: 768 FR<0x1f, _funct, (outs RC:$rt), (ins RC:$rs, uimm16:$pos, size_ext:$sz), 769 !strconcat(instr_asm, " $rt, $rs, $pos, $sz"), 770 [(set RC:$rt, (MipsExt RC:$rs, imm:$pos, imm:$sz))], NoItinerary> { 771 bits<5> pos; 772 bits<5> sz; 773 let rd = sz; 774 let shamt = pos; 775 let Predicates = [HasMips32r2, HasStandardEncoding]; 776} 777 778class InsBase<bits<6> _funct, string instr_asm, RegisterClass RC>: 779 FR<0x1f, _funct, (outs RC:$rt), 780 (ins RC:$rs, uimm16:$pos, size_ins:$sz, RC:$src), 781 !strconcat(instr_asm, " $rt, $rs, $pos, $sz"), 782 [(set RC:$rt, (MipsIns RC:$rs, imm:$pos, imm:$sz, RC:$src))], 783 NoItinerary> { 784 bits<5> pos; 785 bits<5> sz; 786 let rd = sz; 787 let shamt = pos; 788 let Predicates = [HasMips32r2, HasStandardEncoding]; 789 let Constraints = "$src = $rt"; 790} 791 792// Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*). 793class Atomic2Ops<PatFrag Op, string Opstr, RegisterClass DRC, 794 RegisterClass PRC> : 795 MipsPseudo<(outs DRC:$dst), (ins PRC:$ptr, DRC:$incr), 796 !strconcat("atomic_", Opstr, "\t$dst, $ptr, $incr"), 797 [(set DRC:$dst, (Op PRC:$ptr, DRC:$incr))]>; 798 799multiclass Atomic2Ops32<PatFrag Op, string Opstr> { 800 def #NAME# : Atomic2Ops<Op, Opstr, CPURegs, CPURegs>, 801 Requires<[NotN64, HasStandardEncoding]>; 802 def _P8 : Atomic2Ops<Op, Opstr, CPURegs, CPU64Regs>, 803 Requires<[IsN64, HasStandardEncoding]> { 804 let DecoderNamespace = "Mips64"; 805 } 806} 807 808// Atomic Compare & Swap. 809class AtomicCmpSwap<PatFrag Op, string Width, RegisterClass DRC, 810 RegisterClass PRC> : 811 MipsPseudo<(outs DRC:$dst), (ins PRC:$ptr, DRC:$cmp, DRC:$swap), 812 !strconcat("atomic_cmp_swap_", Width, "\t$dst, $ptr, $cmp, $swap"), 813 [(set DRC:$dst, (Op PRC:$ptr, DRC:$cmp, DRC:$swap))]>; 814 815multiclass AtomicCmpSwap32<PatFrag Op, string Width> { 816 def #NAME# : AtomicCmpSwap<Op, Width, CPURegs, CPURegs>, 817 Requires<[NotN64, HasStandardEncoding]>; 818 def _P8 : AtomicCmpSwap<Op, Width, CPURegs, CPU64Regs>, 819 Requires<[IsN64, HasStandardEncoding]> { 820 let DecoderNamespace = "Mips64"; 821 } 822} 823 824class LLBase<bits<6> Opc, string opstring, RegisterClass RC, Operand Mem> : 825 FMem<Opc, (outs RC:$rt), (ins Mem:$addr), 826 !strconcat(opstring, "\t$rt, $addr"), [], IILoad> { 827 let mayLoad = 1; 828} 829 830class SCBase<bits<6> Opc, string opstring, RegisterClass RC, Operand Mem> : 831 FMem<Opc, (outs RC:$dst), (ins RC:$rt, Mem:$addr), 832 !strconcat(opstring, "\t$rt, $addr"), [], IIStore> { 833 let mayStore = 1; 834 let Constraints = "$rt = $dst"; 835} 836 837//===----------------------------------------------------------------------===// 838// Pseudo instructions 839//===----------------------------------------------------------------------===// 840 841// As stack alignment is always done with addiu, we need a 16-bit immediate 842let Defs = [SP], Uses = [SP] in { 843def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins uimm16:$amt), 844 "!ADJCALLSTACKDOWN $amt", 845 [(callseq_start timm:$amt)]>; 846def ADJCALLSTACKUP : MipsPseudo<(outs), (ins uimm16:$amt1, uimm16:$amt2), 847 "!ADJCALLSTACKUP $amt1", 848 [(callseq_end timm:$amt1, timm:$amt2)]>; 849} 850 851// When handling PIC code the assembler needs .cpload and .cprestore 852// directives. If the real instructions corresponding these directives 853// are used, we have the same behavior, but get also a bunch of warnings 854// from the assembler. 855let neverHasSideEffects = 1 in 856def CPRESTORE : MipsPseudo<(outs), (ins i32imm:$loc, CPURegs:$gp), 857 ".cprestore\t$loc", []>; 858 859let usesCustomInserter = 1 in { 860 defm ATOMIC_LOAD_ADD_I8 : Atomic2Ops32<atomic_load_add_8, "load_add_8">; 861 defm ATOMIC_LOAD_ADD_I16 : Atomic2Ops32<atomic_load_add_16, "load_add_16">; 862 defm ATOMIC_LOAD_ADD_I32 : Atomic2Ops32<atomic_load_add_32, "load_add_32">; 863 defm ATOMIC_LOAD_SUB_I8 : Atomic2Ops32<atomic_load_sub_8, "load_sub_8">; 864 defm ATOMIC_LOAD_SUB_I16 : Atomic2Ops32<atomic_load_sub_16, "load_sub_16">; 865 defm ATOMIC_LOAD_SUB_I32 : Atomic2Ops32<atomic_load_sub_32, "load_sub_32">; 866 defm ATOMIC_LOAD_AND_I8 : Atomic2Ops32<atomic_load_and_8, "load_and_8">; 867 defm ATOMIC_LOAD_AND_I16 : Atomic2Ops32<atomic_load_and_16, "load_and_16">; 868 defm ATOMIC_LOAD_AND_I32 : Atomic2Ops32<atomic_load_and_32, "load_and_32">; 869 defm ATOMIC_LOAD_OR_I8 : Atomic2Ops32<atomic_load_or_8, "load_or_8">; 870 defm ATOMIC_LOAD_OR_I16 : Atomic2Ops32<atomic_load_or_16, "load_or_16">; 871 defm ATOMIC_LOAD_OR_I32 : Atomic2Ops32<atomic_load_or_32, "load_or_32">; 872 defm ATOMIC_LOAD_XOR_I8 : Atomic2Ops32<atomic_load_xor_8, "load_xor_8">; 873 defm ATOMIC_LOAD_XOR_I16 : Atomic2Ops32<atomic_load_xor_16, "load_xor_16">; 874 defm ATOMIC_LOAD_XOR_I32 : Atomic2Ops32<atomic_load_xor_32, "load_xor_32">; 875 defm ATOMIC_LOAD_NAND_I8 : Atomic2Ops32<atomic_load_nand_8, "load_nand_8">; 876 defm ATOMIC_LOAD_NAND_I16 : Atomic2Ops32<atomic_load_nand_16, "load_nand_16">; 877 defm ATOMIC_LOAD_NAND_I32 : Atomic2Ops32<atomic_load_nand_32, "load_nand_32">; 878 879 defm ATOMIC_SWAP_I8 : Atomic2Ops32<atomic_swap_8, "swap_8">; 880 defm ATOMIC_SWAP_I16 : Atomic2Ops32<atomic_swap_16, "swap_16">; 881 defm ATOMIC_SWAP_I32 : Atomic2Ops32<atomic_swap_32, "swap_32">; 882 883 defm ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap32<atomic_cmp_swap_8, "8">; 884 defm ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap32<atomic_cmp_swap_16, "16">; 885 defm ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap32<atomic_cmp_swap_32, "32">; 886} 887 888//===----------------------------------------------------------------------===// 889// Instruction definition 890//===----------------------------------------------------------------------===// 891 892//===----------------------------------------------------------------------===// 893// MipsI Instructions 894//===----------------------------------------------------------------------===// 895 896/// Arithmetic Instructions (ALU Immediate) 897def ADDiu : ArithLogicI<0x09, "addiu", add, simm16, immSExt16, CPURegs>; 898def ADDi : ArithOverflowI<0x08, "addi", add, simm16, immSExt16, CPURegs>; 899def SLTi : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16, CPURegs>; 900def SLTiu : SetCC_I<0x0b, "sltiu", setult, simm16, immSExt16, CPURegs>; 901def ANDi : ArithLogicI<0x0c, "andi", and, uimm16, immZExt16, CPURegs>; 902def ORi : ArithLogicI<0x0d, "ori", or, uimm16, immZExt16, CPURegs>; 903def XORi : ArithLogicI<0x0e, "xori", xor, uimm16, immZExt16, CPURegs>; 904def LUi : LoadUpper<0x0f, "lui", CPURegs, uimm16>; 905 906/// Arithmetic Instructions (3-Operand, R-Type) 907def ADDu : ArithLogicR<0x00, 0x21, "addu", add, IIAlu, CPURegs, 1>; 908def SUBu : ArithLogicR<0x00, 0x23, "subu", sub, IIAlu, CPURegs>; 909def ADD : ArithOverflowR<0x00, 0x20, "add", IIAlu, CPURegs, 1>; 910def SUB : ArithOverflowR<0x00, 0x22, "sub", IIAlu, CPURegs>; 911def SLT : SetCC_R<0x00, 0x2a, "slt", setlt, CPURegs>; 912def SLTu : SetCC_R<0x00, 0x2b, "sltu", setult, CPURegs>; 913def AND : ArithLogicR<0x00, 0x24, "and", and, IIAlu, CPURegs, 1>; 914def OR : ArithLogicR<0x00, 0x25, "or", or, IIAlu, CPURegs, 1>; 915def XOR : ArithLogicR<0x00, 0x26, "xor", xor, IIAlu, CPURegs, 1>; 916def NOR : LogicNOR<0x00, 0x27, "nor", CPURegs>; 917 918/// Shift Instructions 919def SLL : shift_rotate_imm32<0x00, 0x00, "sll", shl>; 920def SRL : shift_rotate_imm32<0x02, 0x00, "srl", srl>; 921def SRA : shift_rotate_imm32<0x03, 0x00, "sra", sra>; 922def SLLV : shift_rotate_reg<0x04, 0x00, "sllv", shl, CPURegs>; 923def SRLV : shift_rotate_reg<0x06, 0x00, "srlv", srl, CPURegs>; 924def SRAV : shift_rotate_reg<0x07, 0x00, "srav", sra, CPURegs>; 925 926// Rotate Instructions 927let Predicates = [HasMips32r2, HasStandardEncoding] in { 928 def ROTR : shift_rotate_imm32<0x02, 0x01, "rotr", rotr>; 929 def ROTRV : shift_rotate_reg<0x06, 0x01, "rotrv", rotr, CPURegs>; 930} 931 932/// Load and Store Instructions 933/// aligned 934defm LB : LoadM32<0x20, "lb", sextloadi8>; 935defm LBu : LoadM32<0x24, "lbu", zextloadi8>; 936defm LH : LoadM32<0x21, "lh", sextloadi16_a>; 937defm LHu : LoadM32<0x25, "lhu", zextloadi16_a>; 938defm LW : LoadM32<0x23, "lw", load_a>; 939defm SB : StoreM32<0x28, "sb", truncstorei8>; 940defm SH : StoreM32<0x29, "sh", truncstorei16_a>; 941defm SW : StoreM32<0x2b, "sw", store_a>; 942 943/// unaligned 944defm ULH : LoadM32<0x21, "ulh", sextloadi16_u, 1>; 945defm ULHu : LoadM32<0x25, "ulhu", zextloadi16_u, 1>; 946defm ULW : LoadM32<0x23, "ulw", load_u, 1>; 947defm USH : StoreM32<0x29, "ush", truncstorei16_u, 1>; 948defm USW : StoreM32<0x2b, "usw", store_u, 1>; 949 950/// load/store left/right 951defm LWL : LoadLeftRightM32<0x22, "lwl", MipsLWL>; 952defm LWR : LoadLeftRightM32<0x26, "lwr", MipsLWR>; 953defm SWL : StoreLeftRightM32<0x2a, "swl", MipsSWL>; 954defm SWR : StoreLeftRightM32<0x2e, "swr", MipsSWR>; 955 956let hasSideEffects = 1 in 957def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype", 958 [(MipsSync imm:$stype)], NoItinerary, FrmOther> 959{ 960 bits<5> stype; 961 let Opcode = 0; 962 let Inst{25-11} = 0; 963 let Inst{10-6} = stype; 964 let Inst{5-0} = 15; 965} 966 967/// Load-linked, Store-conditional 968def LL : LLBase<0x30, "ll", CPURegs, mem>, 969 Requires<[NotN64, HasStandardEncoding]>; 970def LL_P8 : LLBase<0x30, "ll", CPURegs, mem64>, 971 Requires<[IsN64, HasStandardEncoding]> { 972 let DecoderNamespace = "Mips64"; 973} 974 975def SC : SCBase<0x38, "sc", CPURegs, mem>, 976 Requires<[NotN64, HasStandardEncoding]>; 977def SC_P8 : SCBase<0x38, "sc", CPURegs, mem64>, 978 Requires<[IsN64, HasStandardEncoding]> { 979 let DecoderNamespace = "Mips64"; 980} 981 982/// Jump and Branch Instructions 983def J : JumpFJ<0x02, "j">; 984def JR : JumpFR<0x00, 0x08, "jr", CPURegs>; 985def B : UncondBranch<0x04, "b">; 986def BEQ : CBranch<0x04, "beq", seteq, CPURegs>; 987def BNE : CBranch<0x05, "bne", setne, CPURegs>; 988def BGEZ : CBranchZero<0x01, 1, "bgez", setge, CPURegs>; 989def BGTZ : CBranchZero<0x07, 0, "bgtz", setgt, CPURegs>; 990def BLEZ : CBranchZero<0x06, 0, "blez", setle, CPURegs>; 991def BLTZ : CBranchZero<0x01, 0, "bltz", setlt, CPURegs>; 992 993def JAL : JumpLink<0x03, "jal">; 994def JALR : JumpLinkReg<0x00, 0x09, "jalr", CPURegs>; 995def BGEZAL : BranchLink<"bgezal", 0x11, CPURegs>; 996def BLTZAL : BranchLink<"bltzal", 0x10, CPURegs>; 997 998let isReturn=1, isTerminator=1, hasDelaySlot=1, isCodeGenOnly=1, 999 isBarrier=1, hasCtrlDep=1, rd=0, rt=0, shamt=0 in 1000 def RET : FR <0x00, 0x08, (outs), (ins CPURegs:$target), 1001 "jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>; 1002 1003/// Multiply and Divide Instructions. 1004def MULT : Mult32<0x18, "mult", IIImul>; 1005def MULTu : Mult32<0x19, "multu", IIImul>; 1006def SDIV : Div32<MipsDivRem, 0x1a, "div", IIIdiv>; 1007def UDIV : Div32<MipsDivRemU, 0x1b, "divu", IIIdiv>; 1008 1009def MTHI : MoveToLOHI<0x11, "mthi", CPURegs, [HI]>; 1010def MTLO : MoveToLOHI<0x13, "mtlo", CPURegs, [LO]>; 1011def MFHI : MoveFromLOHI<0x10, "mfhi", CPURegs, [HI]>; 1012def MFLO : MoveFromLOHI<0x12, "mflo", CPURegs, [LO]>; 1013 1014/// Sign Ext In Register Instructions. 1015def SEB : SignExtInReg<0x10, "seb", i8, CPURegs>; 1016def SEH : SignExtInReg<0x18, "seh", i16, CPURegs>; 1017 1018/// Count Leading 1019def CLZ : CountLeading0<0x20, "clz", CPURegs>; 1020def CLO : CountLeading1<0x21, "clo", CPURegs>; 1021 1022/// Word Swap Bytes Within Halfwords 1023def WSBH : SubwordSwap<0x20, 0x2, "wsbh", CPURegs>; 1024 1025/// No operation 1026let addr=0 in 1027 def NOP : FJ<0, (outs), (ins), "nop", [], IIAlu>; 1028 1029// FrameIndexes are legalized when they are operands from load/store 1030// instructions. The same not happens for stack address copies, so an 1031// add op with mem ComplexPattern is used and the stack address copy 1032// can be matched. It's similar to Sparc LEA_ADDRi 1033def LEA_ADDiu : EffectiveAddress<"addiu\t$rt, $addr", CPURegs, mem_ea> { 1034 let isCodeGenOnly = 1; 1035} 1036 1037// DynAlloc node points to dynamically allocated stack space. 1038// $sp is added to the list of implicitly used registers to prevent dead code 1039// elimination from removing instructions that modify $sp. 1040let Uses = [SP] in 1041def DynAlloc : EffectiveAddress<"addiu\t$rt, $addr", CPURegs, mem_ea> { 1042 let isCodeGenOnly = 1; 1043} 1044 1045// MADD*/MSUB* 1046def MADD : MArithR<0, "madd", MipsMAdd, 1>; 1047def MADDU : MArithR<1, "maddu", MipsMAddu, 1>; 1048def MSUB : MArithR<4, "msub", MipsMSub>; 1049def MSUBU : MArithR<5, "msubu", MipsMSubu>; 1050 1051// MUL is a assembly macro in the current used ISAs. In recent ISA's 1052// it is a real instruction. 1053def MUL : ArithLogicR<0x1c, 0x02, "mul", mul, IIImul, CPURegs, 1>, 1054 Requires<[HasMips32, HasStandardEncoding]>; 1055 1056def RDHWR : ReadHardware<CPURegs, HWRegs>; 1057 1058def EXT : ExtBase<0, "ext", CPURegs>; 1059def INS : InsBase<4, "ins", CPURegs>; 1060 1061//===----------------------------------------------------------------------===// 1062// Arbitrary patterns that map to one or more instructions 1063//===----------------------------------------------------------------------===// 1064 1065// Small immediates 1066def : MipsPat<(i32 immSExt16:$in), 1067 (ADDiu ZERO, imm:$in)>; 1068def : MipsPat<(i32 immZExt16:$in), 1069 (ORi ZERO, imm:$in)>; 1070def : MipsPat<(i32 immLow16Zero:$in), 1071 (LUi (HI16 imm:$in))>; 1072 1073// Arbitrary immediates 1074def : MipsPat<(i32 imm:$imm), 1075 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>; 1076 1077// Carry MipsPatterns 1078def : MipsPat<(subc CPURegs:$lhs, CPURegs:$rhs), 1079 (SUBu CPURegs:$lhs, CPURegs:$rhs)>; 1080def : MipsPat<(addc CPURegs:$lhs, CPURegs:$rhs), 1081 (ADDu CPURegs:$lhs, CPURegs:$rhs)>; 1082def : MipsPat<(addc CPURegs:$src, immSExt16:$imm), 1083 (ADDiu CPURegs:$src, imm:$imm)>; 1084 1085// Call 1086def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)), 1087 (JAL tglobaladdr:$dst)>; 1088def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)), 1089 (JAL texternalsym:$dst)>; 1090//def : MipsPat<(MipsJmpLink CPURegs:$dst), 1091// (JALR CPURegs:$dst)>; 1092 1093// hi/lo relocs 1094def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>; 1095def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>; 1096def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>; 1097def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>; 1098def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>; 1099 1100def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>; 1101def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>; 1102def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>; 1103def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>; 1104def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>; 1105 1106def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)), 1107 (ADDiu CPURegs:$hi, tglobaladdr:$lo)>; 1108def : MipsPat<(add CPURegs:$hi, (MipsLo tblockaddress:$lo)), 1109 (ADDiu CPURegs:$hi, tblockaddress:$lo)>; 1110def : MipsPat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)), 1111 (ADDiu CPURegs:$hi, tjumptable:$lo)>; 1112def : MipsPat<(add CPURegs:$hi, (MipsLo tconstpool:$lo)), 1113 (ADDiu CPURegs:$hi, tconstpool:$lo)>; 1114def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaltlsaddr:$lo)), 1115 (ADDiu CPURegs:$hi, tglobaltlsaddr:$lo)>; 1116 1117// gp_rel relocs 1118def : MipsPat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)), 1119 (ADDiu CPURegs:$gp, tglobaladdr:$in)>; 1120def : MipsPat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)), 1121 (ADDiu CPURegs:$gp, tconstpool:$in)>; 1122 1123// wrapper_pic 1124class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>: 1125 MipsPat<(MipsWrapper RC:$gp, node:$in), 1126 (ADDiuOp RC:$gp, node:$in)>; 1127 1128def : WrapperPat<tglobaladdr, ADDiu, CPURegs>; 1129def : WrapperPat<tconstpool, ADDiu, CPURegs>; 1130def : WrapperPat<texternalsym, ADDiu, CPURegs>; 1131def : WrapperPat<tblockaddress, ADDiu, CPURegs>; 1132def : WrapperPat<tjumptable, ADDiu, CPURegs>; 1133def : WrapperPat<tglobaltlsaddr, ADDiu, CPURegs>; 1134 1135// Mips does not have "not", so we expand our way 1136def : MipsPat<(not CPURegs:$in), 1137 (NOR CPURegs:$in, ZERO)>; 1138 1139// extended loads 1140let Predicates = [NotN64, HasStandardEncoding] in { 1141 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>; 1142 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>; 1143 def : MipsPat<(i32 (extloadi16_a addr:$src)), (LHu addr:$src)>; 1144 def : MipsPat<(i32 (extloadi16_u addr:$src)), (ULHu addr:$src)>; 1145} 1146let Predicates = [IsN64, HasStandardEncoding] in { 1147 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu_P8 addr:$src)>; 1148 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu_P8 addr:$src)>; 1149 def : MipsPat<(i32 (extloadi16_a addr:$src)), (LHu_P8 addr:$src)>; 1150 def : MipsPat<(i32 (extloadi16_u addr:$src)), (ULHu_P8 addr:$src)>; 1151} 1152 1153// peepholes 1154let Predicates = [NotN64, HasStandardEncoding] in { 1155 def : MipsPat<(store_a (i32 0), addr:$dst), (SW ZERO, addr:$dst)>; 1156 def : MipsPat<(store_u (i32 0), addr:$dst), (USW ZERO, addr:$dst)>; 1157} 1158let Predicates = [IsN64, HasStandardEncoding] in { 1159 def : MipsPat<(store_a (i32 0), addr:$dst), (SW_P8 ZERO, addr:$dst)>; 1160 def : MipsPat<(store_u (i32 0), addr:$dst), (USW_P8 ZERO, addr:$dst)>; 1161} 1162 1163// brcond patterns 1164multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp, 1165 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp, 1166 Instruction SLTiuOp, Register ZEROReg> { 1167def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst), 1168 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>; 1169def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst), 1170 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>; 1171 1172def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst), 1173 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>; 1174def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst), 1175 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>; 1176def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst), 1177 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; 1178def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst), 1179 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; 1180 1181def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst), 1182 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; 1183def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst), 1184 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; 1185 1186def : MipsPat<(brcond RC:$cond, bb:$dst), 1187 (BNEOp RC:$cond, ZEROReg, bb:$dst)>; 1188} 1189 1190defm : BrcondPats<CPURegs, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>; 1191 1192// setcc patterns 1193multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp, 1194 Instruction SLTuOp, Register ZEROReg> { 1195 def : MipsPat<(seteq RC:$lhs, RC:$rhs), 1196 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>; 1197 def : MipsPat<(setne RC:$lhs, RC:$rhs), 1198 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>; 1199} 1200 1201multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> { 1202 def : MipsPat<(setle RC:$lhs, RC:$rhs), 1203 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>; 1204 def : MipsPat<(setule RC:$lhs, RC:$rhs), 1205 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>; 1206} 1207 1208multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> { 1209 def : MipsPat<(setgt RC:$lhs, RC:$rhs), 1210 (SLTOp RC:$rhs, RC:$lhs)>; 1211 def : MipsPat<(setugt RC:$lhs, RC:$rhs), 1212 (SLTuOp RC:$rhs, RC:$lhs)>; 1213} 1214 1215multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> { 1216 def : MipsPat<(setge RC:$lhs, RC:$rhs), 1217 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>; 1218 def : MipsPat<(setuge RC:$lhs, RC:$rhs), 1219 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>; 1220} 1221 1222multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp, 1223 Instruction SLTiuOp> { 1224 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs), 1225 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>; 1226 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs), 1227 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>; 1228} 1229 1230defm : SeteqPats<CPURegs, SLTiu, XOR, SLTu, ZERO>; 1231defm : SetlePats<CPURegs, SLT, SLTu>; 1232defm : SetgtPats<CPURegs, SLT, SLTu>; 1233defm : SetgePats<CPURegs, SLT, SLTu>; 1234defm : SetgeImmPats<CPURegs, SLTi, SLTiu>; 1235 1236// select MipsDynAlloc 1237def : MipsPat<(MipsDynAlloc addr:$f), (DynAlloc addr:$f)>; 1238 1239// bswap pattern 1240def : MipsPat<(bswap CPURegs:$rt), (ROTR (WSBH CPURegs:$rt), 16)>; 1241 1242//===----------------------------------------------------------------------===// 1243// Floating Point Support 1244//===----------------------------------------------------------------------===// 1245 1246include "MipsInstrFPU.td" 1247include "Mips64InstrInfo.td" 1248include "MipsCondMov.td" 1249 1250// 1251// Mips16 1252 1253include "Mips16InstrFormats.td" 1254include "Mips16InstrInfo.td" 1255