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