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