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 24 using namespace llvm; 25 26 namespace { 27 class MipsAssemblerOptions { 28 public: 29 MipsAssemblerOptions(): 30 aTReg(1), reorder(true), macro(true) { 31 } 32 33 unsigned getATRegNum() {return aTReg;} 34 bool setATReg(unsigned Reg); 35 36 bool isReorder() {return reorder;} 37 void setReorder() {reorder = true;} 38 void setNoreorder() {reorder = false;} 39 40 bool isMacro() {return macro;} 41 void setMacro() {macro = true;} 42 void setNomacro() {macro = false;} 43 44 private: 45 unsigned aTReg; 46 bool reorder; 47 bool macro; 48 }; 49 } 50 51 namespace { 52 class MipsAsmParser : public MCTargetAsmParser { 53 54 enum FpFormatTy { 55 FP_FORMAT_NONE = -1, 56 FP_FORMAT_S, 57 FP_FORMAT_D, 58 FP_FORMAT_L, 59 FP_FORMAT_W 60 } FpFormat; 61 62 MCSubtargetInfo &STI; 63 MCAsmParser &Parser; 64 MipsAssemblerOptions Options; 65 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 parseMathOperation(StringRef Name, SMLoc NameLoc, 82 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 83 84 bool ParseDirective(AsmToken DirectiveID); 85 86 MipsAsmParser::OperandMatchResultTy 87 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*>&); 88 89 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 90 StringRef Mnemonic); 91 92 int tryParseRegister(StringRef Mnemonic); 93 94 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 95 StringRef Mnemonic); 96 97 bool needsExpansion(MCInst &Inst); 98 99 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 100 SmallVectorImpl<MCInst> &Instructions); 101 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 102 SmallVectorImpl<MCInst> &Instructions); 103 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 104 SmallVectorImpl<MCInst> &Instructions); 105 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 106 SmallVectorImpl<MCInst> &Instructions); 107 bool reportParseError(StringRef ErrorMsg); 108 109 bool parseMemOffset(const MCExpr *&Res); 110 bool parseRelocOperand(const MCExpr *&Res, SMLoc &E); 111 112 bool parseDirectiveSet(); 113 114 bool parseSetAtDirective(); 115 bool parseSetNoAtDirective(); 116 bool parseSetMacroDirective(); 117 bool parseSetNoMacroDirective(); 118 bool parseSetReorderDirective(); 119 bool parseSetNoReorderDirective(); 120 121 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 122 123 bool isMips64() const { 124 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 125 } 126 127 bool isFP64() const { 128 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 129 } 130 131 int matchRegisterName(StringRef Symbol); 132 133 int matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic); 134 135 void setFpFormat(FpFormatTy Format) { 136 FpFormat = Format; 137 } 138 139 void setDefaultFpFormat(); 140 141 void setFpFormat(StringRef Format); 142 143 FpFormatTy getFpFormat() {return FpFormat;} 144 145 bool requestsDoubleOperand(StringRef Mnemonic); 146 147 unsigned getReg(int RC,int RegNo); 148 149 unsigned getATReg(); 150 public: 151 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 152 : MCTargetAsmParser(), STI(sti), Parser(parser) { 153 // Initialize the set of available features. 154 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 155 } 156 157 MCAsmParser &getParser() const { return Parser; } 158 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 159 160 }; 161 } 162 163 namespace { 164 165 /// MipsOperand - Instances of this class represent a parsed Mips machine 166 /// instruction. 167 class MipsOperand : public MCParsedAsmOperand { 168 169 enum KindTy { 170 k_CondCode, 171 k_CoprocNum, 172 k_Immediate, 173 k_Memory, 174 k_PostIndexRegister, 175 k_Register, 176 k_Token 177 } Kind; 178 179 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 180 181 union { 182 struct { 183 const char *Data; 184 unsigned Length; 185 } Tok; 186 187 struct { 188 unsigned RegNum; 189 } Reg; 190 191 struct { 192 const MCExpr *Val; 193 } Imm; 194 195 struct { 196 unsigned Base; 197 const MCExpr *Off; 198 } Mem; 199 }; 200 201 SMLoc StartLoc, EndLoc; 202 203 public: 204 void addRegOperands(MCInst &Inst, unsigned N) const { 205 assert(N == 1 && "Invalid number of operands!"); 206 Inst.addOperand(MCOperand::CreateReg(getReg())); 207 } 208 209 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 210 // Add as immediate when possible. Null MCExpr = 0. 211 if (Expr == 0) 212 Inst.addOperand(MCOperand::CreateImm(0)); 213 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 214 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 215 else 216 Inst.addOperand(MCOperand::CreateExpr(Expr)); 217 } 218 219 void addImmOperands(MCInst &Inst, unsigned N) const { 220 assert(N == 1 && "Invalid number of operands!"); 221 const MCExpr *Expr = getImm(); 222 addExpr(Inst,Expr); 223 } 224 225 void addMemOperands(MCInst &Inst, unsigned N) const { 226 assert(N == 2 && "Invalid number of operands!"); 227 228 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 229 230 const MCExpr *Expr = getMemOff(); 231 addExpr(Inst,Expr); 232 } 233 234 bool isReg() const { return Kind == k_Register; } 235 bool isImm() const { return Kind == k_Immediate; } 236 bool isToken() const { return Kind == k_Token; } 237 bool isMem() const { return Kind == k_Memory; } 238 239 StringRef getToken() const { 240 assert(Kind == k_Token && "Invalid access!"); 241 return StringRef(Tok.Data, Tok.Length); 242 } 243 244 unsigned getReg() const { 245 assert((Kind == k_Register) && "Invalid access!"); 246 return Reg.RegNum; 247 } 248 249 const MCExpr *getImm() const { 250 assert((Kind == k_Immediate) && "Invalid access!"); 251 return Imm.Val; 252 } 253 254 unsigned getMemBase() const { 255 assert((Kind == k_Memory) && "Invalid access!"); 256 return Mem.Base; 257 } 258 259 const MCExpr *getMemOff() const { 260 assert((Kind == k_Memory) && "Invalid access!"); 261 return Mem.Off; 262 } 263 264 static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 265 MipsOperand *Op = new MipsOperand(k_Token); 266 Op->Tok.Data = Str.data(); 267 Op->Tok.Length = Str.size(); 268 Op->StartLoc = S; 269 Op->EndLoc = S; 270 return Op; 271 } 272 273 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 274 MipsOperand *Op = new MipsOperand(k_Register); 275 Op->Reg.RegNum = RegNum; 276 Op->StartLoc = S; 277 Op->EndLoc = E; 278 return Op; 279 } 280 281 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 282 MipsOperand *Op = new MipsOperand(k_Immediate); 283 Op->Imm.Val = Val; 284 Op->StartLoc = S; 285 Op->EndLoc = E; 286 return Op; 287 } 288 289 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 290 SMLoc S, SMLoc E) { 291 MipsOperand *Op = new MipsOperand(k_Memory); 292 Op->Mem.Base = Base; 293 Op->Mem.Off = Off; 294 Op->StartLoc = S; 295 Op->EndLoc = E; 296 return Op; 297 } 298 299 /// getStartLoc - Get the location of the first token of this operand. 300 SMLoc getStartLoc() const { return StartLoc; } 301 /// getEndLoc - Get the location of the last token of this operand. 302 SMLoc getEndLoc() const { return EndLoc; } 303 304 virtual void print(raw_ostream &OS) const { 305 llvm_unreachable("unimplemented!"); 306 } 307 }; 308 } 309 310 bool MipsAsmParser::needsExpansion(MCInst &Inst) { 311 312 switch(Inst.getOpcode()) { 313 case Mips::LoadImm32Reg: 314 case Mips::LoadAddr32Imm: 315 case Mips::LoadAddr32Reg: 316 return true; 317 default: 318 return false; 319 } 320 } 321 322 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 323 SmallVectorImpl<MCInst> &Instructions){ 324 switch(Inst.getOpcode()) { 325 case Mips::LoadImm32Reg: 326 return expandLoadImm(Inst, IDLoc, Instructions); 327 case Mips::LoadAddr32Imm: 328 return expandLoadAddressImm(Inst,IDLoc,Instructions); 329 case Mips::LoadAddr32Reg: 330 return expandLoadAddressReg(Inst,IDLoc,Instructions); 331 } 332 } 333 334 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 335 SmallVectorImpl<MCInst> &Instructions){ 336 MCInst tmpInst; 337 const MCOperand &ImmOp = Inst.getOperand(1); 338 assert(ImmOp.isImm() && "expected immediate operand kind"); 339 const MCOperand &RegOp = Inst.getOperand(0); 340 assert(RegOp.isReg() && "expected register operand kind"); 341 342 int ImmValue = ImmOp.getImm(); 343 tmpInst.setLoc(IDLoc); 344 if ( 0 <= ImmValue && ImmValue <= 65535) { 345 // for 0 <= j <= 65535. 346 // li d,j => ori d,$zero,j 347 tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi); 348 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 349 tmpInst.addOperand( 350 MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO)); 351 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 352 Instructions.push_back(tmpInst); 353 } else if ( ImmValue < 0 && ImmValue >= -32768) { 354 // for -32768 <= j < 0. 355 // li d,j => addiu d,$zero,j 356 tmpInst.setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files? 357 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 358 tmpInst.addOperand( 359 MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO)); 360 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 361 Instructions.push_back(tmpInst); 362 } else { 363 // for any other value of j that is representable as a 32-bit integer. 364 // li d,j => lui d,hi16(j) 365 // ori d,d,lo16(j) 366 tmpInst.setOpcode(isMips64() ? Mips::LUi64 : Mips::LUi); 367 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 368 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 369 Instructions.push_back(tmpInst); 370 tmpInst.clear(); 371 tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi); 372 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 373 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 374 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 375 tmpInst.setLoc(IDLoc); 376 Instructions.push_back(tmpInst); 377 } 378 } 379 380 void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 381 SmallVectorImpl<MCInst> &Instructions){ 382 MCInst tmpInst; 383 const MCOperand &ImmOp = Inst.getOperand(2); 384 assert(ImmOp.isImm() && "expected immediate operand kind"); 385 const MCOperand &SrcRegOp = Inst.getOperand(1); 386 assert(SrcRegOp.isReg() && "expected register operand kind"); 387 const MCOperand &DstRegOp = Inst.getOperand(0); 388 assert(DstRegOp.isReg() && "expected register operand kind"); 389 int ImmValue = ImmOp.getImm(); 390 if ( -32768 <= ImmValue && ImmValue <= 65535) { 391 //for -32768 <= j <= 65535. 392 //la d,j(s) => addiu d,s,j 393 tmpInst.setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files? 394 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 395 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 396 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 397 Instructions.push_back(tmpInst); 398 } else { 399 //for any other value of j that is representable as a 32-bit integer. 400 //la d,j(s) => lui d,hi16(j) 401 // ori d,d,lo16(j) 402 // addu d,d,s 403 tmpInst.setOpcode(isMips64()?Mips::LUi64:Mips::LUi); 404 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 405 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 406 Instructions.push_back(tmpInst); 407 tmpInst.clear(); 408 tmpInst.setOpcode(isMips64()?Mips::ORi64:Mips::ORi); 409 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 410 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 411 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 412 Instructions.push_back(tmpInst); 413 tmpInst.clear(); 414 tmpInst.setOpcode(Mips::ADDu); 415 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 416 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 417 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 418 Instructions.push_back(tmpInst); 419 } 420 } 421 422 void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 423 SmallVectorImpl<MCInst> &Instructions){ 424 MCInst tmpInst; 425 const MCOperand &ImmOp = Inst.getOperand(1); 426 assert(ImmOp.isImm() && "expected immediate operand kind"); 427 const MCOperand &RegOp = Inst.getOperand(0); 428 assert(RegOp.isReg() && "expected register operand kind"); 429 int ImmValue = ImmOp.getImm(); 430 if ( -32768 <= ImmValue && ImmValue <= 65535) { 431 //for -32768 <= j <= 65535. 432 //la d,j => addiu d,$zero,j 433 tmpInst.setOpcode(Mips::ADDiu); 434 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 435 tmpInst.addOperand( 436 MCOperand::CreateReg(isMips64()?Mips::ZERO_64:Mips::ZERO)); 437 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 438 Instructions.push_back(tmpInst); 439 } else { 440 //for any other value of j that is representable as a 32-bit integer. 441 //la d,j => lui d,hi16(j) 442 // ori d,d,lo16(j) 443 tmpInst.setOpcode(isMips64()?Mips::LUi64:Mips::LUi); 444 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 445 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 446 Instructions.push_back(tmpInst); 447 tmpInst.clear(); 448 tmpInst.setOpcode(isMips64()?Mips::ORi64:Mips::ORi); 449 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 450 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 451 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 452 Instructions.push_back(tmpInst); 453 } 454 } 455 456 bool MipsAsmParser:: 457 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 458 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 459 MCStreamer &Out, unsigned &ErrorInfo, 460 bool MatchingInlineAsm) { 461 MCInst Inst; 462 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 463 MatchingInlineAsm); 464 465 switch (MatchResult) { 466 default: break; 467 case Match_Success: { 468 if (needsExpansion(Inst)) { 469 SmallVector<MCInst, 4> Instructions; 470 expandInstruction(Inst, IDLoc, Instructions); 471 for(unsigned i =0; i < Instructions.size(); i++){ 472 Out.EmitInstruction(Instructions[i]); 473 } 474 } else { 475 Inst.setLoc(IDLoc); 476 Out.EmitInstruction(Inst); 477 } 478 return false; 479 } 480 case Match_MissingFeature: 481 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 482 return true; 483 case Match_InvalidOperand: { 484 SMLoc ErrorLoc = IDLoc; 485 if (ErrorInfo != ~0U) { 486 if (ErrorInfo >= Operands.size()) 487 return Error(IDLoc, "too few operands for instruction"); 488 489 ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc(); 490 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 491 } 492 493 return Error(ErrorLoc, "invalid operand for instruction"); 494 } 495 case Match_MnemonicFail: 496 return Error(IDLoc, "invalid instruction"); 497 } 498 return true; 499 } 500 501 int MipsAsmParser::matchRegisterName(StringRef Name) { 502 503 int CC; 504 if (!isMips64()) 505 CC = StringSwitch<unsigned>(Name) 506 .Case("zero", Mips::ZERO) 507 .Case("a0", Mips::A0) 508 .Case("a1", Mips::A1) 509 .Case("a2", Mips::A2) 510 .Case("a3", Mips::A3) 511 .Case("v0", Mips::V0) 512 .Case("v1", Mips::V1) 513 .Case("s0", Mips::S0) 514 .Case("s1", Mips::S1) 515 .Case("s2", Mips::S2) 516 .Case("s3", Mips::S3) 517 .Case("s4", Mips::S4) 518 .Case("s5", Mips::S5) 519 .Case("s6", Mips::S6) 520 .Case("s7", Mips::S7) 521 .Case("k0", Mips::K0) 522 .Case("k1", Mips::K1) 523 .Case("sp", Mips::SP) 524 .Case("fp", Mips::FP) 525 .Case("gp", Mips::GP) 526 .Case("ra", Mips::RA) 527 .Case("t0", Mips::T0) 528 .Case("t1", Mips::T1) 529 .Case("t2", Mips::T2) 530 .Case("t3", Mips::T3) 531 .Case("t4", Mips::T4) 532 .Case("t5", Mips::T5) 533 .Case("t6", Mips::T6) 534 .Case("t7", Mips::T7) 535 .Case("t8", Mips::T8) 536 .Case("t9", Mips::T9) 537 .Case("at", Mips::AT) 538 .Case("fcc0", Mips::FCC0) 539 .Default(-1); 540 else 541 CC = StringSwitch<unsigned>(Name) 542 .Case("zero", Mips::ZERO_64) 543 .Case("at", Mips::AT_64) 544 .Case("v0", Mips::V0_64) 545 .Case("v1", Mips::V1_64) 546 .Case("a0", Mips::A0_64) 547 .Case("a1", Mips::A1_64) 548 .Case("a2", Mips::A2_64) 549 .Case("a3", Mips::A3_64) 550 .Case("a4", Mips::T0_64) 551 .Case("a5", Mips::T1_64) 552 .Case("a6", Mips::T2_64) 553 .Case("a7", Mips::T3_64) 554 .Case("t4", Mips::T4_64) 555 .Case("t5", Mips::T5_64) 556 .Case("t6", Mips::T6_64) 557 .Case("t7", Mips::T7_64) 558 .Case("s0", Mips::S0_64) 559 .Case("s1", Mips::S1_64) 560 .Case("s2", Mips::S2_64) 561 .Case("s3", Mips::S3_64) 562 .Case("s4", Mips::S4_64) 563 .Case("s5", Mips::S5_64) 564 .Case("s6", Mips::S6_64) 565 .Case("s7", Mips::S7_64) 566 .Case("t8", Mips::T8_64) 567 .Case("t9", Mips::T9_64) 568 .Case("kt0", Mips::K0_64) 569 .Case("kt1", Mips::K1_64) 570 .Case("gp", Mips::GP_64) 571 .Case("sp", Mips::SP_64) 572 .Case("fp", Mips::FP_64) 573 .Case("s8", Mips::FP_64) 574 .Case("ra", Mips::RA_64) 575 .Default(-1); 576 577 if (CC != -1) 578 return CC; 579 580 if (Name[0] == 'f') { 581 StringRef NumString = Name.substr(1); 582 unsigned IntVal; 583 if( NumString.getAsInteger(10, IntVal)) 584 return -1; // not integer 585 if (IntVal > 31) 586 return -1; 587 588 FpFormatTy Format = getFpFormat(); 589 590 if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 591 return getReg(Mips::FGR32RegClassID, IntVal); 592 if (Format == FP_FORMAT_D) { 593 if(isFP64()) { 594 return getReg(Mips::FGR64RegClassID, IntVal); 595 } 596 // only even numbers available as register pairs 597 if (( IntVal > 31) || (IntVal%2 != 0)) 598 return -1; 599 return getReg(Mips::AFGR64RegClassID, IntVal/2); 600 } 601 } 602 603 return -1; 604 } 605 void MipsAsmParser::setDefaultFpFormat() { 606 607 if (isMips64() || isFP64()) 608 FpFormat = FP_FORMAT_D; 609 else 610 FpFormat = FP_FORMAT_S; 611 } 612 613 bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 614 615 bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 616 .Case("ldxc1", true) 617 .Case("ldc1", true) 618 .Case("sdxc1", true) 619 .Case("sdc1", true) 620 .Default(false); 621 622 return IsDouble; 623 } 624 void MipsAsmParser::setFpFormat(StringRef Format) { 625 626 FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 627 .Case(".s", FP_FORMAT_S) 628 .Case(".d", FP_FORMAT_D) 629 .Case(".l", FP_FORMAT_L) 630 .Case(".w", FP_FORMAT_W) 631 .Default(FP_FORMAT_NONE); 632 } 633 634 bool MipsAssemblerOptions::setATReg(unsigned Reg) { 635 if (Reg > 31) 636 return false; 637 638 aTReg = Reg; 639 return true; 640 } 641 642 unsigned MipsAsmParser::getATReg() { 643 unsigned Reg = Options.getATRegNum(); 644 if (isMips64()) 645 return getReg(Mips::CPU64RegsRegClassID,Reg); 646 647 return getReg(Mips::CPURegsRegClassID,Reg); 648 } 649 650 unsigned MipsAsmParser::getReg(int RC,int RegNo) { 651 return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); 652 } 653 654 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) { 655 656 if (Mnemonic.lower() == "rdhwr") { 657 // at the moment only hwreg29 is supported 658 if (RegNum != 29) 659 return -1; 660 return Mips::HWR29; 661 } 662 663 if (RegNum > 31) 664 return -1; 665 666 // MIPS64 registers are numbered 1 after the 32-bit equivalents 667 return getReg(Mips::CPURegsRegClassID, RegNum) + isMips64(); 668 } 669 670 int MipsAsmParser::tryParseRegister(StringRef Mnemonic) { 671 const AsmToken &Tok = Parser.getTok(); 672 int RegNum = -1; 673 674 if (Tok.is(AsmToken::Identifier)) { 675 std::string lowerCase = Tok.getString().lower(); 676 RegNum = matchRegisterName(lowerCase); 677 } else if (Tok.is(AsmToken::Integer)) 678 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 679 Mnemonic.lower()); 680 else 681 return RegNum; //error 682 // 64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64 683 if (isMips64() && RegNum == Mips::ZERO_64) { 684 if (Mnemonic.find("ddiv") != StringRef::npos) 685 RegNum = Mips::ZERO; 686 } 687 return RegNum; 688 } 689 690 bool MipsAsmParser:: 691 tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 692 StringRef Mnemonic){ 693 694 SMLoc S = Parser.getTok().getLoc(); 695 SMLoc E = Parser.getTok().getEndLoc(); 696 int RegNo = -1; 697 698 // FIXME: we should make a more generic method for CCR 699 if ((Mnemonic == "cfc1" || Mnemonic == "ctc1") 700 && Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){ 701 RegNo = Parser.getTok().getIntVal(); // get the int value 702 // at the moment only fcc0 is supported 703 if (RegNo == 0) 704 RegNo = Mips::FCC0; 705 } else 706 RegNo = tryParseRegister(Mnemonic); 707 if (RegNo == -1) 708 return true; 709 710 Operands.push_back(MipsOperand::CreateReg(RegNo, S, E)); 711 Parser.Lex(); // Eat register token. 712 return false; 713 } 714 715 bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 716 StringRef Mnemonic) { 717 // Check if the current operand has a custom associated parser, if so, try to 718 // custom parse the operand, or fallback to the general approach. 719 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 720 if (ResTy == MatchOperand_Success) 721 return false; 722 // If there wasn't a custom match, try the generic matcher below. Otherwise, 723 // there was a match, but an error occurred, in which case, just return that 724 // the operand parsing failed. 725 if (ResTy == MatchOperand_ParseFail) 726 return true; 727 728 switch (getLexer().getKind()) { 729 default: 730 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 731 return true; 732 case AsmToken::Dollar: { 733 // parse register 734 SMLoc S = Parser.getTok().getLoc(); 735 Parser.Lex(); // Eat dollar token. 736 // parse register operand 737 if (!tryParseRegisterOperand(Operands, Mnemonic)) { 738 if (getLexer().is(AsmToken::LParen)) { 739 // check if it is indexed addressing operand 740 Operands.push_back(MipsOperand::CreateToken("(", S)); 741 Parser.Lex(); // eat parenthesis 742 if (getLexer().isNot(AsmToken::Dollar)) 743 return true; 744 745 Parser.Lex(); // eat dollar 746 if (tryParseRegisterOperand(Operands, Mnemonic)) 747 return true; 748 749 if (!getLexer().is(AsmToken::RParen)) 750 return true; 751 752 S = Parser.getTok().getLoc(); 753 Operands.push_back(MipsOperand::CreateToken(")", S)); 754 Parser.Lex(); 755 } 756 return false; 757 } 758 // maybe it is a symbol reference 759 StringRef Identifier; 760 if (Parser.ParseIdentifier(Identifier)) 761 return true; 762 763 SMLoc E = SMLoc::getFromPointer(Identifier.end()); 764 765 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 766 767 // Otherwise create a symbol ref. 768 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 769 getContext()); 770 771 Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 772 return false; 773 } 774 case AsmToken::Identifier: 775 case AsmToken::LParen: 776 case AsmToken::Minus: 777 case AsmToken::Plus: 778 case AsmToken::Integer: 779 case AsmToken::String: { 780 // quoted label names 781 const MCExpr *IdVal; 782 SMLoc S = Parser.getTok().getLoc(); 783 SMLoc E; 784 if (getParser().ParseExpression(IdVal, E)) 785 return true; 786 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 787 return false; 788 } 789 case AsmToken::Percent: { 790 // it is a symbol reference or constant expression 791 const MCExpr *IdVal; 792 SMLoc S = Parser.getTok().getLoc(); // start location of the operand 793 SMLoc E; 794 if (parseRelocOperand(IdVal, E)) 795 return true; 796 797 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 798 return false; 799 } // case AsmToken::Percent 800 } // switch(getLexer().getKind()) 801 return true; 802 } 803 804 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res, SMLoc &EndLoc) { 805 806 Parser.Lex(); // eat % token 807 const AsmToken &Tok = Parser.getTok(); // get next token, operation 808 if (Tok.isNot(AsmToken::Identifier)) 809 return true; 810 811 std::string Str = Tok.getIdentifier().str(); 812 813 Parser.Lex(); // eat identifier 814 // now make expression from the rest of the operand 815 const MCExpr *IdVal; 816 817 if (getLexer().getKind() == AsmToken::LParen) { 818 while (1) { 819 Parser.Lex(); // eat '(' token 820 if (getLexer().getKind() == AsmToken::Percent) { 821 Parser.Lex(); // eat % token 822 const AsmToken &nextTok = Parser.getTok(); 823 if (nextTok.isNot(AsmToken::Identifier)) 824 return true; 825 Str += "(%"; 826 Str += nextTok.getIdentifier(); 827 Parser.Lex(); // eat identifier 828 if (getLexer().getKind() != AsmToken::LParen) 829 return true; 830 } else 831 break; 832 } 833 if (getParser().ParseParenExpression(IdVal,EndLoc)) 834 return true; 835 836 while (getLexer().getKind() == AsmToken::RParen) { 837 EndLoc = Parser.getTok().getEndLoc(); 838 Parser.Lex(); // eat ')' token 839 } 840 841 } else 842 return true; // parenthesis must follow reloc operand 843 844 // Check the type of the expression 845 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) { 846 // it's a constant, evaluate lo or hi value 847 int Val = MCE->getValue(); 848 if (Str == "lo") { 849 Val = Val & 0xffff; 850 } else if (Str == "hi") { 851 Val = (Val & 0xffff0000) >> 16; 852 } 853 Res = MCConstantExpr::Create(Val, getContext()); 854 return false; 855 } 856 857 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) { 858 // it's a symbol, create symbolic expression from symbol 859 StringRef Symbol = MSRE->getSymbol().getName(); 860 MCSymbolRefExpr::VariantKind VK = getVariantKind(Str); 861 Res = MCSymbolRefExpr::Create(Symbol,VK,getContext()); 862 return false; 863 } 864 return true; 865 } 866 867 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 868 SMLoc &EndLoc) { 869 870 StartLoc = Parser.getTok().getLoc(); 871 EndLoc = Parser.getTok().getEndLoc(); 872 RegNo = tryParseRegister(""); 873 return (RegNo == (unsigned)-1); 874 } 875 876 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { 877 switch(getLexer().getKind()) { 878 default: 879 return true; 880 case AsmToken::Integer: 881 case AsmToken::Minus: 882 case AsmToken::Plus: 883 return getParser().ParseExpression(Res); 884 case AsmToken::Percent: { 885 SMLoc E; 886 return parseRelocOperand(Res, E); 887 } 888 case AsmToken::LParen: 889 return false; // it's probably assuming 0 890 } 891 return true; 892 } 893 894 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 895 SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 896 897 const MCExpr *IdVal = 0; 898 SMLoc S = Parser.getTok().getLoc(); 899 SMLoc E = Parser.getTok().getEndLoc(); 900 901 if (parseMemOffset(IdVal)) 902 return MatchOperand_ParseFail; 903 904 const AsmToken &Tok = Parser.getTok(); // get next token 905 if (Tok.isNot(AsmToken::LParen)) { 906 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 907 if (Mnemonic->getToken() == "la") { 908 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 909 return MatchOperand_Success; 910 } 911 Error(Parser.getTok().getLoc(), "'(' expected"); 912 return MatchOperand_ParseFail; 913 } 914 915 Parser.Lex(); // Eat '(' token. 916 917 const AsmToken &Tok1 = Parser.getTok(); // get next token 918 if (Tok1.is(AsmToken::Dollar)) { 919 Parser.Lex(); // Eat '$' token. 920 if (tryParseRegisterOperand(Operands,"")) { 921 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 922 return MatchOperand_ParseFail; 923 } 924 925 } else { 926 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 927 return MatchOperand_ParseFail; 928 } 929 930 const AsmToken &Tok2 = Parser.getTok(); // get next token 931 if (Tok2.isNot(AsmToken::RParen)) { 932 Error(Parser.getTok().getLoc(), "')' expected"); 933 return MatchOperand_ParseFail; 934 } 935 936 E = Parser.getTok().getEndLoc(); 937 Parser.Lex(); // Eat ')' token. 938 939 if (IdVal == 0) 940 IdVal = MCConstantExpr::Create(0, getContext()); 941 942 // now replace register operand with the mem operand 943 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 944 int RegNo = op->getReg(); 945 // remove register from operands 946 Operands.pop_back(); 947 // and add memory operand 948 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 949 delete op; 950 return MatchOperand_Success; 951 } 952 953 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 954 955 MCSymbolRefExpr::VariantKind VK 956 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 957 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 958 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 959 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 960 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 961 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 962 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 963 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 964 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 965 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 966 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 967 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 968 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 969 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 970 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 971 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 972 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 973 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 974 .Default(MCSymbolRefExpr::VK_None); 975 976 return VK; 977 } 978 979 static int ConvertCcString(StringRef CondString) { 980 int CC = StringSwitch<unsigned>(CondString) 981 .Case(".f", 0) 982 .Case(".un", 1) 983 .Case(".eq", 2) 984 .Case(".ueq", 3) 985 .Case(".olt", 4) 986 .Case(".ult", 5) 987 .Case(".ole", 6) 988 .Case(".ule", 7) 989 .Case(".sf", 8) 990 .Case(".ngle", 9) 991 .Case(".seq", 10) 992 .Case(".ngl", 11) 993 .Case(".lt", 12) 994 .Case(".nge", 13) 995 .Case(".le", 14) 996 .Case(".ngt", 15) 997 .Default(-1); 998 999 return CC; 1000 } 1001 1002 bool MipsAsmParser:: 1003 parseMathOperation(StringRef Name, SMLoc NameLoc, 1004 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1005 // split the format 1006 size_t Start = Name.find('.'), Next = Name.rfind('.'); 1007 StringRef Format1 = Name.slice(Start, Next); 1008 // and add the first format to the operands 1009 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 1010 // now for the second format 1011 StringRef Format2 = Name.slice(Next, StringRef::npos); 1012 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1013 1014 // set the format for the first register 1015 setFpFormat(Format1); 1016 1017 // Read the remaining operands. 1018 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1019 // Read the first operand. 1020 if (ParseOperand(Operands, Name)) { 1021 SMLoc Loc = getLexer().getLoc(); 1022 Parser.EatToEndOfStatement(); 1023 return Error(Loc, "unexpected token in argument list"); 1024 } 1025 1026 if (getLexer().isNot(AsmToken::Comma)) { 1027 SMLoc Loc = getLexer().getLoc(); 1028 Parser.EatToEndOfStatement(); 1029 return Error(Loc, "unexpected token in argument list"); 1030 1031 } 1032 Parser.Lex(); // Eat the comma. 1033 1034 //set the format for the first register 1035 setFpFormat(Format2); 1036 1037 // Parse and remember the operand. 1038 if (ParseOperand(Operands, Name)) { 1039 SMLoc Loc = getLexer().getLoc(); 1040 Parser.EatToEndOfStatement(); 1041 return Error(Loc, "unexpected token in argument list"); 1042 } 1043 } 1044 1045 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1046 SMLoc Loc = getLexer().getLoc(); 1047 Parser.EatToEndOfStatement(); 1048 return Error(Loc, "unexpected token in argument list"); 1049 } 1050 1051 Parser.Lex(); // Consume the EndOfStatement 1052 return false; 1053 } 1054 1055 bool MipsAsmParser:: 1056 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1057 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1058 // floating point instructions: should register be treated as double? 1059 if (requestsDoubleOperand(Name)) { 1060 setFpFormat(FP_FORMAT_D); 1061 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1062 } 1063 else { 1064 setDefaultFpFormat(); 1065 // Create the leading tokens for the mnemonic, split by '.' characters. 1066 size_t Start = 0, Next = Name.find('.'); 1067 StringRef Mnemonic = Name.slice(Start, Next); 1068 1069 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1070 1071 if (Next != StringRef::npos) { 1072 // there is a format token in mnemonic 1073 // StringRef Rest = Name.slice(Next, StringRef::npos); 1074 size_t Dot = Name.find('.', Next+1); 1075 StringRef Format = Name.slice(Next, Dot); 1076 if (Dot == StringRef::npos) //only one '.' in a string, it's a format 1077 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1078 else { 1079 if (Name.startswith("c.")){ 1080 // floating point compare, add '.' and immediate represent for cc 1081 Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1082 int Cc = ConvertCcString(Format); 1083 if (Cc == -1) { 1084 return Error(NameLoc, "Invalid conditional code"); 1085 } 1086 // FIXME: May include trailing whitespace... 1087 SMLoc E = Parser.getTok().getLoc(); 1088 Operands.push_back(MipsOperand::CreateImm( 1089 MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 1090 } else { 1091 // trunc, ceil, floor ... 1092 return parseMathOperation(Name, NameLoc, Operands); 1093 } 1094 1095 // the rest is a format 1096 Format = Name.slice(Dot, StringRef::npos); 1097 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1098 } 1099 1100 setFpFormat(Format); 1101 } 1102 } 1103 1104 // Read the remaining operands. 1105 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1106 // Read the first operand. 1107 if (ParseOperand(Operands, Name)) { 1108 SMLoc Loc = getLexer().getLoc(); 1109 Parser.EatToEndOfStatement(); 1110 return Error(Loc, "unexpected token in argument list"); 1111 } 1112 1113 while (getLexer().is(AsmToken::Comma) ) { 1114 Parser.Lex(); // Eat the comma. 1115 1116 // Parse and remember the operand. 1117 if (ParseOperand(Operands, Name)) { 1118 SMLoc Loc = getLexer().getLoc(); 1119 Parser.EatToEndOfStatement(); 1120 return Error(Loc, "unexpected token in argument list"); 1121 } 1122 } 1123 } 1124 1125 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1126 SMLoc Loc = getLexer().getLoc(); 1127 Parser.EatToEndOfStatement(); 1128 return Error(Loc, "unexpected token in argument list"); 1129 } 1130 1131 Parser.Lex(); // Consume the EndOfStatement 1132 return false; 1133 } 1134 1135 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1136 SMLoc Loc = getLexer().getLoc(); 1137 Parser.EatToEndOfStatement(); 1138 return Error(Loc, ErrorMsg); 1139 } 1140 1141 bool MipsAsmParser::parseSetNoAtDirective() { 1142 // line should look like: 1143 // .set noat 1144 // set at reg to 0 1145 Options.setATReg(0); 1146 // eat noat 1147 Parser.Lex(); 1148 // if this is not the end of the statement, report error 1149 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1150 reportParseError("unexpected token in statement"); 1151 return false; 1152 } 1153 Parser.Lex(); // Consume the EndOfStatement 1154 return false; 1155 } 1156 bool MipsAsmParser::parseSetAtDirective() { 1157 // line can be 1158 // .set at - defaults to $1 1159 // or .set at=$reg 1160 getParser().Lex(); 1161 if (getLexer().is(AsmToken::EndOfStatement)) { 1162 Options.setATReg(1); 1163 Parser.Lex(); // Consume the EndOfStatement 1164 return false; 1165 } else if (getLexer().is(AsmToken::Equal)) { 1166 getParser().Lex(); //eat '=' 1167 if (getLexer().isNot(AsmToken::Dollar)) { 1168 reportParseError("unexpected token in statement"); 1169 return false; 1170 } 1171 Parser.Lex(); // eat '$' 1172 if (getLexer().isNot(AsmToken::Integer)) { 1173 reportParseError("unexpected token in statement"); 1174 return false; 1175 } 1176 const AsmToken &Reg = Parser.getTok(); 1177 if (!Options.setATReg(Reg.getIntVal())) { 1178 reportParseError("unexpected token in statement"); 1179 return false; 1180 } 1181 getParser().Lex(); //eat reg 1182 1183 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1184 reportParseError("unexpected token in statement"); 1185 return false; 1186 } 1187 Parser.Lex(); // Consume the EndOfStatement 1188 return false; 1189 } else { 1190 reportParseError("unexpected token in statement"); 1191 return false; 1192 } 1193 } 1194 1195 bool MipsAsmParser::parseSetReorderDirective() { 1196 Parser.Lex(); 1197 // if this is not the end of the statement, report error 1198 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1199 reportParseError("unexpected token in statement"); 1200 return false; 1201 } 1202 Options.setReorder(); 1203 Parser.Lex(); // Consume the EndOfStatement 1204 return false; 1205 } 1206 1207 bool MipsAsmParser::parseSetNoReorderDirective() { 1208 Parser.Lex(); 1209 // if this is not the end of the statement, report error 1210 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1211 reportParseError("unexpected token in statement"); 1212 return false; 1213 } 1214 Options.setNoreorder(); 1215 Parser.Lex(); // Consume the EndOfStatement 1216 return false; 1217 } 1218 1219 bool MipsAsmParser::parseSetMacroDirective() { 1220 Parser.Lex(); 1221 // if this is not the end of the statement, report error 1222 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1223 reportParseError("unexpected token in statement"); 1224 return false; 1225 } 1226 Options.setMacro(); 1227 Parser.Lex(); // Consume the EndOfStatement 1228 return false; 1229 } 1230 1231 bool MipsAsmParser::parseSetNoMacroDirective() { 1232 Parser.Lex(); 1233 // if this is not the end of the statement, report error 1234 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1235 reportParseError("`noreorder' must be set before `nomacro'"); 1236 return false; 1237 } 1238 if (Options.isReorder()) { 1239 reportParseError("`noreorder' must be set before `nomacro'"); 1240 return false; 1241 } 1242 Options.setNomacro(); 1243 Parser.Lex(); // Consume the EndOfStatement 1244 return false; 1245 } 1246 bool MipsAsmParser::parseDirectiveSet() { 1247 1248 // get next token 1249 const AsmToken &Tok = Parser.getTok(); 1250 1251 if (Tok.getString() == "noat") { 1252 return parseSetNoAtDirective(); 1253 } else if (Tok.getString() == "at") { 1254 return parseSetAtDirective(); 1255 } else if (Tok.getString() == "reorder") { 1256 return parseSetReorderDirective(); 1257 } else if (Tok.getString() == "noreorder") { 1258 return parseSetNoReorderDirective(); 1259 } else if (Tok.getString() == "macro") { 1260 return parseSetMacroDirective(); 1261 } else if (Tok.getString() == "nomacro") { 1262 return parseSetNoMacroDirective(); 1263 } else if (Tok.getString() == "nomips16") { 1264 // ignore this directive for now 1265 Parser.EatToEndOfStatement(); 1266 return false; 1267 } else if (Tok.getString() == "nomicromips") { 1268 // ignore this directive for now 1269 Parser.EatToEndOfStatement(); 1270 return false; 1271 } 1272 return true; 1273 } 1274 1275 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1276 1277 if (DirectiveID.getString() == ".ent") { 1278 // ignore this directive for now 1279 Parser.Lex(); 1280 return false; 1281 } 1282 1283 if (DirectiveID.getString() == ".end") { 1284 // ignore this directive for now 1285 Parser.Lex(); 1286 return false; 1287 } 1288 1289 if (DirectiveID.getString() == ".frame") { 1290 // ignore this directive for now 1291 Parser.EatToEndOfStatement(); 1292 return false; 1293 } 1294 1295 if (DirectiveID.getString() == ".set") { 1296 return parseDirectiveSet(); 1297 } 1298 1299 if (DirectiveID.getString() == ".fmask") { 1300 // ignore this directive for now 1301 Parser.EatToEndOfStatement(); 1302 return false; 1303 } 1304 1305 if (DirectiveID.getString() == ".mask") { 1306 // ignore this directive for now 1307 Parser.EatToEndOfStatement(); 1308 return false; 1309 } 1310 1311 if (DirectiveID.getString() == ".gpword") { 1312 // ignore this directive for now 1313 Parser.EatToEndOfStatement(); 1314 return false; 1315 } 1316 1317 return true; 1318 } 1319 1320 extern "C" void LLVMInitializeMipsAsmParser() { 1321 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1322 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1323 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1324 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1325 } 1326 1327 #define GET_REGISTER_MATCHER 1328 #define GET_MATCHER_IMPLEMENTATION 1329 #include "MipsGenAsmMatcher.inc" 1330