1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 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 #include "MCTargetDesc/MipsMCExpr.h" 11 #include "MCTargetDesc/MipsMCTargetDesc.h" 12 #include "MipsRegisterInfo.h" 13 #include "MipsTargetStreamer.h" 14 #include "llvm/ADT/APInt.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCInstBuilder.h" 20 #include "llvm/MC/MCParser/MCAsmLexer.h" 21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 22 #include "llvm/MC/MCStreamer.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/MC/MCSymbol.h" 25 #include "llvm/MC/MCTargetAsmParser.h" 26 #include "llvm/Support/Debug.h" 27 #include "llvm/Support/MathExtras.h" 28 #include "llvm/Support/TargetRegistry.h" 29 30 using namespace llvm; 31 32 #define DEBUG_TYPE "mips-asm-parser" 33 34 namespace llvm { 35 class MCInstrInfo; 36 } 37 38 namespace { 39 class MipsAssemblerOptions { 40 public: 41 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {} 42 43 unsigned getATRegNum() { return aTReg; } 44 bool setATReg(unsigned Reg); 45 46 bool isReorder() { return reorder; } 47 void setReorder() { reorder = true; } 48 void setNoreorder() { reorder = false; } 49 50 bool isMacro() { return macro; } 51 void setMacro() { macro = true; } 52 void setNomacro() { macro = false; } 53 54 private: 55 unsigned aTReg; 56 bool reorder; 57 bool macro; 58 }; 59 } 60 61 namespace { 62 class MipsAsmParser : public MCTargetAsmParser { 63 MipsTargetStreamer &getTargetStreamer() { 64 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer(); 65 return static_cast<MipsTargetStreamer &>(TS); 66 } 67 68 MCSubtargetInfo &STI; 69 MCAsmParser &Parser; 70 MipsAssemblerOptions Options; 71 72 #define GET_ASSEMBLER_HEADER 73 #include "MipsGenAsmMatcher.inc" 74 75 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 76 77 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 78 OperandVector &Operands, MCStreamer &Out, 79 unsigned &ErrorInfo, 80 bool MatchingInlineAsm) override; 81 82 /// Parse a register as used in CFI directives 83 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 84 85 bool ParseParenSuffix(StringRef Name, OperandVector &Operands); 86 87 bool ParseBracketSuffix(StringRef Name, OperandVector &Operands); 88 89 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 90 SMLoc NameLoc, OperandVector &Operands) override; 91 92 bool ParseDirective(AsmToken DirectiveID) override; 93 94 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands); 95 96 MipsAsmParser::OperandMatchResultTy 97 MatchAnyRegisterNameWithoutDollar(OperandVector &Operands, 98 StringRef Identifier, SMLoc S); 99 100 MipsAsmParser::OperandMatchResultTy 101 MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S); 102 103 MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands); 104 105 MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands); 106 107 MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands); 108 109 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands); 110 111 MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands); 112 113 bool searchSymbolAlias(OperandVector &Operands); 114 115 bool ParseOperand(OperandVector &, StringRef Mnemonic); 116 117 bool needsExpansion(MCInst &Inst); 118 119 // Expands assembly pseudo instructions. 120 // Returns false on success, true otherwise. 121 bool expandInstruction(MCInst &Inst, SMLoc IDLoc, 122 SmallVectorImpl<MCInst> &Instructions); 123 124 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, 125 SmallVectorImpl<MCInst> &Instructions); 126 127 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 128 SmallVectorImpl<MCInst> &Instructions); 129 130 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 131 SmallVectorImpl<MCInst> &Instructions); 132 133 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 134 SmallVectorImpl<MCInst> &Instructions, bool isLoad, 135 bool isImmOpnd); 136 bool reportParseError(StringRef ErrorMsg); 137 bool reportParseError(SMLoc Loc, StringRef ErrorMsg); 138 139 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 140 bool parseRelocOperand(const MCExpr *&Res); 141 142 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 143 144 bool isEvaluated(const MCExpr *Expr); 145 bool parseSetFeature(uint64_t Feature); 146 bool parseDirectiveCPLoad(SMLoc Loc); 147 bool parseDirectiveCPSetup(); 148 bool parseDirectiveNaN(); 149 bool parseDirectiveSet(); 150 bool parseDirectiveOption(); 151 152 bool parseSetAtDirective(); 153 bool parseSetNoAtDirective(); 154 bool parseSetMacroDirective(); 155 bool parseSetNoMacroDirective(); 156 bool parseSetReorderDirective(); 157 bool parseSetNoReorderDirective(); 158 bool parseSetNoMips16Directive(); 159 160 bool parseSetAssignment(); 161 162 bool parseDataDirective(unsigned Size, SMLoc L); 163 bool parseDirectiveGpWord(); 164 bool parseDirectiveGpDWord(); 165 166 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 167 168 bool isGP64() const { 169 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0; 170 } 171 172 bool isFP64() const { 173 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 174 } 175 176 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; } 177 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 178 179 bool isMicroMips() const { 180 return STI.getFeatureBits() & Mips::FeatureMicroMips; 181 } 182 183 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; } 184 bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; } 185 bool hasMips32r6() const { 186 return STI.getFeatureBits() & Mips::FeatureMips32r6; 187 } 188 bool hasMips64r6() const { 189 return STI.getFeatureBits() & Mips::FeatureMips64r6; 190 } 191 192 bool eatComma(StringRef ErrorStr); 193 194 int matchCPURegisterName(StringRef Symbol); 195 196 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 197 198 int matchFPURegisterName(StringRef Name); 199 200 int matchFCCRegisterName(StringRef Name); 201 202 int matchACRegisterName(StringRef Name); 203 204 int matchMSA128RegisterName(StringRef Name); 205 206 int matchMSA128CtrlRegisterName(StringRef Name); 207 208 unsigned getReg(int RC, int RegNo); 209 210 unsigned getGPR(int RegNo); 211 212 int getATReg(SMLoc Loc); 213 214 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 215 SmallVectorImpl<MCInst> &Instructions); 216 217 // Helper function that checks if the value of a vector index is within the 218 // boundaries of accepted values for each RegisterKind 219 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 220 bool validateMSAIndex(int Val, int RegKind); 221 222 void setFeatureBits(unsigned Feature, StringRef FeatureString) { 223 if (!(STI.getFeatureBits() & Feature)) { 224 setAvailableFeatures( 225 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 226 } 227 } 228 229 void clearFeatureBits(unsigned Feature, StringRef FeatureString) { 230 if (STI.getFeatureBits() & Feature) { 231 setAvailableFeatures( 232 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 233 } 234 } 235 236 public: 237 enum MipsMatchResultTy { 238 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY 239 #define GET_OPERAND_DIAGNOSTIC_TYPES 240 #include "MipsGenAsmMatcher.inc" 241 #undef GET_OPERAND_DIAGNOSTIC_TYPES 242 243 }; 244 245 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 246 const MCInstrInfo &MII, 247 const MCTargetOptions &Options) 248 : MCTargetAsmParser(), STI(sti), Parser(parser) { 249 // Initialize the set of available features. 250 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 251 252 // Assert exactly one ABI was chosen. 253 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + 254 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + 255 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + 256 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); 257 } 258 259 MCAsmParser &getParser() const { return Parser; } 260 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 261 262 /// True if all of $fcc0 - $fcc7 exist for the current ISA. 263 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); } 264 265 /// Warn if RegNo is the current assembler temporary. 266 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc); 267 }; 268 } 269 270 namespace { 271 272 /// MipsOperand - Instances of this class represent a parsed Mips machine 273 /// instruction. 274 class MipsOperand : public MCParsedAsmOperand { 275 public: 276 /// Broad categories of register classes 277 /// The exact class is finalized by the render method. 278 enum RegKind { 279 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64()) 280 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 281 /// isFP64()) 282 RegKind_FCC = 4, /// FCC 283 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 284 RegKind_MSACtrl = 16, /// MSA control registers 285 RegKind_COP2 = 32, /// COP2 286 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 287 /// context). 288 RegKind_CCR = 128, /// CCR 289 RegKind_HWRegs = 256, /// HWRegs 290 RegKind_COP3 = 512, /// COP3 291 292 /// Potentially any (e.g. $1) 293 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 294 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 295 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 296 }; 297 298 private: 299 enum KindTy { 300 k_Immediate, /// An immediate (possibly involving symbol references) 301 k_Memory, /// Base + Offset Memory Address 302 k_PhysRegister, /// A physical register from the Mips namespace 303 k_RegisterIndex, /// A register index in one or more RegKind. 304 k_Token /// A simple token 305 } Kind; 306 307 public: 308 MipsOperand(KindTy K, MipsAsmParser &Parser) 309 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 310 311 private: 312 /// For diagnostics, and checking the assembler temporary 313 MipsAsmParser &AsmParser; 314 315 struct Token { 316 const char *Data; 317 unsigned Length; 318 }; 319 320 struct PhysRegOp { 321 unsigned Num; /// Register Number 322 }; 323 324 struct RegIdxOp { 325 unsigned Index; /// Index into the register class 326 RegKind Kind; /// Bitfield of the kinds it could possibly be 327 const MCRegisterInfo *RegInfo; 328 }; 329 330 struct ImmOp { 331 const MCExpr *Val; 332 }; 333 334 struct MemOp { 335 MipsOperand *Base; 336 const MCExpr *Off; 337 }; 338 339 union { 340 struct Token Tok; 341 struct PhysRegOp PhysReg; 342 struct RegIdxOp RegIdx; 343 struct ImmOp Imm; 344 struct MemOp Mem; 345 }; 346 347 SMLoc StartLoc, EndLoc; 348 349 /// Internal constructor for register kinds 350 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind, 351 const MCRegisterInfo *RegInfo, 352 SMLoc S, SMLoc E, 353 MipsAsmParser &Parser) { 354 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser); 355 Op->RegIdx.Index = Index; 356 Op->RegIdx.RegInfo = RegInfo; 357 Op->RegIdx.Kind = RegKind; 358 Op->StartLoc = S; 359 Op->EndLoc = E; 360 return Op; 361 } 362 363 public: 364 /// Coerce the register to GPR32 and return the real register for the current 365 /// target. 366 unsigned getGPR32Reg() const { 367 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 368 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc); 369 unsigned ClassID = Mips::GPR32RegClassID; 370 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 371 } 372 373 /// Coerce the register to GPR64 and return the real register for the current 374 /// target. 375 unsigned getGPR64Reg() const { 376 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 377 unsigned ClassID = Mips::GPR64RegClassID; 378 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 379 } 380 381 private: 382 /// Coerce the register to AFGR64 and return the real register for the current 383 /// target. 384 unsigned getAFGR64Reg() const { 385 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 386 if (RegIdx.Index % 2 != 0) 387 AsmParser.Warning(StartLoc, "Float register should be even."); 388 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 389 .getRegister(RegIdx.Index / 2); 390 } 391 392 /// Coerce the register to FGR64 and return the real register for the current 393 /// target. 394 unsigned getFGR64Reg() const { 395 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 396 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 397 .getRegister(RegIdx.Index); 398 } 399 400 /// Coerce the register to FGR32 and return the real register for the current 401 /// target. 402 unsigned getFGR32Reg() const { 403 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 404 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 405 .getRegister(RegIdx.Index); 406 } 407 408 /// Coerce the register to FGRH32 and return the real register for the current 409 /// target. 410 unsigned getFGRH32Reg() const { 411 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 412 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 413 .getRegister(RegIdx.Index); 414 } 415 416 /// Coerce the register to FCC and return the real register for the current 417 /// target. 418 unsigned getFCCReg() const { 419 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 420 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 421 .getRegister(RegIdx.Index); 422 } 423 424 /// Coerce the register to MSA128 and return the real register for the current 425 /// target. 426 unsigned getMSA128Reg() const { 427 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 428 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 429 // identical 430 unsigned ClassID = Mips::MSA128BRegClassID; 431 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 432 } 433 434 /// Coerce the register to MSACtrl and return the real register for the 435 /// current target. 436 unsigned getMSACtrlReg() const { 437 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 438 unsigned ClassID = Mips::MSACtrlRegClassID; 439 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 440 } 441 442 /// Coerce the register to COP2 and return the real register for the 443 /// current target. 444 unsigned getCOP2Reg() const { 445 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 446 unsigned ClassID = Mips::COP2RegClassID; 447 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 448 } 449 450 /// Coerce the register to COP3 and return the real register for the 451 /// current target. 452 unsigned getCOP3Reg() const { 453 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); 454 unsigned ClassID = Mips::COP3RegClassID; 455 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 456 } 457 458 /// Coerce the register to ACC64DSP and return the real register for the 459 /// current target. 460 unsigned getACC64DSPReg() const { 461 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 462 unsigned ClassID = Mips::ACC64DSPRegClassID; 463 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 464 } 465 466 /// Coerce the register to HI32DSP and return the real register for the 467 /// current target. 468 unsigned getHI32DSPReg() const { 469 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 470 unsigned ClassID = Mips::HI32DSPRegClassID; 471 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 472 } 473 474 /// Coerce the register to LO32DSP and return the real register for the 475 /// current target. 476 unsigned getLO32DSPReg() const { 477 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 478 unsigned ClassID = Mips::LO32DSPRegClassID; 479 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 480 } 481 482 /// Coerce the register to CCR and return the real register for the 483 /// current target. 484 unsigned getCCRReg() const { 485 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 486 unsigned ClassID = Mips::CCRRegClassID; 487 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 488 } 489 490 /// Coerce the register to HWRegs and return the real register for the 491 /// current target. 492 unsigned getHWRegsReg() const { 493 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 494 unsigned ClassID = Mips::HWRegsRegClassID; 495 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 496 } 497 498 public: 499 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 500 // Add as immediate when possible. Null MCExpr = 0. 501 if (!Expr) 502 Inst.addOperand(MCOperand::CreateImm(0)); 503 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 504 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 505 else 506 Inst.addOperand(MCOperand::CreateExpr(Expr)); 507 } 508 509 void addRegOperands(MCInst &Inst, unsigned N) const { 510 llvm_unreachable("Use a custom parser instead"); 511 } 512 513 /// Render the operand to an MCInst as a GPR32 514 /// Asserts if the wrong number of operands are requested, or the operand 515 /// is not a k_RegisterIndex compatible with RegKind_GPR 516 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 517 assert(N == 1 && "Invalid number of operands!"); 518 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); 519 } 520 521 /// Render the operand to an MCInst as a GPR64 522 /// Asserts if the wrong number of operands are requested, or the operand 523 /// is not a k_RegisterIndex compatible with RegKind_GPR 524 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 525 assert(N == 1 && "Invalid number of operands!"); 526 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); 527 } 528 529 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 530 assert(N == 1 && "Invalid number of operands!"); 531 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); 532 } 533 534 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 535 assert(N == 1 && "Invalid number of operands!"); 536 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); 537 } 538 539 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 540 assert(N == 1 && "Invalid number of operands!"); 541 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); 542 } 543 544 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 545 assert(N == 1 && "Invalid number of operands!"); 546 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); 547 } 548 549 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 550 assert(N == 1 && "Invalid number of operands!"); 551 Inst.addOperand(MCOperand::CreateReg(getFCCReg())); 552 } 553 554 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 555 assert(N == 1 && "Invalid number of operands!"); 556 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); 557 } 558 559 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 560 assert(N == 1 && "Invalid number of operands!"); 561 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); 562 } 563 564 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 565 assert(N == 1 && "Invalid number of operands!"); 566 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); 567 } 568 569 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { 570 assert(N == 1 && "Invalid number of operands!"); 571 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg())); 572 } 573 574 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 575 assert(N == 1 && "Invalid number of operands!"); 576 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); 577 } 578 579 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 580 assert(N == 1 && "Invalid number of operands!"); 581 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); 582 } 583 584 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 585 assert(N == 1 && "Invalid number of operands!"); 586 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); 587 } 588 589 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 590 assert(N == 1 && "Invalid number of operands!"); 591 Inst.addOperand(MCOperand::CreateReg(getCCRReg())); 592 } 593 594 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 595 assert(N == 1 && "Invalid number of operands!"); 596 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); 597 } 598 599 void addImmOperands(MCInst &Inst, unsigned N) const { 600 assert(N == 1 && "Invalid number of operands!"); 601 const MCExpr *Expr = getImm(); 602 addExpr(Inst, Expr); 603 } 604 605 void addMemOperands(MCInst &Inst, unsigned N) const { 606 assert(N == 2 && "Invalid number of operands!"); 607 608 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); 609 610 const MCExpr *Expr = getMemOff(); 611 addExpr(Inst, Expr); 612 } 613 614 bool isReg() const override { 615 // As a special case until we sort out the definition of div/divu, pretend 616 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 617 if (isGPRAsmReg() && RegIdx.Index == 0) 618 return true; 619 620 return Kind == k_PhysRegister; 621 } 622 bool isRegIdx() const { return Kind == k_RegisterIndex; } 623 bool isImm() const override { return Kind == k_Immediate; } 624 bool isConstantImm() const { 625 return isImm() && dyn_cast<MCConstantExpr>(getImm()); 626 } 627 bool isToken() const override { 628 // Note: It's not possible to pretend that other operand kinds are tokens. 629 // The matcher emitter checks tokens first. 630 return Kind == k_Token; 631 } 632 bool isMem() const override { return Kind == k_Memory; } 633 bool isConstantMemOff() const { 634 return isMem() && dyn_cast<MCConstantExpr>(getMemOff()); 635 } 636 template <unsigned Bits> bool isMemWithSimmOffset() const { 637 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()); 638 } 639 bool isInvNum() const { return Kind == k_Immediate; } 640 bool isLSAImm() const { 641 if (!isConstantImm()) 642 return false; 643 int64_t Val = getConstantImm(); 644 return 1 <= Val && Val <= 4; 645 } 646 647 StringRef getToken() const { 648 assert(Kind == k_Token && "Invalid access!"); 649 return StringRef(Tok.Data, Tok.Length); 650 } 651 652 unsigned getReg() const override { 653 // As a special case until we sort out the definition of div/divu, pretend 654 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 655 if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 656 RegIdx.Kind & RegKind_GPR) 657 return getGPR32Reg(); // FIXME: GPR64 too 658 659 assert(Kind == k_PhysRegister && "Invalid access!"); 660 return PhysReg.Num; 661 } 662 663 const MCExpr *getImm() const { 664 assert((Kind == k_Immediate) && "Invalid access!"); 665 return Imm.Val; 666 } 667 668 int64_t getConstantImm() const { 669 const MCExpr *Val = getImm(); 670 return static_cast<const MCConstantExpr *>(Val)->getValue(); 671 } 672 673 MipsOperand *getMemBase() const { 674 assert((Kind == k_Memory) && "Invalid access!"); 675 return Mem.Base; 676 } 677 678 const MCExpr *getMemOff() const { 679 assert((Kind == k_Memory) && "Invalid access!"); 680 return Mem.Off; 681 } 682 683 int64_t getConstantMemOff() const { 684 return static_cast<const MCConstantExpr *>(getMemOff())->getValue(); 685 } 686 687 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, 688 MipsAsmParser &Parser) { 689 auto Op = make_unique<MipsOperand>(k_Token, Parser); 690 Op->Tok.Data = Str.data(); 691 Op->Tok.Length = Str.size(); 692 Op->StartLoc = S; 693 Op->EndLoc = S; 694 return Op; 695 } 696 697 /// Create a numeric register (e.g. $1). The exact register remains 698 /// unresolved until an instruction successfully matches 699 static std::unique_ptr<MipsOperand> 700 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 701 SMLoc E, MipsAsmParser &Parser) { 702 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n"); 703 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 704 } 705 706 /// Create a register that is definitely a GPR. 707 /// This is typically only used for named registers such as $gp. 708 static std::unique_ptr<MipsOperand> 709 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 710 MipsAsmParser &Parser) { 711 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 712 } 713 714 /// Create a register that is definitely a FGR. 715 /// This is typically only used for named registers such as $f0. 716 static std::unique_ptr<MipsOperand> 717 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 718 MipsAsmParser &Parser) { 719 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 720 } 721 722 /// Create a register that is definitely an FCC. 723 /// This is typically only used for named registers such as $fcc0. 724 static std::unique_ptr<MipsOperand> 725 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 726 MipsAsmParser &Parser) { 727 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 728 } 729 730 /// Create a register that is definitely an ACC. 731 /// This is typically only used for named registers such as $ac0. 732 static std::unique_ptr<MipsOperand> 733 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 734 MipsAsmParser &Parser) { 735 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 736 } 737 738 /// Create a register that is definitely an MSA128. 739 /// This is typically only used for named registers such as $w0. 740 static std::unique_ptr<MipsOperand> 741 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 742 SMLoc E, MipsAsmParser &Parser) { 743 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 744 } 745 746 /// Create a register that is definitely an MSACtrl. 747 /// This is typically only used for named registers such as $msaaccess. 748 static std::unique_ptr<MipsOperand> 749 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 750 SMLoc E, MipsAsmParser &Parser) { 751 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 752 } 753 754 static std::unique_ptr<MipsOperand> 755 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { 756 auto Op = make_unique<MipsOperand>(k_Immediate, Parser); 757 Op->Imm.Val = Val; 758 Op->StartLoc = S; 759 Op->EndLoc = E; 760 return Op; 761 } 762 763 static std::unique_ptr<MipsOperand> 764 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S, 765 SMLoc E, MipsAsmParser &Parser) { 766 auto Op = make_unique<MipsOperand>(k_Memory, Parser); 767 Op->Mem.Base = Base.release(); 768 Op->Mem.Off = Off; 769 Op->StartLoc = S; 770 Op->EndLoc = E; 771 return Op; 772 } 773 774 bool isGPRAsmReg() const { 775 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 776 } 777 bool isFGRAsmReg() const { 778 // AFGR64 is $0-$15 but we handle this in getAFGR64() 779 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 780 } 781 bool isHWRegsAsmReg() const { 782 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 783 } 784 bool isCCRAsmReg() const { 785 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 786 } 787 bool isFCCAsmReg() const { 788 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) 789 return false; 790 if (!AsmParser.hasEightFccRegisters()) 791 return RegIdx.Index == 0; 792 return RegIdx.Index <= 7; 793 } 794 bool isACCAsmReg() const { 795 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 796 } 797 bool isCOP2AsmReg() const { 798 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 799 } 800 bool isCOP3AsmReg() const { 801 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; 802 } 803 bool isMSA128AsmReg() const { 804 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 805 } 806 bool isMSACtrlAsmReg() const { 807 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 808 } 809 810 /// getStartLoc - Get the location of the first token of this operand. 811 SMLoc getStartLoc() const override { return StartLoc; } 812 /// getEndLoc - Get the location of the last token of this operand. 813 SMLoc getEndLoc() const override { return EndLoc; } 814 815 virtual ~MipsOperand() { 816 switch (Kind) { 817 case k_Immediate: 818 break; 819 case k_Memory: 820 delete Mem.Base; 821 break; 822 case k_PhysRegister: 823 case k_RegisterIndex: 824 case k_Token: 825 break; 826 } 827 } 828 829 void print(raw_ostream &OS) const override { 830 switch (Kind) { 831 case k_Immediate: 832 OS << "Imm<"; 833 Imm.Val->print(OS); 834 OS << ">"; 835 break; 836 case k_Memory: 837 OS << "Mem<"; 838 Mem.Base->print(OS); 839 OS << ", "; 840 Mem.Off->print(OS); 841 OS << ">"; 842 break; 843 case k_PhysRegister: 844 OS << "PhysReg<" << PhysReg.Num << ">"; 845 break; 846 case k_RegisterIndex: 847 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 848 break; 849 case k_Token: 850 OS << Tok.Data; 851 break; 852 } 853 } 854 }; // class MipsOperand 855 } // namespace 856 857 namespace llvm { 858 extern const MCInstrDesc MipsInsts[]; 859 } 860 static const MCInstrDesc &getInstDesc(unsigned Opcode) { 861 return MipsInsts[Opcode]; 862 } 863 864 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 865 SmallVectorImpl<MCInst> &Instructions) { 866 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 867 868 Inst.setLoc(IDLoc); 869 870 if (MCID.isBranch() || MCID.isCall()) { 871 const unsigned Opcode = Inst.getOpcode(); 872 MCOperand Offset; 873 874 switch (Opcode) { 875 default: 876 break; 877 case Mips::BEQ: 878 case Mips::BNE: 879 case Mips::BEQ_MM: 880 case Mips::BNE_MM: 881 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 882 Offset = Inst.getOperand(2); 883 if (!Offset.isImm()) 884 break; // We'll deal with this situation later on when applying fixups. 885 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm())) 886 return Error(IDLoc, "branch target out of range"); 887 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2))) 888 return Error(IDLoc, "branch to misaligned address"); 889 break; 890 case Mips::BGEZ: 891 case Mips::BGTZ: 892 case Mips::BLEZ: 893 case Mips::BLTZ: 894 case Mips::BGEZAL: 895 case Mips::BLTZAL: 896 case Mips::BC1F: 897 case Mips::BC1T: 898 case Mips::BGEZ_MM: 899 case Mips::BGTZ_MM: 900 case Mips::BLEZ_MM: 901 case Mips::BLTZ_MM: 902 case Mips::BGEZAL_MM: 903 case Mips::BLTZAL_MM: 904 case Mips::BC1F_MM: 905 case Mips::BC1T_MM: 906 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 907 Offset = Inst.getOperand(1); 908 if (!Offset.isImm()) 909 break; // We'll deal with this situation later on when applying fixups. 910 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm())) 911 return Error(IDLoc, "branch target out of range"); 912 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2))) 913 return Error(IDLoc, "branch to misaligned address"); 914 break; 915 } 916 } 917 918 // SSNOP is deprecated on MIPS32r6/MIPS64r6 919 // We still accept it but it is a normal nop. 920 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) { 921 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6"; 922 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a " 923 "nop instruction"); 924 } 925 926 if (MCID.hasDelaySlot() && Options.isReorder()) { 927 // If this instruction has a delay slot and .set reorder is active, 928 // emit a NOP after it. 929 Instructions.push_back(Inst); 930 MCInst NopInst; 931 NopInst.setOpcode(Mips::SLL); 932 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 933 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 934 NopInst.addOperand(MCOperand::CreateImm(0)); 935 Instructions.push_back(NopInst); 936 return false; 937 } 938 939 if (MCID.mayLoad() || MCID.mayStore()) { 940 // Check the offset of memory operand, if it is a symbol 941 // reference or immediate we may have to expand instructions. 942 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 943 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 944 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 945 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 946 MCOperand &Op = Inst.getOperand(i); 947 if (Op.isImm()) { 948 int MemOffset = Op.getImm(); 949 if (MemOffset < -32768 || MemOffset > 32767) { 950 // Offset can't exceed 16bit value. 951 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 952 return false; 953 } 954 } else if (Op.isExpr()) { 955 const MCExpr *Expr = Op.getExpr(); 956 if (Expr->getKind() == MCExpr::SymbolRef) { 957 const MCSymbolRefExpr *SR = 958 static_cast<const MCSymbolRefExpr *>(Expr); 959 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 960 // Expand symbol. 961 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 962 return false; 963 } 964 } else if (!isEvaluated(Expr)) { 965 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 966 return false; 967 } 968 } 969 } 970 } // for 971 } // if load/store 972 973 if (needsExpansion(Inst)) 974 return expandInstruction(Inst, IDLoc, Instructions); 975 else 976 Instructions.push_back(Inst); 977 978 return false; 979 } 980 981 bool MipsAsmParser::needsExpansion(MCInst &Inst) { 982 983 switch (Inst.getOpcode()) { 984 case Mips::LoadImm32Reg: 985 case Mips::LoadAddr32Imm: 986 case Mips::LoadAddr32Reg: 987 case Mips::LoadImm64Reg: 988 return true; 989 default: 990 return false; 991 } 992 } 993 994 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 995 SmallVectorImpl<MCInst> &Instructions) { 996 switch (Inst.getOpcode()) { 997 default: assert(0 && "unimplemented expansion"); 998 return true; 999 case Mips::LoadImm32Reg: 1000 return expandLoadImm(Inst, IDLoc, Instructions); 1001 case Mips::LoadImm64Reg: 1002 if (!isGP64()) { 1003 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1004 return true; 1005 } 1006 return expandLoadImm(Inst, IDLoc, Instructions); 1007 case Mips::LoadAddr32Imm: 1008 return expandLoadAddressImm(Inst, IDLoc, Instructions); 1009 case Mips::LoadAddr32Reg: 1010 return expandLoadAddressReg(Inst, IDLoc, Instructions); 1011 } 1012 } 1013 1014 namespace { 1015 template <int Shift, bool PerformShift> 1016 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc, 1017 SmallVectorImpl<MCInst> &Instructions) { 1018 MCInst tmpInst; 1019 if (PerformShift) { 1020 tmpInst.setOpcode(Mips::DSLL); 1021 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1022 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1023 tmpInst.addOperand(MCOperand::CreateImm(16)); 1024 tmpInst.setLoc(IDLoc); 1025 Instructions.push_back(tmpInst); 1026 tmpInst.clear(); 1027 } 1028 tmpInst.setOpcode(Mips::ORi); 1029 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1030 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1031 tmpInst.addOperand( 1032 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift))); 1033 tmpInst.setLoc(IDLoc); 1034 Instructions.push_back(tmpInst); 1035 } 1036 } 1037 1038 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 1039 SmallVectorImpl<MCInst> &Instructions) { 1040 MCInst tmpInst; 1041 const MCOperand &ImmOp = Inst.getOperand(1); 1042 assert(ImmOp.isImm() && "expected immediate operand kind"); 1043 const MCOperand &RegOp = Inst.getOperand(0); 1044 assert(RegOp.isReg() && "expected register operand kind"); 1045 1046 int64_t ImmValue = ImmOp.getImm(); 1047 tmpInst.setLoc(IDLoc); 1048 // FIXME: gas has a special case for values that are 000...1111, which 1049 // becomes a li -1 and then a dsrl 1050 if (0 <= ImmValue && ImmValue <= 65535) { 1051 // For 0 <= j <= 65535. 1052 // li d,j => ori d,$zero,j 1053 tmpInst.setOpcode(Mips::ORi); 1054 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1055 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1056 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1057 Instructions.push_back(tmpInst); 1058 } else if (ImmValue < 0 && ImmValue >= -32768) { 1059 // For -32768 <= j < 0. 1060 // li d,j => addiu d,$zero,j 1061 tmpInst.setOpcode(Mips::ADDiu); 1062 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1063 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1064 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1065 Instructions.push_back(tmpInst); 1066 } else if ((ImmValue & 0xffffffff) == ImmValue) { 1067 // For any value of j that is representable as a 32-bit integer, create 1068 // a sequence of: 1069 // li d,j => lui d,hi16(j) 1070 // ori d,d,lo16(j) 1071 tmpInst.setOpcode(Mips::LUi); 1072 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1073 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1074 Instructions.push_back(tmpInst); 1075 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1076 } else if ((ImmValue & (0xffffLL << 48)) == 0) { 1077 if (!isGP64()) { 1078 Error (IDLoc, "instruction requires a CPU feature not currently enabled"); 1079 return true; 1080 } 1081 1082 // <------- lo32 ------> 1083 // <------- hi32 ------> 1084 // <- hi16 -> <- lo16 -> 1085 // _________________________________ 1086 // | | | | 1087 // | 16-bytes | 16-bytes | 16-bytes | 1088 // |__________|__________|__________| 1089 // 1090 // For any value of j that is representable as a 48-bit integer, create 1091 // a sequence of: 1092 // li d,j => lui d,hi16(j) 1093 // ori d,d,hi16(lo32(j)) 1094 // dsll d,d,16 1095 // ori d,d,lo16(lo32(j)) 1096 tmpInst.setOpcode(Mips::LUi); 1097 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1098 tmpInst.addOperand( 1099 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32)); 1100 Instructions.push_back(tmpInst); 1101 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1102 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1103 } else { 1104 if (!isGP64()) { 1105 Error (IDLoc, "instruction requires a CPU feature not currently enabled"); 1106 return true; 1107 } 1108 1109 // <------- hi32 ------> <------- lo32 ------> 1110 // <- hi16 -> <- lo16 -> 1111 // ___________________________________________ 1112 // | | | | | 1113 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes | 1114 // |__________|__________|__________|__________| 1115 // 1116 // For any value of j that isn't representable as a 48-bit integer. 1117 // li d,j => lui d,hi16(j) 1118 // ori d,d,lo16(hi32(j)) 1119 // dsll d,d,16 1120 // ori d,d,hi16(lo32(j)) 1121 // dsll d,d,16 1122 // ori d,d,lo16(lo32(j)) 1123 tmpInst.setOpcode(Mips::LUi); 1124 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1125 tmpInst.addOperand( 1126 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48)); 1127 Instructions.push_back(tmpInst); 1128 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1129 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1130 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1131 } 1132 return false; 1133 } 1134 1135 bool 1136 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1137 SmallVectorImpl<MCInst> &Instructions) { 1138 MCInst tmpInst; 1139 const MCOperand &ImmOp = Inst.getOperand(2); 1140 assert(ImmOp.isImm() && "expected immediate operand kind"); 1141 const MCOperand &SrcRegOp = Inst.getOperand(1); 1142 assert(SrcRegOp.isReg() && "expected register operand kind"); 1143 const MCOperand &DstRegOp = Inst.getOperand(0); 1144 assert(DstRegOp.isReg() && "expected register operand kind"); 1145 int ImmValue = ImmOp.getImm(); 1146 if (-32768 <= ImmValue && ImmValue <= 65535) { 1147 // For -32768 <= j <= 65535. 1148 // la d,j(s) => addiu d,s,j 1149 tmpInst.setOpcode(Mips::ADDiu); 1150 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1151 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1152 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1153 Instructions.push_back(tmpInst); 1154 } else { 1155 // For any other value of j that is representable as a 32-bit integer. 1156 // la d,j(s) => lui d,hi16(j) 1157 // ori d,d,lo16(j) 1158 // addu d,d,s 1159 tmpInst.setOpcode(Mips::LUi); 1160 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1161 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1162 Instructions.push_back(tmpInst); 1163 tmpInst.clear(); 1164 tmpInst.setOpcode(Mips::ORi); 1165 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1166 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1167 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1168 Instructions.push_back(tmpInst); 1169 tmpInst.clear(); 1170 tmpInst.setOpcode(Mips::ADDu); 1171 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1172 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1173 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1174 Instructions.push_back(tmpInst); 1175 } 1176 return false; 1177 } 1178 1179 bool 1180 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1181 SmallVectorImpl<MCInst> &Instructions) { 1182 MCInst tmpInst; 1183 const MCOperand &ImmOp = Inst.getOperand(1); 1184 assert(ImmOp.isImm() && "expected immediate operand kind"); 1185 const MCOperand &RegOp = Inst.getOperand(0); 1186 assert(RegOp.isReg() && "expected register operand kind"); 1187 int ImmValue = ImmOp.getImm(); 1188 if (-32768 <= ImmValue && ImmValue <= 65535) { 1189 // For -32768 <= j <= 65535. 1190 // la d,j => addiu d,$zero,j 1191 tmpInst.setOpcode(Mips::ADDiu); 1192 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1193 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1194 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1195 Instructions.push_back(tmpInst); 1196 } else { 1197 // For any other value of j that is representable as a 32-bit integer. 1198 // la d,j => lui d,hi16(j) 1199 // ori d,d,lo16(j) 1200 tmpInst.setOpcode(Mips::LUi); 1201 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1202 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1203 Instructions.push_back(tmpInst); 1204 tmpInst.clear(); 1205 tmpInst.setOpcode(Mips::ORi); 1206 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1207 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1208 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1209 Instructions.push_back(tmpInst); 1210 } 1211 return false; 1212 } 1213 1214 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 1215 SmallVectorImpl<MCInst> &Instructions, 1216 bool isLoad, bool isImmOpnd) { 1217 const MCSymbolRefExpr *SR; 1218 MCInst TempInst; 1219 unsigned ImmOffset, HiOffset, LoOffset; 1220 const MCExpr *ExprOffset; 1221 unsigned TmpRegNum; 1222 // 1st operand is either the source or destination register. 1223 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 1224 unsigned RegOpNum = Inst.getOperand(0).getReg(); 1225 // 2nd operand is the base register. 1226 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 1227 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 1228 // 3rd operand is either an immediate or expression. 1229 if (isImmOpnd) { 1230 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 1231 ImmOffset = Inst.getOperand(2).getImm(); 1232 LoOffset = ImmOffset & 0x0000ffff; 1233 HiOffset = (ImmOffset & 0xffff0000) >> 16; 1234 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 1235 if (LoOffset & 0x8000) 1236 HiOffset++; 1237 } else 1238 ExprOffset = Inst.getOperand(2).getExpr(); 1239 // All instructions will have the same location. 1240 TempInst.setLoc(IDLoc); 1241 // These are some of the types of expansions we perform here: 1242 // 1) lw $8, sym => lui $8, %hi(sym) 1243 // lw $8, %lo(sym)($8) 1244 // 2) lw $8, offset($9) => lui $8, %hi(offset) 1245 // add $8, $8, $9 1246 // lw $8, %lo(offset)($9) 1247 // 3) lw $8, offset($8) => lui $at, %hi(offset) 1248 // add $at, $at, $8 1249 // lw $8, %lo(offset)($at) 1250 // 4) sw $8, sym => lui $at, %hi(sym) 1251 // sw $8, %lo(sym)($at) 1252 // 5) sw $8, offset($8) => lui $at, %hi(offset) 1253 // add $at, $at, $8 1254 // sw $8, %lo(offset)($at) 1255 // 6) ldc1 $f0, sym => lui $at, %hi(sym) 1256 // ldc1 $f0, %lo(sym)($at) 1257 // 1258 // For load instructions we can use the destination register as a temporary 1259 // if base and dst are different (examples 1 and 2) and if the base register 1260 // is general purpose otherwise we must use $at (example 6) and error if it's 1261 // not available. For stores we must use $at (examples 4 and 5) because we 1262 // must not clobber the source register setting up the offset. 1263 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode()); 1264 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass; 1265 unsigned RegClassIDOp0 = 1266 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID(); 1267 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) || 1268 (RegClassIDOp0 == Mips::GPR64RegClassID); 1269 if (isLoad && IsGPR && (BaseRegNum != RegOpNum)) 1270 TmpRegNum = RegOpNum; 1271 else { 1272 int AT = getATReg(IDLoc); 1273 // At this point we need AT to perform the expansions and we exit if it is 1274 // not available. 1275 if (!AT) 1276 return; 1277 TmpRegNum = 1278 getReg((isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT); 1279 } 1280 1281 TempInst.setOpcode(Mips::LUi); 1282 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1283 if (isImmOpnd) 1284 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 1285 else { 1286 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1287 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 1288 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 1289 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 1290 getContext()); 1291 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1292 } else { 1293 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 1294 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1295 } 1296 } 1297 // Add the instruction to the list. 1298 Instructions.push_back(TempInst); 1299 // Prepare TempInst for next instruction. 1300 TempInst.clear(); 1301 // Add temp register to base. 1302 TempInst.setOpcode(Mips::ADDu); 1303 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1304 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1305 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 1306 Instructions.push_back(TempInst); 1307 TempInst.clear(); 1308 // And finally, create original instruction with low part 1309 // of offset and new base. 1310 TempInst.setOpcode(Inst.getOpcode()); 1311 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 1312 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1313 if (isImmOpnd) 1314 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 1315 else { 1316 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1317 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 1318 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 1319 getContext()); 1320 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1321 } else { 1322 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 1323 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1324 } 1325 } 1326 Instructions.push_back(TempInst); 1327 TempInst.clear(); 1328 } 1329 1330 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 1331 // As described by the Mips32r2 spec, the registers Rd and Rs for 1332 // jalr.hb must be different. 1333 unsigned Opcode = Inst.getOpcode(); 1334 1335 if (Opcode == Mips::JALR_HB && 1336 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())) 1337 return Match_RequiresDifferentSrcAndDst; 1338 1339 return Match_Success; 1340 } 1341 1342 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1343 OperandVector &Operands, 1344 MCStreamer &Out, 1345 unsigned &ErrorInfo, 1346 bool MatchingInlineAsm) { 1347 1348 MCInst Inst; 1349 SmallVector<MCInst, 8> Instructions; 1350 unsigned MatchResult = 1351 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 1352 1353 switch (MatchResult) { 1354 default: 1355 break; 1356 case Match_Success: { 1357 if (processInstruction(Inst, IDLoc, Instructions)) 1358 return true; 1359 for (unsigned i = 0; i < Instructions.size(); i++) 1360 Out.EmitInstruction(Instructions[i], STI); 1361 return false; 1362 } 1363 case Match_MissingFeature: 1364 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1365 return true; 1366 case Match_InvalidOperand: { 1367 SMLoc ErrorLoc = IDLoc; 1368 if (ErrorInfo != ~0U) { 1369 if (ErrorInfo >= Operands.size()) 1370 return Error(IDLoc, "too few operands for instruction"); 1371 1372 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc(); 1373 if (ErrorLoc == SMLoc()) 1374 ErrorLoc = IDLoc; 1375 } 1376 1377 return Error(ErrorLoc, "invalid operand for instruction"); 1378 } 1379 case Match_MnemonicFail: 1380 return Error(IDLoc, "invalid instruction"); 1381 case Match_RequiresDifferentSrcAndDst: 1382 return Error(IDLoc, "source and destination must be different"); 1383 } 1384 return true; 1385 } 1386 1387 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { 1388 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) { 1389 if (RegIndex == 1) 1390 Warning(Loc, "Used $at without \".set noat\""); 1391 else 1392 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" + 1393 Twine(RegIndex) + "\""); 1394 } 1395 } 1396 1397 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 1398 int CC; 1399 1400 CC = StringSwitch<unsigned>(Name) 1401 .Case("zero", 0) 1402 .Case("at", 1) 1403 .Case("a0", 4) 1404 .Case("a1", 5) 1405 .Case("a2", 6) 1406 .Case("a3", 7) 1407 .Case("v0", 2) 1408 .Case("v1", 3) 1409 .Case("s0", 16) 1410 .Case("s1", 17) 1411 .Case("s2", 18) 1412 .Case("s3", 19) 1413 .Case("s4", 20) 1414 .Case("s5", 21) 1415 .Case("s6", 22) 1416 .Case("s7", 23) 1417 .Case("k0", 26) 1418 .Case("k1", 27) 1419 .Case("gp", 28) 1420 .Case("sp", 29) 1421 .Case("fp", 30) 1422 .Case("s8", 30) 1423 .Case("ra", 31) 1424 .Case("t0", 8) 1425 .Case("t1", 9) 1426 .Case("t2", 10) 1427 .Case("t3", 11) 1428 .Case("t4", 12) 1429 .Case("t5", 13) 1430 .Case("t6", 14) 1431 .Case("t7", 15) 1432 .Case("t8", 24) 1433 .Case("t9", 25) 1434 .Default(-1); 1435 1436 if (isN32() || isN64()) { 1437 // Although SGI documentation just cuts out t0-t3 for n32/n64, 1438 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 1439 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 1440 if (8 <= CC && CC <= 11) 1441 CC += 4; 1442 1443 if (CC == -1) 1444 CC = StringSwitch<unsigned>(Name) 1445 .Case("a4", 8) 1446 .Case("a5", 9) 1447 .Case("a6", 10) 1448 .Case("a7", 11) 1449 .Case("kt0", 26) 1450 .Case("kt1", 27) 1451 .Default(-1); 1452 } 1453 1454 return CC; 1455 } 1456 1457 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 1458 1459 if (Name[0] == 'f') { 1460 StringRef NumString = Name.substr(1); 1461 unsigned IntVal; 1462 if (NumString.getAsInteger(10, IntVal)) 1463 return -1; // This is not an integer. 1464 if (IntVal > 31) // Maximum index for fpu register. 1465 return -1; 1466 return IntVal; 1467 } 1468 return -1; 1469 } 1470 1471 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 1472 1473 if (Name.startswith("fcc")) { 1474 StringRef NumString = Name.substr(3); 1475 unsigned IntVal; 1476 if (NumString.getAsInteger(10, IntVal)) 1477 return -1; // This is not an integer. 1478 if (IntVal > 7) // There are only 8 fcc registers. 1479 return -1; 1480 return IntVal; 1481 } 1482 return -1; 1483 } 1484 1485 int MipsAsmParser::matchACRegisterName(StringRef Name) { 1486 1487 if (Name.startswith("ac")) { 1488 StringRef NumString = Name.substr(2); 1489 unsigned IntVal; 1490 if (NumString.getAsInteger(10, IntVal)) 1491 return -1; // This is not an integer. 1492 if (IntVal > 3) // There are only 3 acc registers. 1493 return -1; 1494 return IntVal; 1495 } 1496 return -1; 1497 } 1498 1499 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 1500 unsigned IntVal; 1501 1502 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 1503 return -1; 1504 1505 if (IntVal > 31) 1506 return -1; 1507 1508 return IntVal; 1509 } 1510 1511 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 1512 int CC; 1513 1514 CC = StringSwitch<unsigned>(Name) 1515 .Case("msair", 0) 1516 .Case("msacsr", 1) 1517 .Case("msaaccess", 2) 1518 .Case("msasave", 3) 1519 .Case("msamodify", 4) 1520 .Case("msarequest", 5) 1521 .Case("msamap", 6) 1522 .Case("msaunmap", 7) 1523 .Default(-1); 1524 1525 return CC; 1526 } 1527 1528 bool MipsAssemblerOptions::setATReg(unsigned Reg) { 1529 if (Reg > 31) 1530 return false; 1531 1532 aTReg = Reg; 1533 return true; 1534 } 1535 1536 int MipsAsmParser::getATReg(SMLoc Loc) { 1537 int AT = Options.getATRegNum(); 1538 if (AT == 0) 1539 reportParseError(Loc, 1540 "Pseudo instruction requires $at, which is not available"); 1541 return AT; 1542 } 1543 1544 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 1545 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 1546 } 1547 1548 unsigned MipsAsmParser::getGPR(int RegNo) { 1549 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 1550 RegNo); 1551 } 1552 1553 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 1554 if (RegNum > 1555 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 1556 return -1; 1557 1558 return getReg(RegClass, RegNum); 1559 } 1560 1561 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) { 1562 DEBUG(dbgs() << "ParseOperand\n"); 1563 1564 // Check if the current operand has a custom associated parser, if so, try to 1565 // custom parse the operand, or fallback to the general approach. 1566 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1567 if (ResTy == MatchOperand_Success) 1568 return false; 1569 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1570 // there was a match, but an error occurred, in which case, just return that 1571 // the operand parsing failed. 1572 if (ResTy == MatchOperand_ParseFail) 1573 return true; 1574 1575 DEBUG(dbgs() << ".. Generic Parser\n"); 1576 1577 switch (getLexer().getKind()) { 1578 default: 1579 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1580 return true; 1581 case AsmToken::Dollar: { 1582 // Parse the register. 1583 SMLoc S = Parser.getTok().getLoc(); 1584 1585 // Almost all registers have been parsed by custom parsers. There is only 1586 // one exception to this. $zero (and it's alias $0) will reach this point 1587 // for div, divu, and similar instructions because it is not an operand 1588 // to the instruction definition but an explicit register. Special case 1589 // this situation for now. 1590 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch) 1591 return false; 1592 1593 // Maybe it is a symbol reference. 1594 StringRef Identifier; 1595 if (Parser.parseIdentifier(Identifier)) 1596 return true; 1597 1598 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1599 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 1600 // Otherwise create a symbol reference. 1601 const MCExpr *Res = 1602 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1603 1604 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 1605 return false; 1606 } 1607 // Else drop to expression parsing. 1608 case AsmToken::LParen: 1609 case AsmToken::Minus: 1610 case AsmToken::Plus: 1611 case AsmToken::Integer: 1612 case AsmToken::Tilde: 1613 case AsmToken::String: { 1614 DEBUG(dbgs() << ".. generic integer\n"); 1615 OperandMatchResultTy ResTy = ParseImm(Operands); 1616 return ResTy != MatchOperand_Success; 1617 } 1618 case AsmToken::Percent: { 1619 // It is a symbol reference or constant expression. 1620 const MCExpr *IdVal; 1621 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1622 if (parseRelocOperand(IdVal)) 1623 return true; 1624 1625 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1626 1627 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1628 return false; 1629 } // case AsmToken::Percent 1630 } // switch(getLexer().getKind()) 1631 return true; 1632 } 1633 1634 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 1635 StringRef RelocStr) { 1636 const MCExpr *Res; 1637 // Check the type of the expression. 1638 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 1639 // It's a constant, evaluate reloc value. 1640 int16_t Val; 1641 switch (getVariantKind(RelocStr)) { 1642 case MCSymbolRefExpr::VK_Mips_ABS_LO: 1643 // Get the 1st 16-bits. 1644 Val = MCE->getValue() & 0xffff; 1645 break; 1646 case MCSymbolRefExpr::VK_Mips_ABS_HI: 1647 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low 1648 // 16 bits being negative. 1649 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff; 1650 break; 1651 case MCSymbolRefExpr::VK_Mips_HIGHER: 1652 // Get the 3rd 16-bits. 1653 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff; 1654 break; 1655 case MCSymbolRefExpr::VK_Mips_HIGHEST: 1656 // Get the 4th 16-bits. 1657 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff; 1658 break; 1659 default: 1660 report_fatal_error("Unsupported reloc value!"); 1661 } 1662 return MCConstantExpr::Create(Val, getContext()); 1663 } 1664 1665 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 1666 // It's a symbol, create a symbolic expression from the symbol. 1667 StringRef Symbol = MSRE->getSymbol().getName(); 1668 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1669 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 1670 return Res; 1671 } 1672 1673 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1674 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1675 1676 // Try to create target expression. 1677 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE)) 1678 return MipsMCExpr::Create(VK, Expr, getContext()); 1679 1680 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 1681 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 1682 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 1683 return Res; 1684 } 1685 1686 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 1687 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 1688 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 1689 return Res; 1690 } 1691 // Just return the original expression. 1692 return Expr; 1693 } 1694 1695 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 1696 1697 switch (Expr->getKind()) { 1698 case MCExpr::Constant: 1699 return true; 1700 case MCExpr::SymbolRef: 1701 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 1702 case MCExpr::Binary: 1703 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1704 if (!isEvaluated(BE->getLHS())) 1705 return false; 1706 return isEvaluated(BE->getRHS()); 1707 } 1708 case MCExpr::Unary: 1709 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1710 case MCExpr::Target: 1711 return true; 1712 } 1713 return false; 1714 } 1715 1716 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 1717 Parser.Lex(); // Eat the % token. 1718 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 1719 if (Tok.isNot(AsmToken::Identifier)) 1720 return true; 1721 1722 std::string Str = Tok.getIdentifier().str(); 1723 1724 Parser.Lex(); // Eat the identifier. 1725 // Now make an expression from the rest of the operand. 1726 const MCExpr *IdVal; 1727 SMLoc EndLoc; 1728 1729 if (getLexer().getKind() == AsmToken::LParen) { 1730 while (1) { 1731 Parser.Lex(); // Eat the '(' token. 1732 if (getLexer().getKind() == AsmToken::Percent) { 1733 Parser.Lex(); // Eat the % token. 1734 const AsmToken &nextTok = Parser.getTok(); 1735 if (nextTok.isNot(AsmToken::Identifier)) 1736 return true; 1737 Str += "(%"; 1738 Str += nextTok.getIdentifier(); 1739 Parser.Lex(); // Eat the identifier. 1740 if (getLexer().getKind() != AsmToken::LParen) 1741 return true; 1742 } else 1743 break; 1744 } 1745 if (getParser().parseParenExpression(IdVal, EndLoc)) 1746 return true; 1747 1748 while (getLexer().getKind() == AsmToken::RParen) 1749 Parser.Lex(); // Eat the ')' token. 1750 1751 } else 1752 return true; // Parenthesis must follow the relocation operand. 1753 1754 Res = evaluateRelocExpr(IdVal, Str); 1755 return false; 1756 } 1757 1758 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1759 SMLoc &EndLoc) { 1760 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 1761 OperandMatchResultTy ResTy = ParseAnyRegister(Operands); 1762 if (ResTy == MatchOperand_Success) { 1763 assert(Operands.size() == 1); 1764 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 1765 StartLoc = Operand.getStartLoc(); 1766 EndLoc = Operand.getEndLoc(); 1767 1768 // AFAIK, we only support numeric registers and named GPR's in CFI 1769 // directives. 1770 // Don't worry about eating tokens before failing. Using an unrecognised 1771 // register is a parse error. 1772 if (Operand.isGPRAsmReg()) { 1773 // Resolve to GPR32 or GPR64 appropriately. 1774 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 1775 } 1776 1777 return (RegNo == (unsigned)-1); 1778 } 1779 1780 assert(Operands.size() == 0); 1781 return (RegNo == (unsigned)-1); 1782 } 1783 1784 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1785 SMLoc S; 1786 bool Result = true; 1787 1788 while (getLexer().getKind() == AsmToken::LParen) 1789 Parser.Lex(); 1790 1791 switch (getLexer().getKind()) { 1792 default: 1793 return true; 1794 case AsmToken::Identifier: 1795 case AsmToken::LParen: 1796 case AsmToken::Integer: 1797 case AsmToken::Minus: 1798 case AsmToken::Plus: 1799 if (isParenExpr) 1800 Result = getParser().parseParenExpression(Res, S); 1801 else 1802 Result = (getParser().parseExpression(Res)); 1803 while (getLexer().getKind() == AsmToken::RParen) 1804 Parser.Lex(); 1805 break; 1806 case AsmToken::Percent: 1807 Result = parseRelocOperand(Res); 1808 } 1809 return Result; 1810 } 1811 1812 MipsAsmParser::OperandMatchResultTy 1813 MipsAsmParser::parseMemOperand(OperandVector &Operands) { 1814 DEBUG(dbgs() << "parseMemOperand\n"); 1815 const MCExpr *IdVal = nullptr; 1816 SMLoc S; 1817 bool isParenExpr = false; 1818 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 1819 // First operand is the offset. 1820 S = Parser.getTok().getLoc(); 1821 1822 if (getLexer().getKind() == AsmToken::LParen) { 1823 Parser.Lex(); 1824 isParenExpr = true; 1825 } 1826 1827 if (getLexer().getKind() != AsmToken::Dollar) { 1828 if (parseMemOffset(IdVal, isParenExpr)) 1829 return MatchOperand_ParseFail; 1830 1831 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1832 if (Tok.isNot(AsmToken::LParen)) { 1833 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 1834 if (Mnemonic.getToken() == "la") { 1835 SMLoc E = 1836 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1837 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1838 return MatchOperand_Success; 1839 } 1840 if (Tok.is(AsmToken::EndOfStatement)) { 1841 SMLoc E = 1842 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1843 1844 // Zero register assumed, add a memory operand with ZERO as its base. 1845 // "Base" will be managed by k_Memory. 1846 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(), 1847 S, E, *this); 1848 Operands.push_back( 1849 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 1850 return MatchOperand_Success; 1851 } 1852 Error(Parser.getTok().getLoc(), "'(' expected"); 1853 return MatchOperand_ParseFail; 1854 } 1855 1856 Parser.Lex(); // Eat the '(' token. 1857 } 1858 1859 Res = ParseAnyRegister(Operands); 1860 if (Res != MatchOperand_Success) 1861 return Res; 1862 1863 if (Parser.getTok().isNot(AsmToken::RParen)) { 1864 Error(Parser.getTok().getLoc(), "')' expected"); 1865 return MatchOperand_ParseFail; 1866 } 1867 1868 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1869 1870 Parser.Lex(); // Eat the ')' token. 1871 1872 if (!IdVal) 1873 IdVal = MCConstantExpr::Create(0, getContext()); 1874 1875 // Replace the register operand with the memory operand. 1876 std::unique_ptr<MipsOperand> op( 1877 static_cast<MipsOperand *>(Operands.back().release())); 1878 // Remove the register from the operands. 1879 // "op" will be managed by k_Memory. 1880 Operands.pop_back(); 1881 // Add the memory operand. 1882 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 1883 int64_t Imm; 1884 if (IdVal->EvaluateAsAbsolute(Imm)) 1885 IdVal = MCConstantExpr::Create(Imm, getContext()); 1886 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 1887 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 1888 getContext()); 1889 } 1890 1891 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 1892 return MatchOperand_Success; 1893 } 1894 1895 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 1896 1897 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1898 if (Sym) { 1899 SMLoc S = Parser.getTok().getLoc(); 1900 const MCExpr *Expr; 1901 if (Sym->isVariable()) 1902 Expr = Sym->getVariableValue(); 1903 else 1904 return false; 1905 if (Expr->getKind() == MCExpr::SymbolRef) { 1906 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 1907 const StringRef DefSymbol = Ref->getSymbol().getName(); 1908 if (DefSymbol.startswith("$")) { 1909 OperandMatchResultTy ResTy = 1910 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 1911 if (ResTy == MatchOperand_Success) { 1912 Parser.Lex(); 1913 return true; 1914 } else if (ResTy == MatchOperand_ParseFail) 1915 llvm_unreachable("Should never ParseFail"); 1916 return false; 1917 } 1918 } else if (Expr->getKind() == MCExpr::Constant) { 1919 Parser.Lex(); 1920 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 1921 Operands.push_back( 1922 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this)); 1923 return true; 1924 } 1925 } 1926 return false; 1927 } 1928 1929 MipsAsmParser::OperandMatchResultTy 1930 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands, 1931 StringRef Identifier, 1932 SMLoc S) { 1933 int Index = matchCPURegisterName(Identifier); 1934 if (Index != -1) { 1935 Operands.push_back(MipsOperand::CreateGPRReg( 1936 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1937 return MatchOperand_Success; 1938 } 1939 1940 Index = matchFPURegisterName(Identifier); 1941 if (Index != -1) { 1942 Operands.push_back(MipsOperand::CreateFGRReg( 1943 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1944 return MatchOperand_Success; 1945 } 1946 1947 Index = matchFCCRegisterName(Identifier); 1948 if (Index != -1) { 1949 Operands.push_back(MipsOperand::CreateFCCReg( 1950 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1951 return MatchOperand_Success; 1952 } 1953 1954 Index = matchACRegisterName(Identifier); 1955 if (Index != -1) { 1956 Operands.push_back(MipsOperand::CreateACCReg( 1957 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1958 return MatchOperand_Success; 1959 } 1960 1961 Index = matchMSA128RegisterName(Identifier); 1962 if (Index != -1) { 1963 Operands.push_back(MipsOperand::CreateMSA128Reg( 1964 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1965 return MatchOperand_Success; 1966 } 1967 1968 Index = matchMSA128CtrlRegisterName(Identifier); 1969 if (Index != -1) { 1970 Operands.push_back(MipsOperand::CreateMSACtrlReg( 1971 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1972 return MatchOperand_Success; 1973 } 1974 1975 return MatchOperand_NoMatch; 1976 } 1977 1978 MipsAsmParser::OperandMatchResultTy 1979 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 1980 auto Token = Parser.getLexer().peekTok(false); 1981 1982 if (Token.is(AsmToken::Identifier)) { 1983 DEBUG(dbgs() << ".. identifier\n"); 1984 StringRef Identifier = Token.getIdentifier(); 1985 OperandMatchResultTy ResTy = 1986 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 1987 return ResTy; 1988 } else if (Token.is(AsmToken::Integer)) { 1989 DEBUG(dbgs() << ".. integer\n"); 1990 Operands.push_back(MipsOperand::CreateNumericReg( 1991 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 1992 *this)); 1993 return MatchOperand_Success; 1994 } 1995 1996 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 1997 1998 return MatchOperand_NoMatch; 1999 } 2000 2001 MipsAsmParser::OperandMatchResultTy 2002 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) { 2003 DEBUG(dbgs() << "ParseAnyRegister\n"); 2004 2005 auto Token = Parser.getTok(); 2006 2007 SMLoc S = Token.getLoc(); 2008 2009 if (Token.isNot(AsmToken::Dollar)) { 2010 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 2011 if (Token.is(AsmToken::Identifier)) { 2012 if (searchSymbolAlias(Operands)) 2013 return MatchOperand_Success; 2014 } 2015 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 2016 return MatchOperand_NoMatch; 2017 } 2018 DEBUG(dbgs() << ".. $\n"); 2019 2020 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S); 2021 if (ResTy == MatchOperand_Success) { 2022 Parser.Lex(); // $ 2023 Parser.Lex(); // identifier 2024 } 2025 return ResTy; 2026 } 2027 2028 MipsAsmParser::OperandMatchResultTy 2029 MipsAsmParser::ParseImm(OperandVector &Operands) { 2030 switch (getLexer().getKind()) { 2031 default: 2032 return MatchOperand_NoMatch; 2033 case AsmToken::LParen: 2034 case AsmToken::Minus: 2035 case AsmToken::Plus: 2036 case AsmToken::Integer: 2037 case AsmToken::Tilde: 2038 case AsmToken::String: 2039 break; 2040 } 2041 2042 const MCExpr *IdVal; 2043 SMLoc S = Parser.getTok().getLoc(); 2044 if (getParser().parseExpression(IdVal)) 2045 return MatchOperand_ParseFail; 2046 2047 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2048 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 2049 return MatchOperand_Success; 2050 } 2051 2052 MipsAsmParser::OperandMatchResultTy 2053 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) { 2054 DEBUG(dbgs() << "ParseJumpTarget\n"); 2055 2056 SMLoc S = getLexer().getLoc(); 2057 2058 // Integers and expressions are acceptable 2059 OperandMatchResultTy ResTy = ParseImm(Operands); 2060 if (ResTy != MatchOperand_NoMatch) 2061 return ResTy; 2062 2063 // Registers are a valid target and have priority over symbols. 2064 ResTy = ParseAnyRegister(Operands); 2065 if (ResTy != MatchOperand_NoMatch) 2066 return ResTy; 2067 2068 const MCExpr *Expr = nullptr; 2069 if (Parser.parseExpression(Expr)) { 2070 // We have no way of knowing if a symbol was consumed so we must ParseFail 2071 return MatchOperand_ParseFail; 2072 } 2073 Operands.push_back( 2074 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 2075 return MatchOperand_Success; 2076 } 2077 2078 MipsAsmParser::OperandMatchResultTy 2079 MipsAsmParser::parseInvNum(OperandVector &Operands) { 2080 const MCExpr *IdVal; 2081 // If the first token is '$' we may have register operand. 2082 if (Parser.getTok().is(AsmToken::Dollar)) 2083 return MatchOperand_NoMatch; 2084 SMLoc S = Parser.getTok().getLoc(); 2085 if (getParser().parseExpression(IdVal)) 2086 return MatchOperand_ParseFail; 2087 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 2088 assert(MCE && "Unexpected MCExpr type."); 2089 int64_t Val = MCE->getValue(); 2090 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2091 Operands.push_back(MipsOperand::CreateImm( 2092 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); 2093 return MatchOperand_Success; 2094 } 2095 2096 MipsAsmParser::OperandMatchResultTy 2097 MipsAsmParser::ParseLSAImm(OperandVector &Operands) { 2098 switch (getLexer().getKind()) { 2099 default: 2100 return MatchOperand_NoMatch; 2101 case AsmToken::LParen: 2102 case AsmToken::Plus: 2103 case AsmToken::Minus: 2104 case AsmToken::Integer: 2105 break; 2106 } 2107 2108 const MCExpr *Expr; 2109 SMLoc S = Parser.getTok().getLoc(); 2110 2111 if (getParser().parseExpression(Expr)) 2112 return MatchOperand_ParseFail; 2113 2114 int64_t Val; 2115 if (!Expr->EvaluateAsAbsolute(Val)) { 2116 Error(S, "expected immediate value"); 2117 return MatchOperand_ParseFail; 2118 } 2119 2120 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 2121 // and because the CPU always adds one to the immediate field, the allowed 2122 // range becomes 1..4. We'll only check the range here and will deal 2123 // with the addition/subtraction when actually decoding/encoding 2124 // the instruction. 2125 if (Val < 1 || Val > 4) { 2126 Error(S, "immediate not in range (1..4)"); 2127 return MatchOperand_ParseFail; 2128 } 2129 2130 Operands.push_back( 2131 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 2132 return MatchOperand_Success; 2133 } 2134 2135 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 2136 2137 MCSymbolRefExpr::VariantKind VK = 2138 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 2139 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 2140 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 2141 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 2142 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 2143 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 2144 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 2145 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 2146 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 2147 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 2148 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 2149 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 2150 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 2151 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 2152 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 2153 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 2154 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 2155 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 2156 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16) 2157 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16) 2158 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16) 2159 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16) 2160 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER) 2161 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST) 2162 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16) 2163 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16) 2164 .Default(MCSymbolRefExpr::VK_None); 2165 2166 assert(VK != MCSymbolRefExpr::VK_None); 2167 2168 return VK; 2169 } 2170 2171 /// Sometimes (i.e. load/stores) the operand may be followed immediately by 2172 /// either this. 2173 /// ::= '(', register, ')' 2174 /// handle it before we iterate so we don't get tripped up by the lack of 2175 /// a comma. 2176 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) { 2177 if (getLexer().is(AsmToken::LParen)) { 2178 Operands.push_back( 2179 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 2180 Parser.Lex(); 2181 if (ParseOperand(Operands, Name)) { 2182 SMLoc Loc = getLexer().getLoc(); 2183 Parser.eatToEndOfStatement(); 2184 return Error(Loc, "unexpected token in argument list"); 2185 } 2186 if (Parser.getTok().isNot(AsmToken::RParen)) { 2187 SMLoc Loc = getLexer().getLoc(); 2188 Parser.eatToEndOfStatement(); 2189 return Error(Loc, "unexpected token, expected ')'"); 2190 } 2191 Operands.push_back( 2192 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 2193 Parser.Lex(); 2194 } 2195 return false; 2196 } 2197 2198 /// Sometimes (i.e. in MSA) the operand may be followed immediately by 2199 /// either one of these. 2200 /// ::= '[', register, ']' 2201 /// ::= '[', integer, ']' 2202 /// handle it before we iterate so we don't get tripped up by the lack of 2203 /// a comma. 2204 bool MipsAsmParser::ParseBracketSuffix(StringRef Name, 2205 OperandVector &Operands) { 2206 if (getLexer().is(AsmToken::LBrac)) { 2207 Operands.push_back( 2208 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 2209 Parser.Lex(); 2210 if (ParseOperand(Operands, Name)) { 2211 SMLoc Loc = getLexer().getLoc(); 2212 Parser.eatToEndOfStatement(); 2213 return Error(Loc, "unexpected token in argument list"); 2214 } 2215 if (Parser.getTok().isNot(AsmToken::RBrac)) { 2216 SMLoc Loc = getLexer().getLoc(); 2217 Parser.eatToEndOfStatement(); 2218 return Error(Loc, "unexpected token, expected ']'"); 2219 } 2220 Operands.push_back( 2221 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 2222 Parser.Lex(); 2223 } 2224 return false; 2225 } 2226 2227 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 2228 SMLoc NameLoc, OperandVector &Operands) { 2229 DEBUG(dbgs() << "ParseInstruction\n"); 2230 // Check if we have valid mnemonic 2231 if (!mnemonicIsValid(Name, 0)) { 2232 Parser.eatToEndOfStatement(); 2233 return Error(NameLoc, "Unknown instruction"); 2234 } 2235 // First operand in MCInst is instruction mnemonic. 2236 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 2237 2238 // Read the remaining operands. 2239 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2240 // Read the first operand. 2241 if (ParseOperand(Operands, Name)) { 2242 SMLoc Loc = getLexer().getLoc(); 2243 Parser.eatToEndOfStatement(); 2244 return Error(Loc, "unexpected token in argument list"); 2245 } 2246 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands)) 2247 return true; 2248 // AFAIK, parenthesis suffixes are never on the first operand 2249 2250 while (getLexer().is(AsmToken::Comma)) { 2251 Parser.Lex(); // Eat the comma. 2252 // Parse and remember the operand. 2253 if (ParseOperand(Operands, Name)) { 2254 SMLoc Loc = getLexer().getLoc(); 2255 Parser.eatToEndOfStatement(); 2256 return Error(Loc, "unexpected token in argument list"); 2257 } 2258 // Parse bracket and parenthesis suffixes before we iterate 2259 if (getLexer().is(AsmToken::LBrac)) { 2260 if (ParseBracketSuffix(Name, Operands)) 2261 return true; 2262 } else if (getLexer().is(AsmToken::LParen) && 2263 ParseParenSuffix(Name, Operands)) 2264 return true; 2265 } 2266 } 2267 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2268 SMLoc Loc = getLexer().getLoc(); 2269 Parser.eatToEndOfStatement(); 2270 return Error(Loc, "unexpected token in argument list"); 2271 } 2272 Parser.Lex(); // Consume the EndOfStatement. 2273 return false; 2274 } 2275 2276 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 2277 SMLoc Loc = getLexer().getLoc(); 2278 Parser.eatToEndOfStatement(); 2279 return Error(Loc, ErrorMsg); 2280 } 2281 2282 bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) { 2283 return Error(Loc, ErrorMsg); 2284 } 2285 2286 bool MipsAsmParser::parseSetNoAtDirective() { 2287 // Line should look like: ".set noat". 2288 // set at reg to 0. 2289 Options.setATReg(0); 2290 // eat noat 2291 Parser.Lex(); 2292 // If this is not the end of the statement, report an error. 2293 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2294 reportParseError("unexpected token in statement"); 2295 return false; 2296 } 2297 Parser.Lex(); // Consume the EndOfStatement. 2298 return false; 2299 } 2300 2301 bool MipsAsmParser::parseSetAtDirective() { 2302 // Line can be .set at - defaults to $1 2303 // or .set at=$reg 2304 int AtRegNo; 2305 getParser().Lex(); 2306 if (getLexer().is(AsmToken::EndOfStatement)) { 2307 Options.setATReg(1); 2308 Parser.Lex(); // Consume the EndOfStatement. 2309 return false; 2310 } else if (getLexer().is(AsmToken::Equal)) { 2311 getParser().Lex(); // Eat the '='. 2312 if (getLexer().isNot(AsmToken::Dollar)) { 2313 reportParseError("unexpected token in statement"); 2314 return false; 2315 } 2316 Parser.Lex(); // Eat the '$'. 2317 const AsmToken &Reg = Parser.getTok(); 2318 if (Reg.is(AsmToken::Identifier)) { 2319 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 2320 } else if (Reg.is(AsmToken::Integer)) { 2321 AtRegNo = Reg.getIntVal(); 2322 } else { 2323 reportParseError("unexpected token in statement"); 2324 return false; 2325 } 2326 2327 if (AtRegNo < 0 || AtRegNo > 31) { 2328 reportParseError("unexpected token in statement"); 2329 return false; 2330 } 2331 2332 if (!Options.setATReg(AtRegNo)) { 2333 reportParseError("unexpected token in statement"); 2334 return false; 2335 } 2336 getParser().Lex(); // Eat the register. 2337 2338 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2339 reportParseError("unexpected token in statement"); 2340 return false; 2341 } 2342 Parser.Lex(); // Consume the EndOfStatement. 2343 return false; 2344 } else { 2345 reportParseError("unexpected token in statement"); 2346 return false; 2347 } 2348 } 2349 2350 bool MipsAsmParser::parseSetReorderDirective() { 2351 Parser.Lex(); 2352 // If this is not the end of the statement, report an error. 2353 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2354 reportParseError("unexpected token in statement"); 2355 return false; 2356 } 2357 Options.setReorder(); 2358 getTargetStreamer().emitDirectiveSetReorder(); 2359 Parser.Lex(); // Consume the EndOfStatement. 2360 return false; 2361 } 2362 2363 bool MipsAsmParser::parseSetNoReorderDirective() { 2364 Parser.Lex(); 2365 // If this is not the end of the statement, report an error. 2366 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2367 reportParseError("unexpected token in statement"); 2368 return false; 2369 } 2370 Options.setNoreorder(); 2371 getTargetStreamer().emitDirectiveSetNoReorder(); 2372 Parser.Lex(); // Consume the EndOfStatement. 2373 return false; 2374 } 2375 2376 bool MipsAsmParser::parseSetMacroDirective() { 2377 Parser.Lex(); 2378 // If this is not the end of the statement, report an error. 2379 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2380 reportParseError("unexpected token in statement"); 2381 return false; 2382 } 2383 Options.setMacro(); 2384 Parser.Lex(); // Consume the EndOfStatement. 2385 return false; 2386 } 2387 2388 bool MipsAsmParser::parseSetNoMacroDirective() { 2389 Parser.Lex(); 2390 // If this is not the end of the statement, report an error. 2391 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2392 reportParseError("`noreorder' must be set before `nomacro'"); 2393 return false; 2394 } 2395 if (Options.isReorder()) { 2396 reportParseError("`noreorder' must be set before `nomacro'"); 2397 return false; 2398 } 2399 Options.setNomacro(); 2400 Parser.Lex(); // Consume the EndOfStatement. 2401 return false; 2402 } 2403 2404 bool MipsAsmParser::parseSetNoMips16Directive() { 2405 Parser.Lex(); 2406 // If this is not the end of the statement, report an error. 2407 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2408 reportParseError("unexpected token in statement"); 2409 return false; 2410 } 2411 // For now do nothing. 2412 Parser.Lex(); // Consume the EndOfStatement. 2413 return false; 2414 } 2415 2416 bool MipsAsmParser::parseSetAssignment() { 2417 StringRef Name; 2418 const MCExpr *Value; 2419 2420 if (Parser.parseIdentifier(Name)) 2421 reportParseError("expected identifier after .set"); 2422 2423 if (getLexer().isNot(AsmToken::Comma)) 2424 return reportParseError("unexpected token in .set directive"); 2425 Lex(); // Eat comma 2426 2427 if (Parser.parseExpression(Value)) 2428 return reportParseError("expected valid expression after comma"); 2429 2430 // Check if the Name already exists as a symbol. 2431 MCSymbol *Sym = getContext().LookupSymbol(Name); 2432 if (Sym) 2433 return reportParseError("symbol already defined"); 2434 Sym = getContext().GetOrCreateSymbol(Name); 2435 Sym->setVariableValue(Value); 2436 2437 return false; 2438 } 2439 2440 bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 2441 Parser.Lex(); 2442 if (getLexer().isNot(AsmToken::EndOfStatement)) 2443 return reportParseError("unexpected token in .set directive"); 2444 2445 switch (Feature) { 2446 default: 2447 llvm_unreachable("Unimplemented feature"); 2448 case Mips::FeatureDSP: 2449 setFeatureBits(Mips::FeatureDSP, "dsp"); 2450 getTargetStreamer().emitDirectiveSetDsp(); 2451 break; 2452 case Mips::FeatureMicroMips: 2453 getTargetStreamer().emitDirectiveSetMicroMips(); 2454 break; 2455 case Mips::FeatureMips16: 2456 getTargetStreamer().emitDirectiveSetMips16(); 2457 break; 2458 case Mips::FeatureMips32r2: 2459 setFeatureBits(Mips::FeatureMips32r2, "mips32r2"); 2460 getTargetStreamer().emitDirectiveSetMips32R2(); 2461 break; 2462 case Mips::FeatureMips64: 2463 setFeatureBits(Mips::FeatureMips64, "mips64"); 2464 getTargetStreamer().emitDirectiveSetMips64(); 2465 break; 2466 case Mips::FeatureMips64r2: 2467 setFeatureBits(Mips::FeatureMips64r2, "mips64r2"); 2468 getTargetStreamer().emitDirectiveSetMips64R2(); 2469 break; 2470 } 2471 return false; 2472 } 2473 2474 bool MipsAsmParser::eatComma(StringRef ErrorStr) { 2475 if (getLexer().isNot(AsmToken::Comma)) { 2476 SMLoc Loc = getLexer().getLoc(); 2477 Parser.eatToEndOfStatement(); 2478 return Error(Loc, ErrorStr); 2479 } 2480 2481 Parser.Lex(); // Eat the comma. 2482 return true; 2483 } 2484 2485 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) { 2486 if (Options.isReorder()) 2487 Warning(Loc, ".cpload in reorder section"); 2488 2489 // FIXME: Warn if cpload is used in Mips16 mode. 2490 2491 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 2492 OperandMatchResultTy ResTy = ParseAnyRegister(Reg); 2493 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 2494 reportParseError("expected register containing function address"); 2495 return false; 2496 } 2497 2498 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 2499 if (!RegOpnd.isGPRAsmReg()) { 2500 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 2501 return false; 2502 } 2503 2504 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg()); 2505 return false; 2506 } 2507 2508 bool MipsAsmParser::parseDirectiveCPSetup() { 2509 unsigned FuncReg; 2510 unsigned Save; 2511 bool SaveIsReg = true; 2512 2513 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 2514 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg); 2515 if (ResTy == MatchOperand_NoMatch) { 2516 reportParseError("expected register containing function address"); 2517 Parser.eatToEndOfStatement(); 2518 return false; 2519 } 2520 2521 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 2522 if (!FuncRegOpnd.isGPRAsmReg()) { 2523 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 2524 Parser.eatToEndOfStatement(); 2525 return false; 2526 } 2527 2528 FuncReg = FuncRegOpnd.getGPR32Reg(); 2529 TmpReg.clear(); 2530 2531 if (!eatComma("expected comma parsing directive")) 2532 return true; 2533 2534 ResTy = ParseAnyRegister(TmpReg); 2535 if (ResTy == MatchOperand_NoMatch) { 2536 const AsmToken &Tok = Parser.getTok(); 2537 if (Tok.is(AsmToken::Integer)) { 2538 Save = Tok.getIntVal(); 2539 SaveIsReg = false; 2540 Parser.Lex(); 2541 } else { 2542 reportParseError("expected save register or stack offset"); 2543 Parser.eatToEndOfStatement(); 2544 return false; 2545 } 2546 } else { 2547 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 2548 if (!SaveOpnd.isGPRAsmReg()) { 2549 reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 2550 Parser.eatToEndOfStatement(); 2551 return false; 2552 } 2553 Save = SaveOpnd.getGPR32Reg(); 2554 } 2555 2556 if (!eatComma("expected comma parsing directive")) 2557 return true; 2558 2559 StringRef Name; 2560 if (Parser.parseIdentifier(Name)) 2561 reportParseError("expected identifier"); 2562 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2563 2564 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg); 2565 return false; 2566 } 2567 2568 bool MipsAsmParser::parseDirectiveNaN() { 2569 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2570 const AsmToken &Tok = Parser.getTok(); 2571 2572 if (Tok.getString() == "2008") { 2573 Parser.Lex(); 2574 getTargetStreamer().emitDirectiveNaN2008(); 2575 return false; 2576 } else if (Tok.getString() == "legacy") { 2577 Parser.Lex(); 2578 getTargetStreamer().emitDirectiveNaNLegacy(); 2579 return false; 2580 } 2581 } 2582 // If we don't recognize the option passed to the .nan 2583 // directive (e.g. no option or unknown option), emit an error. 2584 reportParseError("invalid option in .nan directive"); 2585 return false; 2586 } 2587 2588 bool MipsAsmParser::parseDirectiveSet() { 2589 2590 // Get the next token. 2591 const AsmToken &Tok = Parser.getTok(); 2592 2593 if (Tok.getString() == "noat") { 2594 return parseSetNoAtDirective(); 2595 } else if (Tok.getString() == "at") { 2596 return parseSetAtDirective(); 2597 } else if (Tok.getString() == "reorder") { 2598 return parseSetReorderDirective(); 2599 } else if (Tok.getString() == "noreorder") { 2600 return parseSetNoReorderDirective(); 2601 } else if (Tok.getString() == "macro") { 2602 return parseSetMacroDirective(); 2603 } else if (Tok.getString() == "nomacro") { 2604 return parseSetNoMacroDirective(); 2605 } else if (Tok.getString() == "mips16") { 2606 return parseSetFeature(Mips::FeatureMips16); 2607 } else if (Tok.getString() == "nomips16") { 2608 return parseSetNoMips16Directive(); 2609 } else if (Tok.getString() == "nomicromips") { 2610 getTargetStreamer().emitDirectiveSetNoMicroMips(); 2611 Parser.eatToEndOfStatement(); 2612 return false; 2613 } else if (Tok.getString() == "micromips") { 2614 return parseSetFeature(Mips::FeatureMicroMips); 2615 } else if (Tok.getString() == "mips32r2") { 2616 return parseSetFeature(Mips::FeatureMips32r2); 2617 } else if (Tok.getString() == "mips64") { 2618 return parseSetFeature(Mips::FeatureMips64); 2619 } else if (Tok.getString() == "mips64r2") { 2620 return parseSetFeature(Mips::FeatureMips64r2); 2621 } else if (Tok.getString() == "dsp") { 2622 return parseSetFeature(Mips::FeatureDSP); 2623 } else { 2624 // It is just an identifier, look for an assignment. 2625 parseSetAssignment(); 2626 return false; 2627 } 2628 2629 return true; 2630 } 2631 2632 /// parseDataDirective 2633 /// ::= .word [ expression (, expression)* ] 2634 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 2635 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2636 for (;;) { 2637 const MCExpr *Value; 2638 if (getParser().parseExpression(Value)) 2639 return true; 2640 2641 getParser().getStreamer().EmitValue(Value, Size); 2642 2643 if (getLexer().is(AsmToken::EndOfStatement)) 2644 break; 2645 2646 // FIXME: Improve diagnostic. 2647 if (getLexer().isNot(AsmToken::Comma)) 2648 return Error(L, "unexpected token in directive"); 2649 Parser.Lex(); 2650 } 2651 } 2652 2653 Parser.Lex(); 2654 return false; 2655 } 2656 2657 /// parseDirectiveGpWord 2658 /// ::= .gpword local_sym 2659 bool MipsAsmParser::parseDirectiveGpWord() { 2660 const MCExpr *Value; 2661 // EmitGPRel32Value requires an expression, so we are using base class 2662 // method to evaluate the expression. 2663 if (getParser().parseExpression(Value)) 2664 return true; 2665 getParser().getStreamer().EmitGPRel32Value(Value); 2666 2667 if (getLexer().isNot(AsmToken::EndOfStatement)) 2668 return Error(getLexer().getLoc(), "unexpected token in directive"); 2669 Parser.Lex(); // Eat EndOfStatement token. 2670 return false; 2671 } 2672 2673 /// parseDirectiveGpDWord 2674 /// ::= .gpdword local_sym 2675 bool MipsAsmParser::parseDirectiveGpDWord() { 2676 const MCExpr *Value; 2677 // EmitGPRel64Value requires an expression, so we are using base class 2678 // method to evaluate the expression. 2679 if (getParser().parseExpression(Value)) 2680 return true; 2681 getParser().getStreamer().EmitGPRel64Value(Value); 2682 2683 if (getLexer().isNot(AsmToken::EndOfStatement)) 2684 return Error(getLexer().getLoc(), "unexpected token in directive"); 2685 Parser.Lex(); // Eat EndOfStatement token. 2686 return false; 2687 } 2688 2689 bool MipsAsmParser::parseDirectiveOption() { 2690 // Get the option token. 2691 AsmToken Tok = Parser.getTok(); 2692 // At the moment only identifiers are supported. 2693 if (Tok.isNot(AsmToken::Identifier)) { 2694 Error(Parser.getTok().getLoc(), "unexpected token in .option directive"); 2695 Parser.eatToEndOfStatement(); 2696 return false; 2697 } 2698 2699 StringRef Option = Tok.getIdentifier(); 2700 2701 if (Option == "pic0") { 2702 getTargetStreamer().emitDirectiveOptionPic0(); 2703 Parser.Lex(); 2704 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2705 Error(Parser.getTok().getLoc(), 2706 "unexpected token in .option pic0 directive"); 2707 Parser.eatToEndOfStatement(); 2708 } 2709 return false; 2710 } 2711 2712 if (Option == "pic2") { 2713 getTargetStreamer().emitDirectiveOptionPic2(); 2714 Parser.Lex(); 2715 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2716 Error(Parser.getTok().getLoc(), 2717 "unexpected token in .option pic2 directive"); 2718 Parser.eatToEndOfStatement(); 2719 } 2720 return false; 2721 } 2722 2723 // Unknown option. 2724 Warning(Parser.getTok().getLoc(), "unknown option in .option directive"); 2725 Parser.eatToEndOfStatement(); 2726 return false; 2727 } 2728 2729 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 2730 StringRef IDVal = DirectiveID.getString(); 2731 2732 if (IDVal == ".cpload") 2733 return parseDirectiveCPLoad(DirectiveID.getLoc()); 2734 if (IDVal == ".dword") { 2735 parseDataDirective(8, DirectiveID.getLoc()); 2736 return false; 2737 } 2738 2739 if (IDVal == ".ent") { 2740 // Ignore this directive for now. 2741 Parser.Lex(); 2742 return false; 2743 } 2744 2745 if (IDVal == ".end") { 2746 // Ignore this directive for now. 2747 Parser.Lex(); 2748 return false; 2749 } 2750 2751 if (IDVal == ".frame") { 2752 // Ignore this directive for now. 2753 Parser.eatToEndOfStatement(); 2754 return false; 2755 } 2756 2757 if (IDVal == ".set") { 2758 return parseDirectiveSet(); 2759 } 2760 2761 if (IDVal == ".fmask") { 2762 // Ignore this directive for now. 2763 Parser.eatToEndOfStatement(); 2764 return false; 2765 } 2766 2767 if (IDVal == ".mask") { 2768 // Ignore this directive for now. 2769 Parser.eatToEndOfStatement(); 2770 return false; 2771 } 2772 2773 if (IDVal == ".nan") 2774 return parseDirectiveNaN(); 2775 2776 if (IDVal == ".gpword") { 2777 parseDirectiveGpWord(); 2778 return false; 2779 } 2780 2781 if (IDVal == ".gpdword") { 2782 parseDirectiveGpDWord(); 2783 return false; 2784 } 2785 2786 if (IDVal == ".word") { 2787 parseDataDirective(4, DirectiveID.getLoc()); 2788 return false; 2789 } 2790 2791 if (IDVal == ".option") 2792 return parseDirectiveOption(); 2793 2794 if (IDVal == ".abicalls") { 2795 getTargetStreamer().emitDirectiveAbiCalls(); 2796 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2797 Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2798 // Clear line 2799 Parser.eatToEndOfStatement(); 2800 } 2801 return false; 2802 } 2803 2804 if (IDVal == ".cpsetup") 2805 return parseDirectiveCPSetup(); 2806 2807 return true; 2808 } 2809 2810 extern "C" void LLVMInitializeMipsAsmParser() { 2811 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 2812 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 2813 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 2814 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 2815 } 2816 2817 #define GET_REGISTER_MATCHER 2818 #define GET_MATCHER_IMPLEMENTATION 2819 #include "MipsGenAsmMatcher.inc" 2820