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