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