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