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