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