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