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 25 using namespace llvm; 26 27 namespace { 28 class MipsAssemblerOptions { 29 public: 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 45 private: 46 unsigned aTReg; 47 bool reorder; 48 bool macro; 49 }; 50 } 51 52 namespace { 53 class 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); 193 public: 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 206 namespace { 207 208 /// MipsOperand - Instances of this class represent a parsed Mips machine 209 /// instruction. 210 class MipsOperand : public MCParsedAsmOperand { 211 212 public: 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 225 private: 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 266 public: 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 420 namespace llvm { 421 extern const MCInstrDesc MipsInsts[]; 422 } 423 static const MCInstrDesc &getInstDesc(unsigned Opcode) { 424 return MipsInsts[Opcode]; 425 } 426 427 bool 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 486 bool 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 498 void 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 510 void 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 554 void 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 596 void 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 629 void 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 710 bool MipsAsmParser:: 711 MatchAndEmitInstruction(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 752 int 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 812 int 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 837 int 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 850 void MipsAsmParser::setDefaultFpFormat() { 851 852 if (isMips64() || isFP64()) 853 FpFormat = FP_FORMAT_D; 854 else 855 FpFormat = FP_FORMAT_S; 856 } 857 858 void 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 868 bool MipsAssemblerOptions::setATReg(unsigned Reg) { 869 if (Reg > 31) 870 return false; 871 872 aTReg = Reg; 873 return true; 874 } 875 876 int MipsAsmParser::getATReg() { 877 return Options.getATRegNum(); 878 } 879 880 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 881 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 882 } 883 884 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 885 886 if (RegNum > 31) 887 return -1; 888 889 return getReg(RegClass, RegNum); 890 } 891 892 int 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 905 bool 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 921 bool 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 1016 const 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 1064 bool 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 1085 bool 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 1127 bool 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 1135 bool 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 1163 MipsAsmParser::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 1253 MipsAsmParser::OperandMatchResultTy 1254 MipsAsmParser::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 return MatchOperand_Success; 1272 } 1273 return MatchOperand_NoMatch; 1274 } 1275 1276 MipsAsmParser::OperandMatchResultTy 1277 MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1278 1279 if (!isMips64()) 1280 return MatchOperand_NoMatch; 1281 return parseRegs(Operands, (int) MipsOperand::Kind_CPU64Regs); 1282 } 1283 1284 MipsAsmParser::OperandMatchResultTy 1285 MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1286 return parseRegs(Operands, (int) MipsOperand::Kind_CPURegs); 1287 } 1288 1289 MipsAsmParser::OperandMatchResultTy 1290 MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1291 1292 if (isFP64()) 1293 return MatchOperand_NoMatch; 1294 // Double operand is expected, set appropriate format 1295 setFpFormat(FP_FORMAT_D); 1296 1297 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs); 1298 } 1299 1300 MipsAsmParser::OperandMatchResultTy 1301 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1302 if (!isFP64()) 1303 return MatchOperand_NoMatch; 1304 // Double operand is expected, set appropriate format 1305 setFpFormat(FP_FORMAT_D); 1306 1307 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs); 1308 } 1309 1310 MipsAsmParser::OperandMatchResultTy 1311 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1312 // Single operand is expected, set appropriate format 1313 setFpFormat(FP_FORMAT_S); 1314 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs); 1315 } 1316 1317 bool MipsAsmParser::searchSymbolAlias( 1318 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) { 1319 1320 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1321 if (Sym) { 1322 SMLoc S = Parser.getTok().getLoc(); 1323 const MCExpr *Expr; 1324 if (Sym->isVariable()) 1325 Expr = Sym->getVariableValue(); 1326 else 1327 return false; 1328 if (Expr->getKind() == MCExpr::SymbolRef) { 1329 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind; 1330 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1331 const StringRef DefSymbol = Ref->getSymbol().getName(); 1332 if (DefSymbol.startswith("$")) { 1333 int RegNum = -1; 1334 APInt IntVal(32, -1); 1335 if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) 1336 RegNum = matchRegisterByNumber(IntVal.getZExtValue(), 1337 isMips64() 1338 ? Mips::CPU64RegsRegClassID 1339 : Mips::CPURegsRegClassID); 1340 else { 1341 // Lookup for the register with the corresponding name. 1342 switch (Kind) { 1343 case MipsOperand::Kind_AFGR64Regs: 1344 case MipsOperand::Kind_FGR64Regs: 1345 RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_D); 1346 break; 1347 case MipsOperand::Kind_FGR32Regs: 1348 RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S); 1349 break; 1350 case MipsOperand::Kind_CPU64Regs: 1351 case MipsOperand::Kind_CPURegs: 1352 default: 1353 RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); 1354 break; 1355 } 1356 } 1357 if (RegNum > -1) { 1358 Parser.Lex(); 1359 MipsOperand *op = MipsOperand::CreateReg(RegNum, S, 1360 Parser.getTok().getLoc()); 1361 op->setRegKind(Kind); 1362 Operands.push_back(op); 1363 return true; 1364 } 1365 } 1366 } else if (Expr->getKind() == MCExpr::Constant) { 1367 Parser.Lex(); 1368 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 1369 MipsOperand *op = MipsOperand::CreateImm(Const, S, 1370 Parser.getTok().getLoc()); 1371 Operands.push_back(op); 1372 return true; 1373 } 1374 } 1375 return false; 1376 } 1377 1378 MipsAsmParser::OperandMatchResultTy 1379 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1380 1381 if (isMips64()) 1382 return MatchOperand_NoMatch; 1383 1384 // If the first token is not '$' we have error. 1385 if (Parser.getTok().isNot(AsmToken::Dollar)) 1386 return MatchOperand_NoMatch; 1387 SMLoc S = Parser.getTok().getLoc(); 1388 Parser.Lex(); // Eat the '$'. 1389 1390 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1391 if (Tok.isNot(AsmToken::Integer)) 1392 return MatchOperand_NoMatch; 1393 1394 unsigned RegNum = Tok.getIntVal(); 1395 // At the moment only hwreg29 is supported. 1396 if (RegNum != 29) 1397 return MatchOperand_ParseFail; 1398 1399 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 1400 Parser.getTok().getLoc()); 1401 op->setRegKind(MipsOperand::Kind_HWRegs); 1402 Operands.push_back(op); 1403 1404 Parser.Lex(); // Eat the register number. 1405 return MatchOperand_Success; 1406 } 1407 1408 MipsAsmParser::OperandMatchResultTy 1409 MipsAsmParser::parseHW64Regs( 1410 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1411 1412 if (!isMips64()) 1413 return MatchOperand_NoMatch; 1414 // If the first token is not '$' we have an error. 1415 if (Parser.getTok().isNot(AsmToken::Dollar)) 1416 return MatchOperand_NoMatch; 1417 SMLoc S = Parser.getTok().getLoc(); 1418 Parser.Lex(); // Eat $ 1419 1420 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1421 if (Tok.isNot(AsmToken::Integer)) 1422 return MatchOperand_NoMatch; 1423 1424 unsigned RegNum = Tok.getIntVal(); 1425 // At the moment only hwreg29 is supported. 1426 if (RegNum != 29) 1427 return MatchOperand_ParseFail; 1428 1429 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 1430 Parser.getTok().getLoc()); 1431 op->setRegKind(MipsOperand::Kind_HW64Regs); 1432 Operands.push_back(op); 1433 1434 Parser.Lex(); // Eat the register number. 1435 return MatchOperand_Success; 1436 } 1437 1438 MipsAsmParser::OperandMatchResultTy 1439 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1440 unsigned RegNum; 1441 // If the first token is not '$' we have an error. 1442 if (Parser.getTok().isNot(AsmToken::Dollar)) 1443 return MatchOperand_NoMatch; 1444 SMLoc S = Parser.getTok().getLoc(); 1445 Parser.Lex(); // Eat the '$' 1446 1447 const AsmToken &Tok = Parser.getTok(); // Get next token. 1448 if (Tok.is(AsmToken::Integer)) { 1449 RegNum = Tok.getIntVal(); 1450 // At the moment only fcc0 is supported. 1451 if (RegNum != 0) 1452 return MatchOperand_ParseFail; 1453 } else if (Tok.is(AsmToken::Identifier)) { 1454 // At the moment only fcc0 is supported. 1455 if (Tok.getIdentifier() != "fcc0") 1456 return MatchOperand_ParseFail; 1457 } else 1458 return MatchOperand_NoMatch; 1459 1460 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 1461 Parser.getTok().getLoc()); 1462 op->setRegKind(MipsOperand::Kind_CCRRegs); 1463 Operands.push_back(op); 1464 1465 Parser.Lex(); // Eat the register number. 1466 return MatchOperand_Success; 1467 } 1468 1469 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1470 1471 MCSymbolRefExpr::VariantKind VK 1472 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1473 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1474 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1475 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1476 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1477 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1478 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1479 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1480 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1481 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1482 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1483 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1484 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1485 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1486 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1487 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1488 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1489 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1490 .Default(MCSymbolRefExpr::VK_None); 1491 1492 return VK; 1493 } 1494 1495 bool MipsAsmParser:: 1496 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1497 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1498 // First operand in MCInst is instruction mnemonic. 1499 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1500 1501 // Read the remaining operands. 1502 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1503 // Read the first operand. 1504 if (ParseOperand(Operands, Name)) { 1505 SMLoc Loc = getLexer().getLoc(); 1506 Parser.eatToEndOfStatement(); 1507 return Error(Loc, "unexpected token in argument list"); 1508 } 1509 1510 while (getLexer().is(AsmToken::Comma)) { 1511 Parser.Lex(); // Eat the comma. 1512 // Parse and remember the operand. 1513 if (ParseOperand(Operands, Name)) { 1514 SMLoc Loc = getLexer().getLoc(); 1515 Parser.eatToEndOfStatement(); 1516 return Error(Loc, "unexpected token in argument list"); 1517 } 1518 } 1519 } 1520 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1521 SMLoc Loc = getLexer().getLoc(); 1522 Parser.eatToEndOfStatement(); 1523 return Error(Loc, "unexpected token in argument list"); 1524 } 1525 Parser.Lex(); // Consume the EndOfStatement. 1526 return false; 1527 } 1528 1529 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1530 SMLoc Loc = getLexer().getLoc(); 1531 Parser.eatToEndOfStatement(); 1532 return Error(Loc, ErrorMsg); 1533 } 1534 1535 bool MipsAsmParser::parseSetNoAtDirective() { 1536 // Line should look like: ".set noat". 1537 // set at reg to 0. 1538 Options.setATReg(0); 1539 // eat noat 1540 Parser.Lex(); 1541 // If this is not the end of the statement, report an error. 1542 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1543 reportParseError("unexpected token in statement"); 1544 return false; 1545 } 1546 Parser.Lex(); // Consume the EndOfStatement. 1547 return false; 1548 } 1549 1550 bool MipsAsmParser::parseSetAtDirective() { 1551 // Line can be .set at - defaults to $1 1552 // or .set at=$reg 1553 int AtRegNo; 1554 getParser().Lex(); 1555 if (getLexer().is(AsmToken::EndOfStatement)) { 1556 Options.setATReg(1); 1557 Parser.Lex(); // Consume the EndOfStatement. 1558 return false; 1559 } else if (getLexer().is(AsmToken::Equal)) { 1560 getParser().Lex(); // Eat the '='. 1561 if (getLexer().isNot(AsmToken::Dollar)) { 1562 reportParseError("unexpected token in statement"); 1563 return false; 1564 } 1565 Parser.Lex(); // Eat the '$'. 1566 const AsmToken &Reg = Parser.getTok(); 1567 if (Reg.is(AsmToken::Identifier)) { 1568 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 1569 } else if (Reg.is(AsmToken::Integer)) { 1570 AtRegNo = Reg.getIntVal(); 1571 } else { 1572 reportParseError("unexpected token in statement"); 1573 return false; 1574 } 1575 1576 if (AtRegNo < 1 || AtRegNo > 31) { 1577 reportParseError("unexpected token in statement"); 1578 return false; 1579 } 1580 1581 if (!Options.setATReg(AtRegNo)) { 1582 reportParseError("unexpected token in statement"); 1583 return false; 1584 } 1585 getParser().Lex(); // Eat the register. 1586 1587 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1588 reportParseError("unexpected token in statement"); 1589 return false; 1590 } 1591 Parser.Lex(); // Consume the EndOfStatement. 1592 return false; 1593 } else { 1594 reportParseError("unexpected token in statement"); 1595 return false; 1596 } 1597 } 1598 1599 bool MipsAsmParser::parseSetReorderDirective() { 1600 Parser.Lex(); 1601 // If this is not the end of the statement, report an error. 1602 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1603 reportParseError("unexpected token in statement"); 1604 return false; 1605 } 1606 Options.setReorder(); 1607 Parser.Lex(); // Consume the EndOfStatement. 1608 return false; 1609 } 1610 1611 bool MipsAsmParser::parseSetNoReorderDirective() { 1612 Parser.Lex(); 1613 // If this is not the end of the statement, report an error. 1614 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1615 reportParseError("unexpected token in statement"); 1616 return false; 1617 } 1618 Options.setNoreorder(); 1619 Parser.Lex(); // Consume the EndOfStatement. 1620 return false; 1621 } 1622 1623 bool MipsAsmParser::parseSetMacroDirective() { 1624 Parser.Lex(); 1625 // If this is not the end of the statement, report an error. 1626 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1627 reportParseError("unexpected token in statement"); 1628 return false; 1629 } 1630 Options.setMacro(); 1631 Parser.Lex(); // Consume the EndOfStatement. 1632 return false; 1633 } 1634 1635 bool MipsAsmParser::parseSetNoMacroDirective() { 1636 Parser.Lex(); 1637 // If this is not the end of the statement, report an error. 1638 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1639 reportParseError("`noreorder' must be set before `nomacro'"); 1640 return false; 1641 } 1642 if (Options.isReorder()) { 1643 reportParseError("`noreorder' must be set before `nomacro'"); 1644 return false; 1645 } 1646 Options.setNomacro(); 1647 Parser.Lex(); // Consume the EndOfStatement. 1648 return false; 1649 } 1650 1651 bool MipsAsmParser::parseSetAssignment() { 1652 StringRef Name; 1653 const MCExpr *Value; 1654 1655 if (Parser.parseIdentifier(Name)) 1656 reportParseError("expected identifier after .set"); 1657 1658 if (getLexer().isNot(AsmToken::Comma)) 1659 return reportParseError("unexpected token in .set directive"); 1660 Lex(); // Eat comma 1661 1662 if (getLexer().is(AsmToken::Dollar)) { 1663 MCSymbol *Symbol; 1664 SMLoc DollarLoc = getLexer().getLoc(); 1665 // Consume the dollar sign, and check for a following identifier. 1666 Parser.Lex(); 1667 // We have a '$' followed by something, make sure they are adjacent. 1668 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1669 return true; 1670 StringRef Res = StringRef(DollarLoc.getPointer(), 1671 getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); 1672 Symbol = getContext().GetOrCreateSymbol(Res); 1673 Parser.Lex(); 1674 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 1675 getContext()); 1676 } else if (Parser.parseExpression(Value)) 1677 return reportParseError("expected valid expression after comma"); 1678 1679 // Check if the Name already exists as a symbol. 1680 MCSymbol *Sym = getContext().LookupSymbol(Name); 1681 if (Sym) 1682 return reportParseError("symbol already defined"); 1683 Sym = getContext().GetOrCreateSymbol(Name); 1684 Sym->setVariableValue(Value); 1685 1686 return false; 1687 } 1688 1689 bool MipsAsmParser::parseDirectiveSet() { 1690 1691 // Get the next token. 1692 const AsmToken &Tok = Parser.getTok(); 1693 1694 if (Tok.getString() == "noat") { 1695 return parseSetNoAtDirective(); 1696 } else if (Tok.getString() == "at") { 1697 return parseSetAtDirective(); 1698 } else if (Tok.getString() == "reorder") { 1699 return parseSetReorderDirective(); 1700 } else if (Tok.getString() == "noreorder") { 1701 return parseSetNoReorderDirective(); 1702 } else if (Tok.getString() == "macro") { 1703 return parseSetMacroDirective(); 1704 } else if (Tok.getString() == "nomacro") { 1705 return parseSetNoMacroDirective(); 1706 } else if (Tok.getString() == "nomips16") { 1707 // Ignore this directive for now. 1708 Parser.eatToEndOfStatement(); 1709 return false; 1710 } else if (Tok.getString() == "nomicromips") { 1711 // Ignore this directive for now. 1712 Parser.eatToEndOfStatement(); 1713 return false; 1714 } else { 1715 // It is just an identifier, look for an assignment. 1716 parseSetAssignment(); 1717 return false; 1718 } 1719 1720 return true; 1721 } 1722 1723 /// parseDirectiveWord 1724 /// ::= .word [ expression (, expression)* ] 1725 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1726 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1727 for (;;) { 1728 const MCExpr *Value; 1729 if (getParser().parseExpression(Value)) 1730 return true; 1731 1732 getParser().getStreamer().EmitValue(Value, Size); 1733 1734 if (getLexer().is(AsmToken::EndOfStatement)) 1735 break; 1736 1737 // FIXME: Improve diagnostic. 1738 if (getLexer().isNot(AsmToken::Comma)) 1739 return Error(L, "unexpected token in directive"); 1740 Parser.Lex(); 1741 } 1742 } 1743 1744 Parser.Lex(); 1745 return false; 1746 } 1747 1748 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1749 1750 StringRef IDVal = DirectiveID.getString(); 1751 1752 if (IDVal == ".ent") { 1753 // Ignore this directive for now. 1754 Parser.Lex(); 1755 return false; 1756 } 1757 1758 if (IDVal == ".end") { 1759 // Ignore this directive for now. 1760 Parser.Lex(); 1761 return false; 1762 } 1763 1764 if (IDVal == ".frame") { 1765 // Ignore this directive for now. 1766 Parser.eatToEndOfStatement(); 1767 return false; 1768 } 1769 1770 if (IDVal == ".set") { 1771 return parseDirectiveSet(); 1772 } 1773 1774 if (IDVal == ".fmask") { 1775 // Ignore this directive for now. 1776 Parser.eatToEndOfStatement(); 1777 return false; 1778 } 1779 1780 if (IDVal == ".mask") { 1781 // Ignore this directive for now. 1782 Parser.eatToEndOfStatement(); 1783 return false; 1784 } 1785 1786 if (IDVal == ".gpword") { 1787 // Ignore this directive for now. 1788 Parser.eatToEndOfStatement(); 1789 return false; 1790 } 1791 1792 if (IDVal == ".word") { 1793 parseDirectiveWord(4, DirectiveID.getLoc()); 1794 return false; 1795 } 1796 1797 return true; 1798 } 1799 1800 extern "C" void LLVMInitializeMipsAsmParser() { 1801 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1802 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1803 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1804 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1805 } 1806 1807 #define GET_REGISTER_MATCHER 1808 #define GET_MATCHER_IMPLEMENTATION 1809 #include "MipsGenAsmMatcher.inc" 1810