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