MipsAsmParser.cpp revision 2f68b311a1b0efb3cafeca3780f5c3d09a762a50
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 Kind; 460 unsigned ErrorInfo; 461 MatchInstMapAndConstraints MapAndConstraints; 462 unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, 463 MapAndConstraints, ErrorInfo, 464 /*matchingInlineAsm*/ false); 465 466 switch (MatchResult) { 467 default: break; 468 case Match_Success: { 469 if (needsExpansion(Inst)) { 470 SmallVector<MCInst, 4> Instructions; 471 expandInstruction(Inst, IDLoc, Instructions); 472 for(unsigned i =0; i < Instructions.size(); i++){ 473 Out.EmitInstruction(Instructions[i]); 474 } 475 } else { 476 Inst.setLoc(IDLoc); 477 Out.EmitInstruction(Inst); 478 } 479 return false; 480 } 481 case Match_MissingFeature: 482 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 483 return true; 484 case Match_InvalidOperand: { 485 SMLoc ErrorLoc = IDLoc; 486 if (ErrorInfo != ~0U) { 487 if (ErrorInfo >= Operands.size()) 488 return Error(IDLoc, "too few operands for instruction"); 489 490 ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc(); 491 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 492 } 493 494 return Error(ErrorLoc, "invalid operand for instruction"); 495 } 496 case Match_MnemonicFail: 497 return Error(IDLoc, "invalid instruction"); 498 } 499 return true; 500} 501 502int MipsAsmParser::matchRegisterName(StringRef Name) { 503 504 int CC; 505 if (!isMips64()) 506 CC = StringSwitch<unsigned>(Name) 507 .Case("zero", Mips::ZERO) 508 .Case("a0", Mips::A0) 509 .Case("a1", Mips::A1) 510 .Case("a2", Mips::A2) 511 .Case("a3", Mips::A3) 512 .Case("v0", Mips::V0) 513 .Case("v1", Mips::V1) 514 .Case("s0", Mips::S0) 515 .Case("s1", Mips::S1) 516 .Case("s2", Mips::S2) 517 .Case("s3", Mips::S3) 518 .Case("s4", Mips::S4) 519 .Case("s5", Mips::S5) 520 .Case("s6", Mips::S6) 521 .Case("s7", Mips::S7) 522 .Case("k0", Mips::K0) 523 .Case("k1", Mips::K1) 524 .Case("sp", Mips::SP) 525 .Case("fp", Mips::FP) 526 .Case("gp", Mips::GP) 527 .Case("ra", Mips::RA) 528 .Case("t0", Mips::T0) 529 .Case("t1", Mips::T1) 530 .Case("t2", Mips::T2) 531 .Case("t3", Mips::T3) 532 .Case("t4", Mips::T4) 533 .Case("t5", Mips::T5) 534 .Case("t6", Mips::T6) 535 .Case("t7", Mips::T7) 536 .Case("t8", Mips::T8) 537 .Case("t9", Mips::T9) 538 .Case("at", Mips::AT) 539 .Case("fcc0", Mips::FCC0) 540 .Default(-1); 541 else 542 CC = StringSwitch<unsigned>(Name) 543 .Case("zero", Mips::ZERO_64) 544 .Case("at", Mips::AT_64) 545 .Case("v0", Mips::V0_64) 546 .Case("v1", Mips::V1_64) 547 .Case("a0", Mips::A0_64) 548 .Case("a1", Mips::A1_64) 549 .Case("a2", Mips::A2_64) 550 .Case("a3", Mips::A3_64) 551 .Case("a4", Mips::T0_64) 552 .Case("a5", Mips::T1_64) 553 .Case("a6", Mips::T2_64) 554 .Case("a7", Mips::T3_64) 555 .Case("t4", Mips::T4_64) 556 .Case("t5", Mips::T5_64) 557 .Case("t6", Mips::T6_64) 558 .Case("t7", Mips::T7_64) 559 .Case("s0", Mips::S0_64) 560 .Case("s1", Mips::S1_64) 561 .Case("s2", Mips::S2_64) 562 .Case("s3", Mips::S3_64) 563 .Case("s4", Mips::S4_64) 564 .Case("s5", Mips::S5_64) 565 .Case("s6", Mips::S6_64) 566 .Case("s7", Mips::S7_64) 567 .Case("t8", Mips::T8_64) 568 .Case("t9", Mips::T9_64) 569 .Case("kt0", Mips::K0_64) 570 .Case("kt1", Mips::K1_64) 571 .Case("gp", Mips::GP_64) 572 .Case("sp", Mips::SP_64) 573 .Case("fp", Mips::FP_64) 574 .Case("s8", Mips::FP_64) 575 .Case("ra", Mips::RA_64) 576 .Default(-1); 577 578 if (CC != -1) 579 return CC; 580 581 if (Name[0] == 'f') { 582 StringRef NumString = Name.substr(1); 583 unsigned IntVal; 584 if( NumString.getAsInteger(10, IntVal)) 585 return -1; // not integer 586 if (IntVal > 31) 587 return -1; 588 589 FpFormatTy Format = getFpFormat(); 590 591 if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 592 return getReg(Mips::FGR32RegClassID, IntVal); 593 if (Format == FP_FORMAT_D) { 594 if(isFP64()) { 595 return getReg(Mips::FGR64RegClassID, IntVal); 596 } 597 // only even numbers available as register pairs 598 if (( IntVal > 31) || (IntVal%2 != 0)) 599 return -1; 600 return getReg(Mips::AFGR64RegClassID, IntVal/2); 601 } 602 } 603 604 return -1; 605} 606void MipsAsmParser::setDefaultFpFormat() { 607 608 if (isMips64() || isFP64()) 609 FpFormat = FP_FORMAT_D; 610 else 611 FpFormat = FP_FORMAT_S; 612} 613 614bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 615 616 bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 617 .Case("ldxc1", true) 618 .Case("ldc1", true) 619 .Case("sdxc1", true) 620 .Case("sdc1", true) 621 .Default(false); 622 623 return IsDouble; 624} 625void MipsAsmParser::setFpFormat(StringRef Format) { 626 627 FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 628 .Case(".s", FP_FORMAT_S) 629 .Case(".d", FP_FORMAT_D) 630 .Case(".l", FP_FORMAT_L) 631 .Case(".w", FP_FORMAT_W) 632 .Default(FP_FORMAT_NONE); 633} 634 635bool MipsAssemblerOptions::setATReg(unsigned Reg) { 636 if (Reg > 31) 637 return false; 638 639 aTReg = Reg; 640 return true; 641} 642 643unsigned MipsAsmParser::getATReg() { 644 unsigned Reg = Options.getATRegNum(); 645 if (isMips64()) 646 return getReg(Mips::CPU64RegsRegClassID,Reg); 647 648 return getReg(Mips::CPURegsRegClassID,Reg); 649} 650 651unsigned MipsAsmParser::getReg(int RC,int RegNo) { 652 return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); 653} 654 655int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) { 656 657 if (Mnemonic.lower() == "rdhwr") { 658 // at the moment only hwreg29 is supported 659 if (RegNum != 29) 660 return -1; 661 return Mips::HWR29; 662 } 663 664 if (RegNum > 31) 665 return -1; 666 667 // MIPS64 registers are numbered 1 after the 32-bit equivalents 668 return getReg(Mips::CPURegsRegClassID, RegNum) + isMips64(); 669} 670 671int MipsAsmParser::tryParseRegister(StringRef Mnemonic) { 672 const AsmToken &Tok = Parser.getTok(); 673 int RegNum = -1; 674 675 if (Tok.is(AsmToken::Identifier)) { 676 std::string lowerCase = Tok.getString().lower(); 677 RegNum = matchRegisterName(lowerCase); 678 } else if (Tok.is(AsmToken::Integer)) 679 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 680 Mnemonic.lower()); 681 else 682 return RegNum; //error 683 // 64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64 684 if (isMips64() && RegNum == Mips::ZERO_64) { 685 if (Mnemonic.find("ddiv") != StringRef::npos) 686 RegNum = Mips::ZERO; 687 } 688 return RegNum; 689} 690 691bool MipsAsmParser:: 692 tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 693 StringRef Mnemonic){ 694 695 SMLoc S = Parser.getTok().getLoc(); 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, 711 Parser.getTok().getLoc())); 712 Parser.Lex(); // Eat register token. 713 return false; 714} 715 716bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 717 StringRef Mnemonic) { 718 // Check if the current operand has a custom associated parser, if so, try to 719 // custom parse the operand, or fallback to the general approach. 720 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 721 if (ResTy == MatchOperand_Success) 722 return false; 723 // If there wasn't a custom match, try the generic matcher below. Otherwise, 724 // there was a match, but an error occurred, in which case, just return that 725 // the operand parsing failed. 726 if (ResTy == MatchOperand_ParseFail) 727 return true; 728 729 switch (getLexer().getKind()) { 730 default: 731 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 732 return true; 733 case AsmToken::Dollar: { 734 // parse register 735 SMLoc S = Parser.getTok().getLoc(); 736 Parser.Lex(); // Eat dollar token. 737 // parse register operand 738 if (!tryParseRegisterOperand(Operands, Mnemonic)) { 739 if (getLexer().is(AsmToken::LParen)) { 740 // check if it is indexed addressing operand 741 Operands.push_back(MipsOperand::CreateToken("(", S)); 742 Parser.Lex(); // eat parenthesis 743 if (getLexer().isNot(AsmToken::Dollar)) 744 return true; 745 746 Parser.Lex(); // eat dollar 747 if (tryParseRegisterOperand(Operands, Mnemonic)) 748 return true; 749 750 if (!getLexer().is(AsmToken::RParen)) 751 return true; 752 753 S = Parser.getTok().getLoc(); 754 Operands.push_back(MipsOperand::CreateToken(")", S)); 755 Parser.Lex(); 756 } 757 return false; 758 } 759 // maybe it is a symbol reference 760 StringRef Identifier; 761 if (Parser.ParseIdentifier(Identifier)) 762 return true; 763 764 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 765 766 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 767 768 // Otherwise create a symbol ref. 769 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 770 getContext()); 771 772 Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 773 return false; 774 } 775 case AsmToken::Identifier: 776 case AsmToken::LParen: 777 case AsmToken::Minus: 778 case AsmToken::Plus: 779 case AsmToken::Integer: 780 case AsmToken::String: { 781 // quoted label names 782 const MCExpr *IdVal; 783 SMLoc S = Parser.getTok().getLoc(); 784 if (getParser().ParseExpression(IdVal)) 785 return true; 786 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 787 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 788 return false; 789 } 790 case AsmToken::Percent: { 791 // it is a symbol reference or constant expression 792 const MCExpr *IdVal; 793 SMLoc S = Parser.getTok().getLoc(); // start location of the operand 794 if (parseRelocOperand(IdVal)) 795 return true; 796 797 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 798 799 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 800 return false; 801 } // case AsmToken::Percent 802 } // switch(getLexer().getKind()) 803 return true; 804} 805 806bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 807 808 Parser.Lex(); // eat % token 809 const AsmToken &Tok = Parser.getTok(); // get next token, operation 810 if (Tok.isNot(AsmToken::Identifier)) 811 return true; 812 813 std::string Str = Tok.getIdentifier().str(); 814 815 Parser.Lex(); // eat identifier 816 // now make expression from the rest of the operand 817 const MCExpr *IdVal; 818 SMLoc EndLoc; 819 820 if (getLexer().getKind() == AsmToken::LParen) { 821 while (1) { 822 Parser.Lex(); // eat '(' token 823 if (getLexer().getKind() == AsmToken::Percent) { 824 Parser.Lex(); // eat % token 825 const AsmToken &nextTok = Parser.getTok(); 826 if (nextTok.isNot(AsmToken::Identifier)) 827 return true; 828 Str += "(%"; 829 Str += nextTok.getIdentifier(); 830 Parser.Lex(); // eat identifier 831 if (getLexer().getKind() != AsmToken::LParen) 832 return true; 833 } else 834 break; 835 } 836 if (getParser().ParseParenExpression(IdVal,EndLoc)) 837 return true; 838 839 while (getLexer().getKind() == AsmToken::RParen) 840 Parser.Lex(); // eat ')' token 841 842 } else 843 return true; // parenthesis must follow reloc operand 844 845 // Check the type of the expression 846 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) { 847 // it's a constant, evaluate lo or hi value 848 int Val = MCE->getValue(); 849 if (Str == "lo") { 850 Val = Val & 0xffff; 851 } else if (Str == "hi") { 852 Val = (Val & 0xffff0000) >> 16; 853 } 854 Res = MCConstantExpr::Create(Val, getContext()); 855 return false; 856 } 857 858 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) { 859 // it's a symbol, create symbolic expression from symbol 860 StringRef Symbol = MSRE->getSymbol().getName(); 861 MCSymbolRefExpr::VariantKind VK = getVariantKind(Str); 862 Res = MCSymbolRefExpr::Create(Symbol,VK,getContext()); 863 return false; 864 } 865 return true; 866} 867 868bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 869 SMLoc &EndLoc) { 870 871 StartLoc = Parser.getTok().getLoc(); 872 RegNo = tryParseRegister(""); 873 EndLoc = Parser.getTok().getLoc(); 874 return (RegNo == (unsigned)-1); 875} 876 877bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { 878 879 SMLoc S; 880 881 switch(getLexer().getKind()) { 882 default: 883 return true; 884 case AsmToken::Integer: 885 case AsmToken::Minus: 886 case AsmToken::Plus: 887 return (getParser().ParseExpression(Res)); 888 case AsmToken::Percent: 889 return parseRelocOperand(Res); 890 case AsmToken::LParen: 891 return false; // it's probably assuming 0 892 } 893 return true; 894} 895 896MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 897 SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 898 899 const MCExpr *IdVal = 0; 900 SMLoc S; 901 // first operand is the offset 902 S = Parser.getTok().getLoc(); 903 904 if (parseMemOffset(IdVal)) 905 return MatchOperand_ParseFail; 906 907 const AsmToken &Tok = Parser.getTok(); // get next token 908 if (Tok.isNot(AsmToken::LParen)) { 909 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 910 if (Mnemonic->getToken() == "la") { 911 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1); 912 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 913 return MatchOperand_Success; 914 } 915 Error(Parser.getTok().getLoc(), "'(' expected"); 916 return MatchOperand_ParseFail; 917 } 918 919 Parser.Lex(); // Eat '(' token. 920 921 const AsmToken &Tok1 = Parser.getTok(); // get next token 922 if (Tok1.is(AsmToken::Dollar)) { 923 Parser.Lex(); // Eat '$' token. 924 if (tryParseRegisterOperand(Operands,"")) { 925 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 926 return MatchOperand_ParseFail; 927 } 928 929 } else { 930 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 931 return MatchOperand_ParseFail; 932 } 933 934 const AsmToken &Tok2 = Parser.getTok(); // get next token 935 if (Tok2.isNot(AsmToken::RParen)) { 936 Error(Parser.getTok().getLoc(), "')' expected"); 937 return MatchOperand_ParseFail; 938 } 939 940 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 941 942 Parser.Lex(); // Eat ')' token. 943 944 if (IdVal == 0) 945 IdVal = MCConstantExpr::Create(0, getContext()); 946 947 // now replace register operand with the mem operand 948 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 949 int RegNo = op->getReg(); 950 // remove register from operands 951 Operands.pop_back(); 952 // and add memory operand 953 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 954 delete op; 955 return MatchOperand_Success; 956} 957 958MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 959 960 MCSymbolRefExpr::VariantKind VK 961 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 962 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 963 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 964 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 965 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 966 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 967 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 968 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 969 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 970 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 971 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 972 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 973 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 974 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 975 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 976 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 977 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 978 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 979 .Default(MCSymbolRefExpr::VK_None); 980 981 return VK; 982} 983 984static int ConvertCcString(StringRef CondString) { 985 int CC = StringSwitch<unsigned>(CondString) 986 .Case(".f", 0) 987 .Case(".un", 1) 988 .Case(".eq", 2) 989 .Case(".ueq", 3) 990 .Case(".olt", 4) 991 .Case(".ult", 5) 992 .Case(".ole", 6) 993 .Case(".ule", 7) 994 .Case(".sf", 8) 995 .Case(".ngle", 9) 996 .Case(".seq", 10) 997 .Case(".ngl", 11) 998 .Case(".lt", 12) 999 .Case(".nge", 13) 1000 .Case(".le", 14) 1001 .Case(".ngt", 15) 1002 .Default(-1); 1003 1004 return CC; 1005} 1006 1007bool MipsAsmParser:: 1008parseMathOperation(StringRef Name, SMLoc NameLoc, 1009 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1010 // split the format 1011 size_t Start = Name.find('.'), Next = Name.rfind('.'); 1012 StringRef Format1 = Name.slice(Start, Next); 1013 // and add the first format to the operands 1014 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 1015 // now for the second format 1016 StringRef Format2 = Name.slice(Next, StringRef::npos); 1017 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1018 1019 // set the format for the first register 1020 setFpFormat(Format1); 1021 1022 // Read the remaining operands. 1023 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1024 // Read the first operand. 1025 if (ParseOperand(Operands, Name)) { 1026 SMLoc Loc = getLexer().getLoc(); 1027 Parser.EatToEndOfStatement(); 1028 return Error(Loc, "unexpected token in argument list"); 1029 } 1030 1031 if (getLexer().isNot(AsmToken::Comma)) { 1032 SMLoc Loc = getLexer().getLoc(); 1033 Parser.EatToEndOfStatement(); 1034 return Error(Loc, "unexpected token in argument list"); 1035 1036 } 1037 Parser.Lex(); // Eat the comma. 1038 1039 //set the format for the first register 1040 setFpFormat(Format2); 1041 1042 // Parse and remember the operand. 1043 if (ParseOperand(Operands, Name)) { 1044 SMLoc Loc = getLexer().getLoc(); 1045 Parser.EatToEndOfStatement(); 1046 return Error(Loc, "unexpected token in argument list"); 1047 } 1048 } 1049 1050 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1051 SMLoc Loc = getLexer().getLoc(); 1052 Parser.EatToEndOfStatement(); 1053 return Error(Loc, "unexpected token in argument list"); 1054 } 1055 1056 Parser.Lex(); // Consume the EndOfStatement 1057 return false; 1058} 1059 1060bool MipsAsmParser:: 1061ParseInstruction(StringRef Name, SMLoc NameLoc, 1062 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1063 // floating point instructions: should register be treated as double? 1064 if (requestsDoubleOperand(Name)) { 1065 setFpFormat(FP_FORMAT_D); 1066 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1067 } 1068 else { 1069 setDefaultFpFormat(); 1070 // Create the leading tokens for the mnemonic, split by '.' characters. 1071 size_t Start = 0, Next = Name.find('.'); 1072 StringRef Mnemonic = Name.slice(Start, Next); 1073 1074 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1075 1076 if (Next != StringRef::npos) { 1077 // there is a format token in mnemonic 1078 // StringRef Rest = Name.slice(Next, StringRef::npos); 1079 size_t Dot = Name.find('.', Next+1); 1080 StringRef Format = Name.slice(Next, Dot); 1081 if (Dot == StringRef::npos) //only one '.' in a string, it's a format 1082 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1083 else { 1084 if (Name.startswith("c.")){ 1085 // floating point compare, add '.' and immediate represent for cc 1086 Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1087 int Cc = ConvertCcString(Format); 1088 if (Cc == -1) { 1089 return Error(NameLoc, "Invalid conditional code"); 1090 } 1091 SMLoc E = SMLoc::getFromPointer( 1092 Parser.getTok().getLoc().getPointer() -1 ); 1093 Operands.push_back(MipsOperand::CreateImm( 1094 MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 1095 } else { 1096 // trunc, ceil, floor ... 1097 return parseMathOperation(Name, NameLoc, Operands); 1098 } 1099 1100 // the rest is a format 1101 Format = Name.slice(Dot, StringRef::npos); 1102 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1103 } 1104 1105 setFpFormat(Format); 1106 } 1107 } 1108 1109 // Read the remaining operands. 1110 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1111 // Read the first operand. 1112 if (ParseOperand(Operands, Name)) { 1113 SMLoc Loc = getLexer().getLoc(); 1114 Parser.EatToEndOfStatement(); 1115 return Error(Loc, "unexpected token in argument list"); 1116 } 1117 1118 while (getLexer().is(AsmToken::Comma) ) { 1119 Parser.Lex(); // Eat the comma. 1120 1121 // Parse and remember the operand. 1122 if (ParseOperand(Operands, Name)) { 1123 SMLoc Loc = getLexer().getLoc(); 1124 Parser.EatToEndOfStatement(); 1125 return Error(Loc, "unexpected token in argument list"); 1126 } 1127 } 1128 } 1129 1130 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1131 SMLoc Loc = getLexer().getLoc(); 1132 Parser.EatToEndOfStatement(); 1133 return Error(Loc, "unexpected token in argument list"); 1134 } 1135 1136 Parser.Lex(); // Consume the EndOfStatement 1137 return false; 1138} 1139 1140bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1141 SMLoc Loc = getLexer().getLoc(); 1142 Parser.EatToEndOfStatement(); 1143 return Error(Loc, ErrorMsg); 1144} 1145 1146bool MipsAsmParser::parseSetNoAtDirective() { 1147 // line should look like: 1148 // .set noat 1149 // set at reg to 0 1150 Options.setATReg(0); 1151 // eat noat 1152 Parser.Lex(); 1153 // if this is not the end of the statement, report error 1154 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1155 reportParseError("unexpected token in statement"); 1156 return false; 1157 } 1158 Parser.Lex(); // Consume the EndOfStatement 1159 return false; 1160} 1161bool MipsAsmParser::parseSetAtDirective() { 1162 // line can be 1163 // .set at - defaults to $1 1164 // or .set at=$reg 1165 getParser().Lex(); 1166 if (getLexer().is(AsmToken::EndOfStatement)) { 1167 Options.setATReg(1); 1168 Parser.Lex(); // Consume the EndOfStatement 1169 return false; 1170 } else if (getLexer().is(AsmToken::Equal)) { 1171 getParser().Lex(); //eat '=' 1172 if (getLexer().isNot(AsmToken::Dollar)) { 1173 reportParseError("unexpected token in statement"); 1174 return false; 1175 } 1176 Parser.Lex(); // eat '$' 1177 if (getLexer().isNot(AsmToken::Integer)) { 1178 reportParseError("unexpected token in statement"); 1179 return false; 1180 } 1181 const AsmToken &Reg = Parser.getTok(); 1182 if (!Options.setATReg(Reg.getIntVal())) { 1183 reportParseError("unexpected token in statement"); 1184 return false; 1185 } 1186 getParser().Lex(); //eat reg 1187 1188 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1189 reportParseError("unexpected token in statement"); 1190 return false; 1191 } 1192 Parser.Lex(); // Consume the EndOfStatement 1193 return false; 1194 } else { 1195 reportParseError("unexpected token in statement"); 1196 return false; 1197 } 1198} 1199 1200bool MipsAsmParser::parseSetReorderDirective() { 1201 Parser.Lex(); 1202 // if this is not the end of the statement, report error 1203 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1204 reportParseError("unexpected token in statement"); 1205 return false; 1206 } 1207 Options.setReorder(); 1208 Parser.Lex(); // Consume the EndOfStatement 1209 return false; 1210} 1211 1212bool MipsAsmParser::parseSetNoReorderDirective() { 1213 Parser.Lex(); 1214 // if this is not the end of the statement, report error 1215 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1216 reportParseError("unexpected token in statement"); 1217 return false; 1218 } 1219 Options.setNoreorder(); 1220 Parser.Lex(); // Consume the EndOfStatement 1221 return false; 1222} 1223 1224bool MipsAsmParser::parseSetMacroDirective() { 1225 Parser.Lex(); 1226 // if this is not the end of the statement, report error 1227 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1228 reportParseError("unexpected token in statement"); 1229 return false; 1230 } 1231 Options.setMacro(); 1232 Parser.Lex(); // Consume the EndOfStatement 1233 return false; 1234} 1235 1236bool MipsAsmParser::parseSetNoMacroDirective() { 1237 Parser.Lex(); 1238 // if this is not the end of the statement, report error 1239 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1240 reportParseError("`noreorder' must be set before `nomacro'"); 1241 return false; 1242 } 1243 if (Options.isReorder()) { 1244 reportParseError("`noreorder' must be set before `nomacro'"); 1245 return false; 1246 } 1247 Options.setNomacro(); 1248 Parser.Lex(); // Consume the EndOfStatement 1249 return false; 1250} 1251bool MipsAsmParser::parseDirectiveSet() { 1252 1253 // get next token 1254 const AsmToken &Tok = Parser.getTok(); 1255 1256 if (Tok.getString() == "noat") { 1257 return parseSetNoAtDirective(); 1258 } else if (Tok.getString() == "at") { 1259 return parseSetAtDirective(); 1260 } else if (Tok.getString() == "reorder") { 1261 return parseSetReorderDirective(); 1262 } else if (Tok.getString() == "noreorder") { 1263 return parseSetNoReorderDirective(); 1264 } else if (Tok.getString() == "macro") { 1265 return parseSetMacroDirective(); 1266 } else if (Tok.getString() == "nomacro") { 1267 return parseSetNoMacroDirective(); 1268 } else if (Tok.getString() == "nomips16") { 1269 // ignore this directive for now 1270 Parser.EatToEndOfStatement(); 1271 return false; 1272 } else if (Tok.getString() == "nomicromips") { 1273 // ignore this directive for now 1274 Parser.EatToEndOfStatement(); 1275 return false; 1276 } 1277 return true; 1278} 1279 1280bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1281 1282 if (DirectiveID.getString() == ".ent") { 1283 // ignore this directive for now 1284 Parser.Lex(); 1285 return false; 1286 } 1287 1288 if (DirectiveID.getString() == ".end") { 1289 // ignore this directive for now 1290 Parser.Lex(); 1291 return false; 1292 } 1293 1294 if (DirectiveID.getString() == ".frame") { 1295 // ignore this directive for now 1296 Parser.EatToEndOfStatement(); 1297 return false; 1298 } 1299 1300 if (DirectiveID.getString() == ".set") { 1301 return parseDirectiveSet(); 1302 } 1303 1304 if (DirectiveID.getString() == ".fmask") { 1305 // ignore this directive for now 1306 Parser.EatToEndOfStatement(); 1307 return false; 1308 } 1309 1310 if (DirectiveID.getString() == ".mask") { 1311 // ignore this directive for now 1312 Parser.EatToEndOfStatement(); 1313 return false; 1314 } 1315 1316 if (DirectiveID.getString() == ".gpword") { 1317 // ignore this directive for now 1318 Parser.EatToEndOfStatement(); 1319 return false; 1320 } 1321 1322 return true; 1323} 1324 1325extern "C" void LLVMInitializeMipsAsmParser() { 1326 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1327 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1328 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1329 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1330} 1331 1332#define GET_REGISTER_MATCHER 1333#define GET_MATCHER_IMPLEMENTATION 1334#include "MipsGenAsmMatcher.inc" 1335