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