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