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