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