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