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