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 #include "llvm/ADT/APInt.h" 24 25 using namespace llvm; 26 27 namespace { 28 class MipsAssemblerOptions { 29 public: 30 MipsAssemblerOptions(): 31 aTReg(1), reorder(true), macro(true) { 32 } 33 34 unsigned getATRegNum() {return aTReg;} 35 bool setATReg(unsigned Reg); 36 37 bool isReorder() {return reorder;} 38 void setReorder() {reorder = true;} 39 void setNoreorder() {reorder = false;} 40 41 bool isMacro() {return macro;} 42 void setMacro() {macro = true;} 43 void setNomacro() {macro = false;} 44 45 private: 46 unsigned aTReg; 47 bool reorder; 48 bool macro; 49 }; 50 } 51 52 namespace { 53 class MipsAsmParser : public MCTargetAsmParser { 54 55 enum FpFormatTy { 56 FP_FORMAT_NONE = -1, 57 FP_FORMAT_S, 58 FP_FORMAT_D, 59 FP_FORMAT_L, 60 FP_FORMAT_W 61 } FpFormat; 62 63 MCSubtargetInfo &STI; 64 MCAsmParser &Parser; 65 MipsAssemblerOptions Options; 66 bool hasConsumedDollar; 67 68 #define GET_ASSEMBLER_HEADER 69 #include "MipsGenAsmMatcher.inc" 70 71 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 72 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 73 MCStreamer &Out, unsigned &ErrorInfo, 74 bool MatchingInlineAsm); 75 76 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 77 78 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 79 SMLoc NameLoc, 80 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 81 82 bool ParseDirective(AsmToken DirectiveID); 83 84 MipsAsmParser::OperandMatchResultTy 85 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 86 int RegKind); 87 88 MipsAsmParser::OperandMatchResultTy 89 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 90 91 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind); 92 93 MipsAsmParser::OperandMatchResultTy 94 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 95 96 MipsAsmParser::OperandMatchResultTy 97 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 98 99 MipsAsmParser::OperandMatchResultTy 100 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 101 102 MipsAsmParser::OperandMatchResultTy 103 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 104 105 MipsAsmParser::OperandMatchResultTy 106 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 107 108 MipsAsmParser::OperandMatchResultTy 109 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 110 111 MipsAsmParser::OperandMatchResultTy 112 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 113 114 MipsAsmParser::OperandMatchResultTy 115 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 116 117 MipsAsmParser::OperandMatchResultTy 118 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 119 120 MipsAsmParser::OperandMatchResultTy 121 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 122 123 MipsAsmParser::OperandMatchResultTy 124 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 125 126 MipsAsmParser::OperandMatchResultTy 127 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 128 129 MipsAsmParser::OperandMatchResultTy 130 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 131 132 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 133 unsigned RegKind); 134 135 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 136 StringRef Mnemonic); 137 138 int tryParseRegister(bool is64BitReg); 139 140 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 141 bool is64BitReg); 142 143 bool needsExpansion(MCInst &Inst); 144 145 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 146 SmallVectorImpl<MCInst> &Instructions); 147 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 148 SmallVectorImpl<MCInst> &Instructions); 149 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 150 SmallVectorImpl<MCInst> &Instructions); 151 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 152 SmallVectorImpl<MCInst> &Instructions); 153 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 154 SmallVectorImpl<MCInst> &Instructions, 155 bool isLoad,bool isImmOpnd); 156 bool reportParseError(StringRef ErrorMsg); 157 158 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 159 bool parseRelocOperand(const MCExpr *&Res); 160 161 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 162 163 bool isEvaluated(const MCExpr *Expr); 164 bool parseDirectiveSet(); 165 166 bool parseSetAtDirective(); 167 bool parseSetNoAtDirective(); 168 bool parseSetMacroDirective(); 169 bool parseSetNoMacroDirective(); 170 bool parseSetReorderDirective(); 171 bool parseSetNoReorderDirective(); 172 173 bool parseSetAssignment(); 174 175 bool parseDirectiveWord(unsigned Size, SMLoc L); 176 177 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 178 179 bool isMips64() const { 180 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 181 } 182 183 bool isFP64() const { 184 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 185 } 186 187 bool isN64() const { 188 return STI.getFeatureBits() & Mips::FeatureN64; 189 } 190 191 int matchRegisterName(StringRef Symbol, bool is64BitReg); 192 193 int matchCPURegisterName(StringRef Symbol); 194 195 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 196 197 int matchFPURegisterName(StringRef Name); 198 199 int matchFCCRegisterName(StringRef Name); 200 201 int matchACRegisterName(StringRef Name); 202 203 int regKindToRegClass(int RegKind); 204 205 FpFormatTy getFpFormat() {return FpFormat;} 206 207 unsigned getReg(int RC, int RegNo); 208 209 int getATReg(); 210 211 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 212 SmallVectorImpl<MCInst> &Instructions); 213 public: 214 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 215 : MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) { 216 // Initialize the set of available features. 217 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 218 } 219 220 MCAsmParser &getParser() const { return Parser; } 221 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 222 223 }; 224 } 225 226 namespace { 227 228 /// MipsOperand - Instances of this class represent a parsed Mips machine 229 /// instruction. 230 class MipsOperand : public MCParsedAsmOperand { 231 232 public: 233 enum RegisterKind { 234 Kind_None, 235 Kind_GPR32, 236 Kind_GPR64, 237 Kind_HWRegs, 238 Kind_FGR32Regs, 239 Kind_FGRH32Regs, 240 Kind_FGR64Regs, 241 Kind_AFGR64Regs, 242 Kind_CCRRegs, 243 Kind_FCCRegs, 244 Kind_ACC64DSP, 245 Kind_LO32DSP, 246 Kind_HI32DSP 247 }; 248 249 private: 250 enum KindTy { 251 k_CondCode, 252 k_CoprocNum, 253 k_Immediate, 254 k_Memory, 255 k_PostIndexRegister, 256 k_Register, 257 k_PtrReg, 258 k_Token 259 } Kind; 260 261 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 262 263 struct Token { 264 const char *Data; 265 unsigned Length; 266 }; 267 268 struct RegOp { 269 unsigned RegNum; 270 RegisterKind Kind; 271 }; 272 273 struct ImmOp { 274 const MCExpr *Val; 275 }; 276 277 struct MemOp { 278 unsigned Base; 279 const MCExpr *Off; 280 }; 281 282 union { 283 struct Token Tok; 284 struct RegOp Reg; 285 struct ImmOp Imm; 286 struct MemOp Mem; 287 }; 288 289 SMLoc StartLoc, EndLoc; 290 291 public: 292 void addRegOperands(MCInst &Inst, unsigned N) const { 293 assert(N == 1 && "Invalid number of operands!"); 294 Inst.addOperand(MCOperand::CreateReg(getReg())); 295 } 296 297 void addPtrRegOperands(MCInst &Inst, unsigned N) const { 298 assert(N == 1 && "Invalid number of operands!"); 299 Inst.addOperand(MCOperand::CreateReg(getPtrReg())); 300 } 301 302 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 303 // Add as immediate when possible. Null MCExpr = 0. 304 if (Expr == 0) 305 Inst.addOperand(MCOperand::CreateImm(0)); 306 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 307 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 308 else 309 Inst.addOperand(MCOperand::CreateExpr(Expr)); 310 } 311 312 void addImmOperands(MCInst &Inst, unsigned N) const { 313 assert(N == 1 && "Invalid number of operands!"); 314 const MCExpr *Expr = getImm(); 315 addExpr(Inst, Expr); 316 } 317 318 void addMemOperands(MCInst &Inst, unsigned N) const { 319 assert(N == 2 && "Invalid number of operands!"); 320 321 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 322 323 const MCExpr *Expr = getMemOff(); 324 addExpr(Inst, Expr); 325 } 326 327 bool isReg() const { return Kind == k_Register; } 328 bool isImm() const { return Kind == k_Immediate; } 329 bool isToken() const { return Kind == k_Token; } 330 bool isMem() const { return Kind == k_Memory; } 331 bool isPtrReg() const { return Kind == k_PtrReg; } 332 333 StringRef getToken() const { 334 assert(Kind == k_Token && "Invalid access!"); 335 return StringRef(Tok.Data, Tok.Length); 336 } 337 338 unsigned getReg() const { 339 assert((Kind == k_Register) && "Invalid access!"); 340 return Reg.RegNum; 341 } 342 343 unsigned getPtrReg() const { 344 assert((Kind == k_PtrReg) && "Invalid access!"); 345 return Reg.RegNum; 346 } 347 348 void setRegKind(RegisterKind RegKind) { 349 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!"); 350 Reg.Kind = RegKind; 351 } 352 353 const MCExpr *getImm() const { 354 assert((Kind == k_Immediate) && "Invalid access!"); 355 return Imm.Val; 356 } 357 358 unsigned getMemBase() const { 359 assert((Kind == k_Memory) && "Invalid access!"); 360 return Mem.Base; 361 } 362 363 const MCExpr *getMemOff() const { 364 assert((Kind == k_Memory) && "Invalid access!"); 365 return Mem.Off; 366 } 367 368 static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 369 MipsOperand *Op = new MipsOperand(k_Token); 370 Op->Tok.Data = Str.data(); 371 Op->Tok.Length = Str.size(); 372 Op->StartLoc = S; 373 Op->EndLoc = S; 374 return Op; 375 } 376 377 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 378 MipsOperand *Op = new MipsOperand(k_Register); 379 Op->Reg.RegNum = RegNum; 380 Op->StartLoc = S; 381 Op->EndLoc = E; 382 return Op; 383 } 384 385 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) { 386 MipsOperand *Op = new MipsOperand(k_PtrReg); 387 Op->Reg.RegNum = RegNum; 388 Op->StartLoc = S; 389 Op->EndLoc = E; 390 return Op; 391 } 392 393 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 394 MipsOperand *Op = new MipsOperand(k_Immediate); 395 Op->Imm.Val = Val; 396 Op->StartLoc = S; 397 Op->EndLoc = E; 398 return Op; 399 } 400 401 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 402 SMLoc S, SMLoc E) { 403 MipsOperand *Op = new MipsOperand(k_Memory); 404 Op->Mem.Base = Base; 405 Op->Mem.Off = Off; 406 Op->StartLoc = S; 407 Op->EndLoc = E; 408 return Op; 409 } 410 411 bool isGPR32Asm() const { 412 return Kind == k_Register && Reg.Kind == Kind_GPR32; 413 } 414 void addRegAsmOperands(MCInst &Inst, unsigned N) const { 415 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 416 } 417 418 bool isGPR64Asm() const { 419 return Kind == k_Register && Reg.Kind == Kind_GPR64; 420 } 421 422 bool isHWRegsAsm() const { 423 assert((Kind == k_Register) && "Invalid access!"); 424 return Reg.Kind == Kind_HWRegs; 425 } 426 427 bool isCCRAsm() const { 428 assert((Kind == k_Register) && "Invalid access!"); 429 return Reg.Kind == Kind_CCRRegs; 430 } 431 432 bool isAFGR64Asm() const { 433 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs; 434 } 435 436 bool isFGR64Asm() const { 437 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs; 438 } 439 440 bool isFGR32Asm() const { 441 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs; 442 } 443 444 bool isFGRH32Asm() const { 445 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs; 446 } 447 448 bool isFCCRegsAsm() const { 449 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs; 450 } 451 452 bool isACC64DSPAsm() const { 453 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP; 454 } 455 456 bool isLO32DSPAsm() const { 457 return Kind == k_Register && Reg.Kind == Kind_LO32DSP; 458 } 459 460 bool isHI32DSPAsm() const { 461 return Kind == k_Register && Reg.Kind == Kind_HI32DSP; 462 } 463 464 /// getStartLoc - Get the location of the first token of this operand. 465 SMLoc getStartLoc() const { 466 return StartLoc; 467 } 468 /// getEndLoc - Get the location of the last token of this operand. 469 SMLoc getEndLoc() const { 470 return EndLoc; 471 } 472 473 virtual void print(raw_ostream &OS) const { 474 llvm_unreachable("unimplemented!"); 475 } 476 }; // class MipsOperand 477 } // namespace 478 479 namespace llvm { 480 extern const MCInstrDesc MipsInsts[]; 481 } 482 static const MCInstrDesc &getInstDesc(unsigned Opcode) { 483 return MipsInsts[Opcode]; 484 } 485 486 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 487 SmallVectorImpl<MCInst> &Instructions) { 488 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 489 Inst.setLoc(IDLoc); 490 if (MCID.hasDelaySlot() && Options.isReorder()) { 491 // If this instruction has a delay slot and .set reorder is active, 492 // emit a NOP after it. 493 Instructions.push_back(Inst); 494 MCInst NopInst; 495 NopInst.setOpcode(Mips::SLL); 496 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 497 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 498 NopInst.addOperand(MCOperand::CreateImm(0)); 499 Instructions.push_back(NopInst); 500 return false; 501 } 502 503 if (MCID.mayLoad() || MCID.mayStore()) { 504 // Check the offset of memory operand, if it is a symbol 505 // reference or immediate we may have to expand instructions. 506 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 507 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 508 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) 509 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 510 MCOperand &Op = Inst.getOperand(i); 511 if (Op.isImm()) { 512 int MemOffset = Op.getImm(); 513 if (MemOffset < -32768 || MemOffset > 32767) { 514 // Offset can't exceed 16bit value. 515 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 516 return false; 517 } 518 } else if (Op.isExpr()) { 519 const MCExpr *Expr = Op.getExpr(); 520 if (Expr->getKind() == MCExpr::SymbolRef) { 521 const MCSymbolRefExpr *SR = 522 static_cast<const MCSymbolRefExpr*>(Expr); 523 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 524 // Expand symbol. 525 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 526 return false; 527 } 528 } else if (!isEvaluated(Expr)) { 529 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 530 return false; 531 } 532 } 533 } 534 } // for 535 } // if load/store 536 537 if (needsExpansion(Inst)) 538 expandInstruction(Inst, IDLoc, Instructions); 539 else 540 Instructions.push_back(Inst); 541 542 return false; 543 } 544 545 bool MipsAsmParser::needsExpansion(MCInst &Inst) { 546 547 switch (Inst.getOpcode()) { 548 case Mips::LoadImm32Reg: 549 case Mips::LoadAddr32Imm: 550 case Mips::LoadAddr32Reg: 551 return true; 552 default: 553 return false; 554 } 555 } 556 557 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 558 SmallVectorImpl<MCInst> &Instructions) { 559 switch (Inst.getOpcode()) { 560 case Mips::LoadImm32Reg: 561 return expandLoadImm(Inst, IDLoc, Instructions); 562 case Mips::LoadAddr32Imm: 563 return expandLoadAddressImm(Inst, IDLoc, Instructions); 564 case Mips::LoadAddr32Reg: 565 return expandLoadAddressReg(Inst, IDLoc, Instructions); 566 } 567 } 568 569 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 570 SmallVectorImpl<MCInst> &Instructions) { 571 MCInst tmpInst; 572 const MCOperand &ImmOp = Inst.getOperand(1); 573 assert(ImmOp.isImm() && "expected immediate operand kind"); 574 const MCOperand &RegOp = Inst.getOperand(0); 575 assert(RegOp.isReg() && "expected register operand kind"); 576 577 int ImmValue = ImmOp.getImm(); 578 tmpInst.setLoc(IDLoc); 579 if (0 <= ImmValue && ImmValue <= 65535) { 580 // For 0 <= j <= 65535. 581 // li d,j => ori d,$zero,j 582 tmpInst.setOpcode(Mips::ORi); 583 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 584 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 585 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 586 Instructions.push_back(tmpInst); 587 } else if (ImmValue < 0 && ImmValue >= -32768) { 588 // For -32768 <= j < 0. 589 // li d,j => addiu d,$zero,j 590 tmpInst.setOpcode(Mips::ADDiu); 591 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 592 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 593 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 594 Instructions.push_back(tmpInst); 595 } else { 596 // For any other value of j that is representable as a 32-bit integer. 597 // li d,j => lui d,hi16(j) 598 // ori d,d,lo16(j) 599 tmpInst.setOpcode(Mips::LUi); 600 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 601 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 602 Instructions.push_back(tmpInst); 603 tmpInst.clear(); 604 tmpInst.setOpcode(Mips::ORi); 605 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 606 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 607 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 608 tmpInst.setLoc(IDLoc); 609 Instructions.push_back(tmpInst); 610 } 611 } 612 613 void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 614 SmallVectorImpl<MCInst> &Instructions) { 615 MCInst tmpInst; 616 const MCOperand &ImmOp = Inst.getOperand(2); 617 assert(ImmOp.isImm() && "expected immediate operand kind"); 618 const MCOperand &SrcRegOp = Inst.getOperand(1); 619 assert(SrcRegOp.isReg() && "expected register operand kind"); 620 const MCOperand &DstRegOp = Inst.getOperand(0); 621 assert(DstRegOp.isReg() && "expected register operand kind"); 622 int ImmValue = ImmOp.getImm(); 623 if (-32768 <= ImmValue && ImmValue <= 65535) { 624 // For -32768 <= j <= 65535. 625 // la d,j(s) => addiu d,s,j 626 tmpInst.setOpcode(Mips::ADDiu); 627 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 628 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 629 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 630 Instructions.push_back(tmpInst); 631 } else { 632 // For any other value of j that is representable as a 32-bit integer. 633 // la d,j(s) => lui d,hi16(j) 634 // ori d,d,lo16(j) 635 // addu d,d,s 636 tmpInst.setOpcode(Mips::LUi); 637 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 638 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 639 Instructions.push_back(tmpInst); 640 tmpInst.clear(); 641 tmpInst.setOpcode(Mips::ORi); 642 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 643 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 644 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 645 Instructions.push_back(tmpInst); 646 tmpInst.clear(); 647 tmpInst.setOpcode(Mips::ADDu); 648 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 649 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 650 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 651 Instructions.push_back(tmpInst); 652 } 653 } 654 655 void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 656 SmallVectorImpl<MCInst> &Instructions) { 657 MCInst tmpInst; 658 const MCOperand &ImmOp = Inst.getOperand(1); 659 assert(ImmOp.isImm() && "expected immediate operand kind"); 660 const MCOperand &RegOp = Inst.getOperand(0); 661 assert(RegOp.isReg() && "expected register operand kind"); 662 int ImmValue = ImmOp.getImm(); 663 if (-32768 <= ImmValue && ImmValue <= 65535) { 664 // For -32768 <= j <= 65535. 665 // la d,j => addiu d,$zero,j 666 tmpInst.setOpcode(Mips::ADDiu); 667 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 668 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 669 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 670 Instructions.push_back(tmpInst); 671 } else { 672 // For any other value of j that is representable as a 32-bit integer. 673 // la d,j => lui d,hi16(j) 674 // ori d,d,lo16(j) 675 tmpInst.setOpcode(Mips::LUi); 676 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 677 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 678 Instructions.push_back(tmpInst); 679 tmpInst.clear(); 680 tmpInst.setOpcode(Mips::ORi); 681 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 682 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 683 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 684 Instructions.push_back(tmpInst); 685 } 686 } 687 688 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 689 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) { 690 const MCSymbolRefExpr *SR; 691 MCInst TempInst; 692 unsigned ImmOffset, HiOffset, LoOffset; 693 const MCExpr *ExprOffset; 694 unsigned TmpRegNum; 695 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID 696 : Mips::GPR32RegClassID, getATReg()); 697 // 1st operand is either the source or destination register. 698 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 699 unsigned RegOpNum = Inst.getOperand(0).getReg(); 700 // 2nd operand is the base register. 701 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 702 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 703 // 3rd operand is either an immediate or expression. 704 if (isImmOpnd) { 705 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 706 ImmOffset = Inst.getOperand(2).getImm(); 707 LoOffset = ImmOffset & 0x0000ffff; 708 HiOffset = (ImmOffset & 0xffff0000) >> 16; 709 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 710 if (LoOffset & 0x8000) 711 HiOffset++; 712 } else 713 ExprOffset = Inst.getOperand(2).getExpr(); 714 // All instructions will have the same location. 715 TempInst.setLoc(IDLoc); 716 // 1st instruction in expansion is LUi. For load instruction we can use 717 // the dst register as a temporary if base and dst are different, 718 // but for stores we must use $at. 719 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 720 TempInst.setOpcode(Mips::LUi); 721 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 722 if (isImmOpnd) 723 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 724 else { 725 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 726 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset); 727 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 728 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 729 getContext()); 730 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 731 } else { 732 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 733 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 734 } 735 } 736 // Add the instruction to the list. 737 Instructions.push_back(TempInst); 738 // Prepare TempInst for next instruction. 739 TempInst.clear(); 740 // Add temp register to base. 741 TempInst.setOpcode(Mips::ADDu); 742 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 743 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 744 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 745 Instructions.push_back(TempInst); 746 TempInst.clear(); 747 // And finaly, create original instruction with low part 748 // of offset and new base. 749 TempInst.setOpcode(Inst.getOpcode()); 750 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 751 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 752 if (isImmOpnd) 753 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 754 else { 755 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 756 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 757 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 758 getContext()); 759 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 760 } else { 761 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 762 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 763 } 764 } 765 Instructions.push_back(TempInst); 766 TempInst.clear(); 767 } 768 769 bool MipsAsmParser:: 770 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 771 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 772 MCStreamer &Out, unsigned &ErrorInfo, 773 bool MatchingInlineAsm) { 774 MCInst Inst; 775 SmallVector<MCInst, 8> Instructions; 776 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 777 MatchingInlineAsm); 778 779 switch (MatchResult) { 780 default: 781 break; 782 case Match_Success: { 783 if (processInstruction(Inst, IDLoc, Instructions)) 784 return true; 785 for (unsigned i = 0; i < Instructions.size(); i++) 786 Out.EmitInstruction(Instructions[i]); 787 return false; 788 } 789 case Match_MissingFeature: 790 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 791 return true; 792 case Match_InvalidOperand: { 793 SMLoc ErrorLoc = IDLoc; 794 if (ErrorInfo != ~0U) { 795 if (ErrorInfo >= Operands.size()) 796 return Error(IDLoc, "too few operands for instruction"); 797 798 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc(); 799 if (ErrorLoc == SMLoc()) 800 ErrorLoc = IDLoc; 801 } 802 803 return Error(ErrorLoc, "invalid operand for instruction"); 804 } 805 case Match_MnemonicFail: 806 return Error(IDLoc, "invalid instruction"); 807 } 808 return true; 809 } 810 811 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 812 int CC; 813 814 if (Name == "at") 815 return getATReg(); 816 817 CC = StringSwitch<unsigned>(Name) 818 .Case("zero", 0) 819 .Case("a0", 4) 820 .Case("a1", 5) 821 .Case("a2", 6) 822 .Case("a3", 7) 823 .Case("v0", 2) 824 .Case("v1", 3) 825 .Case("s0", 16) 826 .Case("s1", 17) 827 .Case("s2", 18) 828 .Case("s3", 19) 829 .Case("s4", 20) 830 .Case("s5", 21) 831 .Case("s6", 22) 832 .Case("s7", 23) 833 .Case("k0", 26) 834 .Case("k1", 27) 835 .Case("sp", 29) 836 .Case("fp", 30) 837 .Case("gp", 28) 838 .Case("ra", 31) 839 .Case("t0", 8) 840 .Case("t1", 9) 841 .Case("t2", 10) 842 .Case("t3", 11) 843 .Case("t4", 12) 844 .Case("t5", 13) 845 .Case("t6", 14) 846 .Case("t7", 15) 847 .Case("t8", 24) 848 .Case("t9", 25) 849 .Default(-1); 850 851 // Although SGI documentation just cuts out t0-t3 for n32/n64, 852 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 853 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 854 if (isMips64() && 8 <= CC && CC <= 11) 855 CC += 4; 856 857 if (CC == -1 && isMips64()) 858 CC = StringSwitch<unsigned>(Name) 859 .Case("a4", 8) 860 .Case("a5", 9) 861 .Case("a6", 10) 862 .Case("a7", 11) 863 .Case("kt0", 26) 864 .Case("kt1", 27) 865 .Case("s8", 30) 866 .Default(-1); 867 868 return CC; 869 } 870 871 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 872 873 if (Name[0] == 'f') { 874 StringRef NumString = Name.substr(1); 875 unsigned IntVal; 876 if (NumString.getAsInteger(10, IntVal)) 877 return -1; // This is not an integer. 878 if (IntVal > 31) // Maximum index for fpu register. 879 return -1; 880 return IntVal; 881 } 882 return -1; 883 } 884 885 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 886 887 if (Name.startswith("fcc")) { 888 StringRef NumString = Name.substr(3); 889 unsigned IntVal; 890 if (NumString.getAsInteger(10, IntVal)) 891 return -1; // This is not an integer. 892 if (IntVal > 7) // There are only 8 fcc registers. 893 return -1; 894 return IntVal; 895 } 896 return -1; 897 } 898 899 int MipsAsmParser::matchACRegisterName(StringRef Name) { 900 901 if (Name.startswith("ac")) { 902 StringRef NumString = Name.substr(2); 903 unsigned IntVal; 904 if (NumString.getAsInteger(10, IntVal)) 905 return -1; // This is not an integer. 906 if (IntVal > 3) // There are only 3 acc registers. 907 return -1; 908 return IntVal; 909 } 910 return -1; 911 } 912 913 int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 914 915 int CC; 916 CC = matchCPURegisterName(Name); 917 if (CC != -1) 918 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID 919 : Mips::GPR32RegClassID); 920 CC= matchFPURegisterName(Name); 921 //TODO: decide about fpu register class 922 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID 923 : Mips::FGR32RegClassID); 924 } 925 926 int MipsAsmParser::regKindToRegClass(int RegKind) { 927 928 switch (RegKind) { 929 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID; 930 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID; 931 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID; 932 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID; 933 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID; 934 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID; 935 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID; 936 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID; 937 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID; 938 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID; 939 default :return -1; 940 } 941 942 } 943 944 bool MipsAssemblerOptions::setATReg(unsigned Reg) { 945 if (Reg > 31) 946 return false; 947 948 aTReg = Reg; 949 return true; 950 } 951 952 int MipsAsmParser::getATReg() { 953 return Options.getATRegNum(); 954 } 955 956 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 957 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 958 } 959 960 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 961 if (RegNum > 962 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs()) 963 return -1; 964 965 return getReg(RegClass, RegNum); 966 } 967 968 int MipsAsmParser::tryParseRegister(bool is64BitReg) { 969 const AsmToken &Tok = Parser.getTok(); 970 int RegNum = -1; 971 972 if (Tok.is(AsmToken::Identifier)) { 973 std::string lowerCase = Tok.getString().lower(); 974 RegNum = matchRegisterName(lowerCase, is64BitReg); 975 } else if (Tok.is(AsmToken::Integer)) 976 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 977 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID); 978 return RegNum; 979 } 980 981 bool MipsAsmParser::tryParseRegisterOperand( 982 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) { 983 984 SMLoc S = Parser.getTok().getLoc(); 985 int RegNo = -1; 986 987 RegNo = tryParseRegister(is64BitReg); 988 if (RegNo == -1) 989 return true; 990 991 Operands.push_back(MipsOperand::CreateReg(RegNo, S, 992 Parser.getTok().getLoc())); 993 Parser.Lex(); // Eat register token. 994 return false; 995 } 996 997 bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 998 StringRef Mnemonic) { 999 // Check if the current operand has a custom associated parser, if so, try to 1000 // custom parse the operand, or fallback to the general approach. 1001 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1002 if (ResTy == MatchOperand_Success) 1003 return false; 1004 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1005 // there was a match, but an error occurred, in which case, just return that 1006 // the operand parsing failed. 1007 if (ResTy == MatchOperand_ParseFail) 1008 return true; 1009 1010 switch (getLexer().getKind()) { 1011 default: 1012 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1013 return true; 1014 case AsmToken::Dollar: { 1015 // Parse the register. 1016 SMLoc S = Parser.getTok().getLoc(); 1017 Parser.Lex(); // Eat dollar token. 1018 // Parse the register operand. 1019 if (!tryParseRegisterOperand(Operands, isMips64())) { 1020 if (getLexer().is(AsmToken::LParen)) { 1021 // Check if it is indexed addressing operand. 1022 Operands.push_back(MipsOperand::CreateToken("(", S)); 1023 Parser.Lex(); // Eat the parenthesis. 1024 if (getLexer().isNot(AsmToken::Dollar)) 1025 return true; 1026 1027 Parser.Lex(); // Eat the dollar 1028 if (tryParseRegisterOperand(Operands, isMips64())) 1029 return true; 1030 1031 if (!getLexer().is(AsmToken::RParen)) 1032 return true; 1033 1034 S = Parser.getTok().getLoc(); 1035 Operands.push_back(MipsOperand::CreateToken(")", S)); 1036 Parser.Lex(); 1037 } 1038 return false; 1039 } 1040 // Maybe it is a symbol reference. 1041 StringRef Identifier; 1042 if (Parser.parseIdentifier(Identifier)) 1043 return true; 1044 1045 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1046 1047 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 1048 1049 // Otherwise create a symbol reference. 1050 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 1051 getContext()); 1052 1053 Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 1054 return false; 1055 } 1056 case AsmToken::Identifier: 1057 // Look for the existing symbol, we should check if 1058 // we need to assigne the propper RegisterKind. 1059 if (searchSymbolAlias(Operands, MipsOperand::Kind_None)) 1060 return false; 1061 // Else drop to expression parsing. 1062 case AsmToken::LParen: 1063 case AsmToken::Minus: 1064 case AsmToken::Plus: 1065 case AsmToken::Integer: 1066 case AsmToken::String: { 1067 // Quoted label names. 1068 const MCExpr *IdVal; 1069 SMLoc S = Parser.getTok().getLoc(); 1070 if (getParser().parseExpression(IdVal)) 1071 return true; 1072 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1073 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1074 return false; 1075 } 1076 case AsmToken::Percent: { 1077 // It is a symbol reference or constant expression. 1078 const MCExpr *IdVal; 1079 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1080 if (parseRelocOperand(IdVal)) 1081 return true; 1082 1083 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1084 1085 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1086 return false; 1087 } // case AsmToken::Percent 1088 } // switch(getLexer().getKind()) 1089 return true; 1090 } 1091 1092 const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 1093 StringRef RelocStr) { 1094 const MCExpr *Res; 1095 // Check the type of the expression. 1096 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 1097 // It's a constant, evaluate lo or hi value. 1098 if (RelocStr == "lo") { 1099 short Val = MCE->getValue(); 1100 Res = MCConstantExpr::Create(Val, getContext()); 1101 } else if (RelocStr == "hi") { 1102 int Val = MCE->getValue(); 1103 int LoSign = Val & 0x8000; 1104 Val = (Val & 0xffff0000) >> 16; 1105 // Lower part is treated as a signed int, so if it is negative 1106 // we must add 1 to the hi part to compensate. 1107 if (LoSign) 1108 Val++; 1109 Res = MCConstantExpr::Create(Val, getContext()); 1110 } else { 1111 llvm_unreachable("Invalid RelocStr value"); 1112 } 1113 return Res; 1114 } 1115 1116 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 1117 // It's a symbol, create a symbolic expression from the symbol. 1118 StringRef Symbol = MSRE->getSymbol().getName(); 1119 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1120 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 1121 return Res; 1122 } 1123 1124 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1125 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 1126 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 1127 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 1128 return Res; 1129 } 1130 1131 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 1132 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 1133 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 1134 return Res; 1135 } 1136 // Just return the original expression. 1137 return Expr; 1138 } 1139 1140 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 1141 1142 switch (Expr->getKind()) { 1143 case MCExpr::Constant: 1144 return true; 1145 case MCExpr::SymbolRef: 1146 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 1147 case MCExpr::Binary: 1148 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1149 if (!isEvaluated(BE->getLHS())) 1150 return false; 1151 return isEvaluated(BE->getRHS()); 1152 } 1153 case MCExpr::Unary: 1154 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1155 default: 1156 return false; 1157 } 1158 return false; 1159 } 1160 1161 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 1162 Parser.Lex(); // Eat the % token. 1163 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 1164 if (Tok.isNot(AsmToken::Identifier)) 1165 return true; 1166 1167 std::string Str = Tok.getIdentifier().str(); 1168 1169 Parser.Lex(); // Eat the identifier. 1170 // Now make an expression from the rest of the operand. 1171 const MCExpr *IdVal; 1172 SMLoc EndLoc; 1173 1174 if (getLexer().getKind() == AsmToken::LParen) { 1175 while (1) { 1176 Parser.Lex(); // Eat the '(' token. 1177 if (getLexer().getKind() == AsmToken::Percent) { 1178 Parser.Lex(); // Eat the % token. 1179 const AsmToken &nextTok = Parser.getTok(); 1180 if (nextTok.isNot(AsmToken::Identifier)) 1181 return true; 1182 Str += "(%"; 1183 Str += nextTok.getIdentifier(); 1184 Parser.Lex(); // Eat the identifier. 1185 if (getLexer().getKind() != AsmToken::LParen) 1186 return true; 1187 } else 1188 break; 1189 } 1190 if (getParser().parseParenExpression(IdVal, EndLoc)) 1191 return true; 1192 1193 while (getLexer().getKind() == AsmToken::RParen) 1194 Parser.Lex(); // Eat the ')' token. 1195 1196 } else 1197 return true; // Parenthesis must follow the relocation operand. 1198 1199 Res = evaluateRelocExpr(IdVal, Str); 1200 return false; 1201 } 1202 1203 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1204 SMLoc &EndLoc) { 1205 StartLoc = Parser.getTok().getLoc(); 1206 RegNo = tryParseRegister(isMips64()); 1207 EndLoc = Parser.getTok().getLoc(); 1208 return (RegNo == (unsigned) -1); 1209 } 1210 1211 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1212 SMLoc S; 1213 bool Result = true; 1214 1215 while (getLexer().getKind() == AsmToken::LParen) 1216 Parser.Lex(); 1217 1218 switch (getLexer().getKind()) { 1219 default: 1220 return true; 1221 case AsmToken::Identifier: 1222 case AsmToken::LParen: 1223 case AsmToken::Integer: 1224 case AsmToken::Minus: 1225 case AsmToken::Plus: 1226 if (isParenExpr) 1227 Result = getParser().parseParenExpression(Res, S); 1228 else 1229 Result = (getParser().parseExpression(Res)); 1230 while (getLexer().getKind() == AsmToken::RParen) 1231 Parser.Lex(); 1232 break; 1233 case AsmToken::Percent: 1234 Result = parseRelocOperand(Res); 1235 } 1236 return Result; 1237 } 1238 1239 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 1240 SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 1241 1242 const MCExpr *IdVal = 0; 1243 SMLoc S; 1244 bool isParenExpr = false; 1245 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 1246 // First operand is the offset. 1247 S = Parser.getTok().getLoc(); 1248 1249 if (getLexer().getKind() == AsmToken::LParen) { 1250 Parser.Lex(); 1251 isParenExpr = true; 1252 } 1253 1254 if (getLexer().getKind() != AsmToken::Dollar) { 1255 if (parseMemOffset(IdVal, isParenExpr)) 1256 return MatchOperand_ParseFail; 1257 1258 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1259 if (Tok.isNot(AsmToken::LParen)) { 1260 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 1261 if (Mnemonic->getToken() == "la") { 1262 SMLoc E = SMLoc::getFromPointer( 1263 Parser.getTok().getLoc().getPointer() - 1); 1264 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1265 return MatchOperand_Success; 1266 } 1267 if (Tok.is(AsmToken::EndOfStatement)) { 1268 SMLoc E = SMLoc::getFromPointer( 1269 Parser.getTok().getLoc().getPointer() - 1); 1270 1271 // Zero register assumed, add a memory operand with ZERO as its base. 1272 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64 1273 : Mips::ZERO, 1274 IdVal, S, E)); 1275 return MatchOperand_Success; 1276 } 1277 Error(Parser.getTok().getLoc(), "'(' expected"); 1278 return MatchOperand_ParseFail; 1279 } 1280 1281 Parser.Lex(); // Eat the '(' token. 1282 } 1283 1284 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64: 1285 (int) MipsOperand::Kind_GPR32); 1286 if (Res != MatchOperand_Success) 1287 return Res; 1288 1289 if (Parser.getTok().isNot(AsmToken::RParen)) { 1290 Error(Parser.getTok().getLoc(), "')' expected"); 1291 return MatchOperand_ParseFail; 1292 } 1293 1294 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1295 1296 Parser.Lex(); // Eat the ')' token. 1297 1298 if (IdVal == 0) 1299 IdVal = MCConstantExpr::Create(0, getContext()); 1300 1301 // Replace the register operand with the memory operand. 1302 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1303 int RegNo = op->getReg(); 1304 // Remove the register from the operands. 1305 Operands.pop_back(); 1306 // Add the memory operand. 1307 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 1308 int64_t Imm; 1309 if (IdVal->EvaluateAsAbsolute(Imm)) 1310 IdVal = MCConstantExpr::Create(Imm, getContext()); 1311 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 1312 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 1313 getContext()); 1314 } 1315 1316 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 1317 delete op; 1318 return MatchOperand_Success; 1319 } 1320 1321 bool 1322 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1323 int RegKind) { 1324 // If the first token is not '$' we have an error. 1325 if (Parser.getTok().isNot(AsmToken::Dollar)) 1326 return false; 1327 1328 SMLoc S = Parser.getTok().getLoc(); 1329 Parser.Lex(); 1330 AsmToken::TokenKind TkKind = getLexer().getKind(); 1331 int Reg; 1332 1333 if (TkKind == AsmToken::Integer) { 1334 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(), 1335 regKindToRegClass(RegKind)); 1336 if (Reg == -1) 1337 return false; 1338 } else if (TkKind == AsmToken::Identifier) { 1339 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1) 1340 return false; 1341 Reg = getReg(regKindToRegClass(RegKind), Reg); 1342 } else { 1343 return false; 1344 } 1345 1346 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc()); 1347 Op->setRegKind((MipsOperand::RegisterKind)RegKind); 1348 Operands.push_back(Op); 1349 Parser.Lex(); 1350 return true; 1351 } 1352 1353 MipsAsmParser::OperandMatchResultTy 1354 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1355 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 : 1356 MipsOperand::Kind_GPR32; 1357 1358 // Parse index register. 1359 if (!parsePtrReg(Operands, RegKind)) 1360 return MatchOperand_NoMatch; 1361 1362 // Parse '('. 1363 if (Parser.getTok().isNot(AsmToken::LParen)) 1364 return MatchOperand_NoMatch; 1365 1366 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1367 Parser.Lex(); 1368 1369 // Parse base register. 1370 if (!parsePtrReg(Operands, RegKind)) 1371 return MatchOperand_NoMatch; 1372 1373 // Parse ')'. 1374 if (Parser.getTok().isNot(AsmToken::RParen)) 1375 return MatchOperand_NoMatch; 1376 1377 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1378 Parser.Lex(); 1379 1380 return MatchOperand_Success; 1381 } 1382 1383 MipsAsmParser::OperandMatchResultTy 1384 MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1385 int RegKind) { 1386 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1387 if (getLexer().getKind() == AsmToken::Identifier 1388 && !hasConsumedDollar) { 1389 if (searchSymbolAlias(Operands, Kind)) 1390 return MatchOperand_Success; 1391 return MatchOperand_NoMatch; 1392 } 1393 SMLoc S = Parser.getTok().getLoc(); 1394 // If the first token is not '$', we have an error. 1395 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar) 1396 return MatchOperand_NoMatch; 1397 if (!hasConsumedDollar) { 1398 Parser.Lex(); // Eat the '$' 1399 hasConsumedDollar = true; 1400 } 1401 if (getLexer().getKind() == AsmToken::Identifier) { 1402 int RegNum = -1; 1403 std::string RegName = Parser.getTok().getString().lower(); 1404 // Match register by name 1405 switch (RegKind) { 1406 case MipsOperand::Kind_GPR32: 1407 case MipsOperand::Kind_GPR64: 1408 RegNum = matchCPURegisterName(RegName); 1409 break; 1410 case MipsOperand::Kind_AFGR64Regs: 1411 case MipsOperand::Kind_FGR64Regs: 1412 case MipsOperand::Kind_FGR32Regs: 1413 case MipsOperand::Kind_FGRH32Regs: 1414 RegNum = matchFPURegisterName(RegName); 1415 if (RegKind == MipsOperand::Kind_AFGR64Regs) 1416 RegNum /= 2; 1417 break; 1418 case MipsOperand::Kind_FCCRegs: 1419 RegNum = matchFCCRegisterName(RegName); 1420 break; 1421 case MipsOperand::Kind_ACC64DSP: 1422 RegNum = matchACRegisterName(RegName); 1423 break; 1424 default: break; // No match, value is set to -1. 1425 } 1426 // No match found, return _NoMatch to give a chance to other round. 1427 if (RegNum < 0) 1428 return MatchOperand_NoMatch; 1429 1430 int RegVal = getReg(regKindToRegClass(Kind), RegNum); 1431 if (RegVal == -1) 1432 return MatchOperand_NoMatch; 1433 1434 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, 1435 Parser.getTok().getLoc()); 1436 Op->setRegKind(Kind); 1437 Operands.push_back(Op); 1438 hasConsumedDollar = false; 1439 Parser.Lex(); // Eat the register name. 1440 if ((RegKind == MipsOperand::Kind_GPR32) 1441 && (getLexer().is(AsmToken::LParen))) { 1442 // Check if it is indexed addressing operand. 1443 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1444 Parser.Lex(); // Eat the parenthesis. 1445 if (parseRegs(Operands,RegKind) != MatchOperand_Success) 1446 return MatchOperand_NoMatch; 1447 if (getLexer().isNot(AsmToken::RParen)) 1448 return MatchOperand_NoMatch; 1449 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1450 Parser.Lex(); 1451 } 1452 return MatchOperand_Success; 1453 } else if (getLexer().getKind() == AsmToken::Integer) { 1454 unsigned RegNum = Parser.getTok().getIntVal(); 1455 if (Kind == MipsOperand::Kind_HWRegs) { 1456 if (RegNum != 29) 1457 return MatchOperand_NoMatch; 1458 // Only hwreg 29 is supported, found at index 0. 1459 RegNum = 0; 1460 } 1461 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind)); 1462 if (Reg == -1) 1463 return MatchOperand_NoMatch; 1464 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1465 Op->setRegKind(Kind); 1466 Operands.push_back(Op); 1467 hasConsumedDollar = false; 1468 Parser.Lex(); // Eat the register number. 1469 if ((RegKind == MipsOperand::Kind_GPR32) 1470 && (getLexer().is(AsmToken::LParen))) { 1471 // Check if it is indexed addressing operand. 1472 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1473 Parser.Lex(); // Eat the parenthesis. 1474 if (parseRegs(Operands,RegKind) != MatchOperand_Success) 1475 return MatchOperand_NoMatch; 1476 if (getLexer().isNot(AsmToken::RParen)) 1477 return MatchOperand_NoMatch; 1478 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1479 Parser.Lex(); 1480 } 1481 return MatchOperand_Success; 1482 } 1483 return MatchOperand_NoMatch; 1484 } 1485 1486 MipsAsmParser::OperandMatchResultTy 1487 MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1488 1489 if (!isMips64()) 1490 return MatchOperand_NoMatch; 1491 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64); 1492 } 1493 1494 MipsAsmParser::OperandMatchResultTy 1495 MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1496 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32); 1497 } 1498 1499 MipsAsmParser::OperandMatchResultTy 1500 MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1501 1502 if (isFP64()) 1503 return MatchOperand_NoMatch; 1504 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs); 1505 } 1506 1507 MipsAsmParser::OperandMatchResultTy 1508 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1509 if (!isFP64()) 1510 return MatchOperand_NoMatch; 1511 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs); 1512 } 1513 1514 MipsAsmParser::OperandMatchResultTy 1515 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1516 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs); 1517 } 1518 1519 MipsAsmParser::OperandMatchResultTy 1520 MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1521 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs); 1522 } 1523 1524 MipsAsmParser::OperandMatchResultTy 1525 MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1526 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs); 1527 } 1528 1529 MipsAsmParser::OperandMatchResultTy 1530 MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1531 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP); 1532 } 1533 1534 MipsAsmParser::OperandMatchResultTy 1535 MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1536 // If the first token is not '$' we have an error. 1537 if (Parser.getTok().isNot(AsmToken::Dollar)) 1538 return MatchOperand_NoMatch; 1539 1540 SMLoc S = Parser.getTok().getLoc(); 1541 Parser.Lex(); // Eat the '$' 1542 1543 const AsmToken &Tok = Parser.getTok(); // Get next token. 1544 1545 if (Tok.isNot(AsmToken::Identifier)) 1546 return MatchOperand_NoMatch; 1547 1548 if (!Tok.getIdentifier().startswith("ac")) 1549 return MatchOperand_NoMatch; 1550 1551 StringRef NumString = Tok.getIdentifier().substr(2); 1552 1553 unsigned IntVal; 1554 if (NumString.getAsInteger(10, IntVal)) 1555 return MatchOperand_NoMatch; 1556 1557 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID); 1558 1559 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1560 Op->setRegKind(MipsOperand::Kind_LO32DSP); 1561 Operands.push_back(Op); 1562 1563 Parser.Lex(); // Eat the register number. 1564 return MatchOperand_Success; 1565 } 1566 1567 MipsAsmParser::OperandMatchResultTy 1568 MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1569 // If the first token is not '$' we have an error. 1570 if (Parser.getTok().isNot(AsmToken::Dollar)) 1571 return MatchOperand_NoMatch; 1572 1573 SMLoc S = Parser.getTok().getLoc(); 1574 Parser.Lex(); // Eat the '$' 1575 1576 const AsmToken &Tok = Parser.getTok(); // Get next token. 1577 1578 if (Tok.isNot(AsmToken::Identifier)) 1579 return MatchOperand_NoMatch; 1580 1581 if (!Tok.getIdentifier().startswith("ac")) 1582 return MatchOperand_NoMatch; 1583 1584 StringRef NumString = Tok.getIdentifier().substr(2); 1585 1586 unsigned IntVal; 1587 if (NumString.getAsInteger(10, IntVal)) 1588 return MatchOperand_NoMatch; 1589 1590 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID); 1591 1592 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1593 Op->setRegKind(MipsOperand::Kind_HI32DSP); 1594 Operands.push_back(Op); 1595 1596 Parser.Lex(); // Eat the register number. 1597 return MatchOperand_Success; 1598 } 1599 1600 bool MipsAsmParser::searchSymbolAlias( 1601 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) { 1602 1603 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1604 if (Sym) { 1605 SMLoc S = Parser.getTok().getLoc(); 1606 const MCExpr *Expr; 1607 if (Sym->isVariable()) 1608 Expr = Sym->getVariableValue(); 1609 else 1610 return false; 1611 if (Expr->getKind() == MCExpr::SymbolRef) { 1612 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind; 1613 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1614 const StringRef DefSymbol = Ref->getSymbol().getName(); 1615 if (DefSymbol.startswith("$")) { 1616 int RegNum = -1; 1617 APInt IntVal(32, -1); 1618 if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) 1619 RegNum = matchRegisterByNumber(IntVal.getZExtValue(), 1620 isMips64() 1621 ? Mips::GPR64RegClassID 1622 : Mips::GPR32RegClassID); 1623 else { 1624 // Lookup for the register with the corresponding name. 1625 switch (Kind) { 1626 case MipsOperand::Kind_AFGR64Regs: 1627 case MipsOperand::Kind_FGR64Regs: 1628 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1629 break; 1630 case MipsOperand::Kind_FGR32Regs: 1631 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1632 break; 1633 case MipsOperand::Kind_GPR64: 1634 case MipsOperand::Kind_GPR32: 1635 default: 1636 RegNum = matchCPURegisterName(DefSymbol.substr(1)); 1637 break; 1638 } 1639 if (RegNum > -1) 1640 RegNum = getReg(regKindToRegClass(Kind), RegNum); 1641 } 1642 if (RegNum > -1) { 1643 Parser.Lex(); 1644 MipsOperand *op = MipsOperand::CreateReg(RegNum, S, 1645 Parser.getTok().getLoc()); 1646 op->setRegKind(Kind); 1647 Operands.push_back(op); 1648 return true; 1649 } 1650 } 1651 } else if (Expr->getKind() == MCExpr::Constant) { 1652 Parser.Lex(); 1653 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 1654 MipsOperand *op = MipsOperand::CreateImm(Const, S, 1655 Parser.getTok().getLoc()); 1656 Operands.push_back(op); 1657 return true; 1658 } 1659 } 1660 return false; 1661 } 1662 1663 MipsAsmParser::OperandMatchResultTy 1664 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1665 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs); 1666 } 1667 1668 MipsAsmParser::OperandMatchResultTy 1669 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1670 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs); 1671 } 1672 1673 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1674 1675 MCSymbolRefExpr::VariantKind VK 1676 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1677 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1678 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1679 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1680 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1681 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1682 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1683 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1684 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1685 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1686 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1687 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1688 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1689 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1690 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1691 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1692 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1693 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1694 .Default(MCSymbolRefExpr::VK_None); 1695 1696 return VK; 1697 } 1698 1699 bool MipsAsmParser:: 1700 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1701 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1702 // Check if we have valid mnemonic 1703 if (!mnemonicIsValid(Name, 0)) { 1704 Parser.eatToEndOfStatement(); 1705 return Error(NameLoc, "Unknown instruction"); 1706 } 1707 // First operand in MCInst is instruction mnemonic. 1708 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1709 1710 // Read the remaining operands. 1711 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1712 // Read the first operand. 1713 if (ParseOperand(Operands, Name)) { 1714 SMLoc Loc = getLexer().getLoc(); 1715 Parser.eatToEndOfStatement(); 1716 return Error(Loc, "unexpected token in argument list"); 1717 } 1718 1719 while (getLexer().is(AsmToken::Comma)) { 1720 Parser.Lex(); // Eat the comma. 1721 // Parse and remember the operand. 1722 if (ParseOperand(Operands, Name)) { 1723 SMLoc Loc = getLexer().getLoc(); 1724 Parser.eatToEndOfStatement(); 1725 return Error(Loc, "unexpected token in argument list"); 1726 } 1727 } 1728 } 1729 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1730 SMLoc Loc = getLexer().getLoc(); 1731 Parser.eatToEndOfStatement(); 1732 return Error(Loc, "unexpected token in argument list"); 1733 } 1734 Parser.Lex(); // Consume the EndOfStatement. 1735 return false; 1736 } 1737 1738 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1739 SMLoc Loc = getLexer().getLoc(); 1740 Parser.eatToEndOfStatement(); 1741 return Error(Loc, ErrorMsg); 1742 } 1743 1744 bool MipsAsmParser::parseSetNoAtDirective() { 1745 // Line should look like: ".set noat". 1746 // set at reg to 0. 1747 Options.setATReg(0); 1748 // eat noat 1749 Parser.Lex(); 1750 // If this is not the end of the statement, report an error. 1751 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1752 reportParseError("unexpected token in statement"); 1753 return false; 1754 } 1755 Parser.Lex(); // Consume the EndOfStatement. 1756 return false; 1757 } 1758 1759 bool MipsAsmParser::parseSetAtDirective() { 1760 // Line can be .set at - defaults to $1 1761 // or .set at=$reg 1762 int AtRegNo; 1763 getParser().Lex(); 1764 if (getLexer().is(AsmToken::EndOfStatement)) { 1765 Options.setATReg(1); 1766 Parser.Lex(); // Consume the EndOfStatement. 1767 return false; 1768 } else if (getLexer().is(AsmToken::Equal)) { 1769 getParser().Lex(); // Eat the '='. 1770 if (getLexer().isNot(AsmToken::Dollar)) { 1771 reportParseError("unexpected token in statement"); 1772 return false; 1773 } 1774 Parser.Lex(); // Eat the '$'. 1775 const AsmToken &Reg = Parser.getTok(); 1776 if (Reg.is(AsmToken::Identifier)) { 1777 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 1778 } else if (Reg.is(AsmToken::Integer)) { 1779 AtRegNo = Reg.getIntVal(); 1780 } else { 1781 reportParseError("unexpected token in statement"); 1782 return false; 1783 } 1784 1785 if (AtRegNo < 1 || AtRegNo > 31) { 1786 reportParseError("unexpected token in statement"); 1787 return false; 1788 } 1789 1790 if (!Options.setATReg(AtRegNo)) { 1791 reportParseError("unexpected token in statement"); 1792 return false; 1793 } 1794 getParser().Lex(); // Eat the register. 1795 1796 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1797 reportParseError("unexpected token in statement"); 1798 return false; 1799 } 1800 Parser.Lex(); // Consume the EndOfStatement. 1801 return false; 1802 } else { 1803 reportParseError("unexpected token in statement"); 1804 return false; 1805 } 1806 } 1807 1808 bool MipsAsmParser::parseSetReorderDirective() { 1809 Parser.Lex(); 1810 // If this is not the end of the statement, report an error. 1811 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1812 reportParseError("unexpected token in statement"); 1813 return false; 1814 } 1815 Options.setReorder(); 1816 Parser.Lex(); // Consume the EndOfStatement. 1817 return false; 1818 } 1819 1820 bool MipsAsmParser::parseSetNoReorderDirective() { 1821 Parser.Lex(); 1822 // If this is not the end of the statement, report an error. 1823 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1824 reportParseError("unexpected token in statement"); 1825 return false; 1826 } 1827 Options.setNoreorder(); 1828 Parser.Lex(); // Consume the EndOfStatement. 1829 return false; 1830 } 1831 1832 bool MipsAsmParser::parseSetMacroDirective() { 1833 Parser.Lex(); 1834 // If this is not the end of the statement, report an error. 1835 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1836 reportParseError("unexpected token in statement"); 1837 return false; 1838 } 1839 Options.setMacro(); 1840 Parser.Lex(); // Consume the EndOfStatement. 1841 return false; 1842 } 1843 1844 bool MipsAsmParser::parseSetNoMacroDirective() { 1845 Parser.Lex(); 1846 // If this is not the end of the statement, report an error. 1847 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1848 reportParseError("`noreorder' must be set before `nomacro'"); 1849 return false; 1850 } 1851 if (Options.isReorder()) { 1852 reportParseError("`noreorder' must be set before `nomacro'"); 1853 return false; 1854 } 1855 Options.setNomacro(); 1856 Parser.Lex(); // Consume the EndOfStatement. 1857 return false; 1858 } 1859 1860 bool MipsAsmParser::parseSetAssignment() { 1861 StringRef Name; 1862 const MCExpr *Value; 1863 1864 if (Parser.parseIdentifier(Name)) 1865 reportParseError("expected identifier after .set"); 1866 1867 if (getLexer().isNot(AsmToken::Comma)) 1868 return reportParseError("unexpected token in .set directive"); 1869 Lex(); // Eat comma 1870 1871 if (getLexer().is(AsmToken::Dollar)) { 1872 MCSymbol *Symbol; 1873 SMLoc DollarLoc = getLexer().getLoc(); 1874 // Consume the dollar sign, and check for a following identifier. 1875 Parser.Lex(); 1876 // We have a '$' followed by something, make sure they are adjacent. 1877 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1878 return true; 1879 StringRef Res = StringRef(DollarLoc.getPointer(), 1880 getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); 1881 Symbol = getContext().GetOrCreateSymbol(Res); 1882 Parser.Lex(); 1883 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 1884 getContext()); 1885 } else if (Parser.parseExpression(Value)) 1886 return reportParseError("expected valid expression after comma"); 1887 1888 // Check if the Name already exists as a symbol. 1889 MCSymbol *Sym = getContext().LookupSymbol(Name); 1890 if (Sym) 1891 return reportParseError("symbol already defined"); 1892 Sym = getContext().GetOrCreateSymbol(Name); 1893 Sym->setVariableValue(Value); 1894 1895 return false; 1896 } 1897 1898 bool MipsAsmParser::parseDirectiveSet() { 1899 1900 // Get the next token. 1901 const AsmToken &Tok = Parser.getTok(); 1902 1903 if (Tok.getString() == "noat") { 1904 return parseSetNoAtDirective(); 1905 } else if (Tok.getString() == "at") { 1906 return parseSetAtDirective(); 1907 } else if (Tok.getString() == "reorder") { 1908 return parseSetReorderDirective(); 1909 } else if (Tok.getString() == "noreorder") { 1910 return parseSetNoReorderDirective(); 1911 } else if (Tok.getString() == "macro") { 1912 return parseSetMacroDirective(); 1913 } else if (Tok.getString() == "nomacro") { 1914 return parseSetNoMacroDirective(); 1915 } else if (Tok.getString() == "nomips16") { 1916 // Ignore this directive for now. 1917 Parser.eatToEndOfStatement(); 1918 return false; 1919 } else if (Tok.getString() == "nomicromips") { 1920 // Ignore this directive for now. 1921 Parser.eatToEndOfStatement(); 1922 return false; 1923 } else { 1924 // It is just an identifier, look for an assignment. 1925 parseSetAssignment(); 1926 return false; 1927 } 1928 1929 return true; 1930 } 1931 1932 /// parseDirectiveWord 1933 /// ::= .word [ expression (, expression)* ] 1934 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1935 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1936 for (;;) { 1937 const MCExpr *Value; 1938 if (getParser().parseExpression(Value)) 1939 return true; 1940 1941 getParser().getStreamer().EmitValue(Value, Size); 1942 1943 if (getLexer().is(AsmToken::EndOfStatement)) 1944 break; 1945 1946 // FIXME: Improve diagnostic. 1947 if (getLexer().isNot(AsmToken::Comma)) 1948 return Error(L, "unexpected token in directive"); 1949 Parser.Lex(); 1950 } 1951 } 1952 1953 Parser.Lex(); 1954 return false; 1955 } 1956 1957 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1958 1959 StringRef IDVal = DirectiveID.getString(); 1960 1961 if (IDVal == ".ent") { 1962 // Ignore this directive for now. 1963 Parser.Lex(); 1964 return false; 1965 } 1966 1967 if (IDVal == ".end") { 1968 // Ignore this directive for now. 1969 Parser.Lex(); 1970 return false; 1971 } 1972 1973 if (IDVal == ".frame") { 1974 // Ignore this directive for now. 1975 Parser.eatToEndOfStatement(); 1976 return false; 1977 } 1978 1979 if (IDVal == ".set") { 1980 return parseDirectiveSet(); 1981 } 1982 1983 if (IDVal == ".fmask") { 1984 // Ignore this directive for now. 1985 Parser.eatToEndOfStatement(); 1986 return false; 1987 } 1988 1989 if (IDVal == ".mask") { 1990 // Ignore this directive for now. 1991 Parser.eatToEndOfStatement(); 1992 return false; 1993 } 1994 1995 if (IDVal == ".gpword") { 1996 // Ignore this directive for now. 1997 Parser.eatToEndOfStatement(); 1998 return false; 1999 } 2000 2001 if (IDVal == ".word") { 2002 parseDirectiveWord(4, DirectiveID.getLoc()); 2003 return false; 2004 } 2005 2006 return true; 2007 } 2008 2009 extern "C" void LLVMInitializeMipsAsmParser() { 2010 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 2011 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 2012 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 2013 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 2014 } 2015 2016 #define GET_REGISTER_MATCHER 2017 #define GET_MATCHER_IMPLEMENTATION 2018 #include "MipsGenAsmMatcher.inc" 2019