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