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