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