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