MipsAsmParser.cpp revision b15da6dc09fdf2699146cd4317f3a43e70397553
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 else if (RegKind == MipsOperand::Kind_FGRH32Regs 1408 && !isFP64()) 1409 if (RegNum != -1 && RegNum %2 != 0) 1410 Warning(S, "Float register should be even."); 1411 break; 1412 case MipsOperand::Kind_FCCRegs: 1413 RegNum = matchFCCRegisterName(RegName); 1414 break; 1415 case MipsOperand::Kind_ACC64DSP: 1416 RegNum = matchACRegisterName(RegName); 1417 break; 1418 default: break; // No match, value is set to -1. 1419 } 1420 // No match found, return _NoMatch to give a chance to other round. 1421 if (RegNum < 0) 1422 return MatchOperand_NoMatch; 1423 1424 int RegVal = getReg(regKindToRegClass(Kind), RegNum); 1425 if (RegVal == -1) 1426 return MatchOperand_NoMatch; 1427 1428 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, 1429 Parser.getTok().getLoc()); 1430 Op->setRegKind(Kind); 1431 Operands.push_back(Op); 1432 hasConsumedDollar = false; 1433 Parser.Lex(); // Eat the register name. 1434 return MatchOperand_Success; 1435 } else if (getLexer().getKind() == AsmToken::Integer) { 1436 unsigned RegNum = Parser.getTok().getIntVal(); 1437 if (Kind == MipsOperand::Kind_HWRegs) { 1438 if (RegNum != 29) 1439 return MatchOperand_NoMatch; 1440 // Only hwreg 29 is supported, found at index 0. 1441 RegNum = 0; 1442 } 1443 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind)); 1444 if (Reg == -1) 1445 return MatchOperand_NoMatch; 1446 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1447 Op->setRegKind(Kind); 1448 Operands.push_back(Op); 1449 hasConsumedDollar = false; 1450 Parser.Lex(); // Eat the register number. 1451 if ((RegKind == MipsOperand::Kind_GPR32) 1452 && (getLexer().is(AsmToken::LParen))) { 1453 // Check if it is indexed addressing operand. 1454 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1455 Parser.Lex(); // Eat the parenthesis. 1456 if (parseRegs(Operands,RegKind) != MatchOperand_Success) 1457 return MatchOperand_NoMatch; 1458 if (getLexer().isNot(AsmToken::RParen)) 1459 return MatchOperand_NoMatch; 1460 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1461 Parser.Lex(); 1462 } 1463 return MatchOperand_Success; 1464 } 1465 return MatchOperand_NoMatch; 1466} 1467 1468MipsAsmParser::OperandMatchResultTy 1469MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1470 1471 if (!isMips64()) 1472 return MatchOperand_NoMatch; 1473 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64); 1474} 1475 1476MipsAsmParser::OperandMatchResultTy 1477MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1478 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32); 1479} 1480 1481MipsAsmParser::OperandMatchResultTy 1482MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1483 1484 if (isFP64()) 1485 return MatchOperand_NoMatch; 1486 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs); 1487} 1488 1489MipsAsmParser::OperandMatchResultTy 1490MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1491 if (!isFP64()) 1492 return MatchOperand_NoMatch; 1493 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs); 1494} 1495 1496MipsAsmParser::OperandMatchResultTy 1497MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1498 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs); 1499} 1500 1501MipsAsmParser::OperandMatchResultTy 1502MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1503 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs); 1504} 1505 1506MipsAsmParser::OperandMatchResultTy 1507MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1508 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs); 1509} 1510 1511MipsAsmParser::OperandMatchResultTy 1512MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1513 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP); 1514} 1515 1516MipsAsmParser::OperandMatchResultTy 1517MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1518 // If the first token is not '$' we have an error. 1519 if (Parser.getTok().isNot(AsmToken::Dollar)) 1520 return MatchOperand_NoMatch; 1521 1522 SMLoc S = Parser.getTok().getLoc(); 1523 Parser.Lex(); // Eat the '$' 1524 1525 const AsmToken &Tok = Parser.getTok(); // Get next token. 1526 1527 if (Tok.isNot(AsmToken::Identifier)) 1528 return MatchOperand_NoMatch; 1529 1530 if (!Tok.getIdentifier().startswith("ac")) 1531 return MatchOperand_NoMatch; 1532 1533 StringRef NumString = Tok.getIdentifier().substr(2); 1534 1535 unsigned IntVal; 1536 if (NumString.getAsInteger(10, IntVal)) 1537 return MatchOperand_NoMatch; 1538 1539 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID); 1540 1541 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1542 Op->setRegKind(MipsOperand::Kind_LO32DSP); 1543 Operands.push_back(Op); 1544 1545 Parser.Lex(); // Eat the register number. 1546 return MatchOperand_Success; 1547} 1548 1549MipsAsmParser::OperandMatchResultTy 1550MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1551 // If the first token is not '$' we have an error. 1552 if (Parser.getTok().isNot(AsmToken::Dollar)) 1553 return MatchOperand_NoMatch; 1554 1555 SMLoc S = Parser.getTok().getLoc(); 1556 Parser.Lex(); // Eat the '$' 1557 1558 const AsmToken &Tok = Parser.getTok(); // Get next token. 1559 1560 if (Tok.isNot(AsmToken::Identifier)) 1561 return MatchOperand_NoMatch; 1562 1563 if (!Tok.getIdentifier().startswith("ac")) 1564 return MatchOperand_NoMatch; 1565 1566 StringRef NumString = Tok.getIdentifier().substr(2); 1567 1568 unsigned IntVal; 1569 if (NumString.getAsInteger(10, IntVal)) 1570 return MatchOperand_NoMatch; 1571 1572 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID); 1573 1574 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1575 Op->setRegKind(MipsOperand::Kind_HI32DSP); 1576 Operands.push_back(Op); 1577 1578 Parser.Lex(); // Eat the register number. 1579 return MatchOperand_Success; 1580} 1581 1582bool MipsAsmParser::searchSymbolAlias( 1583 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) { 1584 1585 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1586 if (Sym) { 1587 SMLoc S = Parser.getTok().getLoc(); 1588 const MCExpr *Expr; 1589 if (Sym->isVariable()) 1590 Expr = Sym->getVariableValue(); 1591 else 1592 return false; 1593 if (Expr->getKind() == MCExpr::SymbolRef) { 1594 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind; 1595 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1596 const StringRef DefSymbol = Ref->getSymbol().getName(); 1597 if (DefSymbol.startswith("$")) { 1598 int RegNum = -1; 1599 APInt IntVal(32, -1); 1600 if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) 1601 RegNum = matchRegisterByNumber(IntVal.getZExtValue(), 1602 isMips64() 1603 ? Mips::GPR64RegClassID 1604 : Mips::GPR32RegClassID); 1605 else { 1606 // Lookup for the register with the corresponding name. 1607 switch (Kind) { 1608 case MipsOperand::Kind_AFGR64Regs: 1609 case MipsOperand::Kind_FGR64Regs: 1610 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1611 break; 1612 case MipsOperand::Kind_FGR32Regs: 1613 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1614 break; 1615 case MipsOperand::Kind_GPR64: 1616 case MipsOperand::Kind_GPR32: 1617 default: 1618 RegNum = matchCPURegisterName(DefSymbol.substr(1)); 1619 break; 1620 } 1621 if (RegNum > -1) 1622 RegNum = getReg(regKindToRegClass(Kind), RegNum); 1623 } 1624 if (RegNum > -1) { 1625 Parser.Lex(); 1626 MipsOperand *op = MipsOperand::CreateReg(RegNum, S, 1627 Parser.getTok().getLoc()); 1628 op->setRegKind(Kind); 1629 Operands.push_back(op); 1630 return true; 1631 } 1632 } 1633 } else if (Expr->getKind() == MCExpr::Constant) { 1634 Parser.Lex(); 1635 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 1636 MipsOperand *op = MipsOperand::CreateImm(Const, S, 1637 Parser.getTok().getLoc()); 1638 Operands.push_back(op); 1639 return true; 1640 } 1641 } 1642 return false; 1643} 1644 1645MipsAsmParser::OperandMatchResultTy 1646MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1647 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs); 1648} 1649 1650MipsAsmParser::OperandMatchResultTy 1651MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1652 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs); 1653} 1654 1655MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1656 1657 MCSymbolRefExpr::VariantKind VK 1658 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1659 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1660 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1661 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1662 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1663 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1664 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1665 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1666 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1667 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1668 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1669 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1670 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1671 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1672 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1673 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1674 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1675 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1676 .Default(MCSymbolRefExpr::VK_None); 1677 1678 return VK; 1679} 1680 1681bool MipsAsmParser:: 1682ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1683 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1684 // Check if we have valid mnemonic 1685 if (!mnemonicIsValid(Name, 0)) { 1686 Parser.eatToEndOfStatement(); 1687 return Error(NameLoc, "Unknown instruction"); 1688 } 1689 // First operand in MCInst is instruction mnemonic. 1690 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1691 1692 // Read the remaining operands. 1693 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1694 // Read the first operand. 1695 if (ParseOperand(Operands, Name)) { 1696 SMLoc Loc = getLexer().getLoc(); 1697 Parser.eatToEndOfStatement(); 1698 return Error(Loc, "unexpected token in argument list"); 1699 } 1700 1701 while (getLexer().is(AsmToken::Comma)) { 1702 Parser.Lex(); // Eat the comma. 1703 // Parse and remember the operand. 1704 if (ParseOperand(Operands, Name)) { 1705 SMLoc Loc = getLexer().getLoc(); 1706 Parser.eatToEndOfStatement(); 1707 return Error(Loc, "unexpected token in argument list"); 1708 } 1709 } 1710 } 1711 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1712 SMLoc Loc = getLexer().getLoc(); 1713 Parser.eatToEndOfStatement(); 1714 return Error(Loc, "unexpected token in argument list"); 1715 } 1716 Parser.Lex(); // Consume the EndOfStatement. 1717 return false; 1718} 1719 1720bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1721 SMLoc Loc = getLexer().getLoc(); 1722 Parser.eatToEndOfStatement(); 1723 return Error(Loc, ErrorMsg); 1724} 1725 1726bool MipsAsmParser::parseSetNoAtDirective() { 1727 // Line should look like: ".set noat". 1728 // set at reg to 0. 1729 Options.setATReg(0); 1730 // eat noat 1731 Parser.Lex(); 1732 // If this is not the end of the statement, report an error. 1733 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1734 reportParseError("unexpected token in statement"); 1735 return false; 1736 } 1737 Parser.Lex(); // Consume the EndOfStatement. 1738 return false; 1739} 1740 1741bool MipsAsmParser::parseSetAtDirective() { 1742 // Line can be .set at - defaults to $1 1743 // or .set at=$reg 1744 int AtRegNo; 1745 getParser().Lex(); 1746 if (getLexer().is(AsmToken::EndOfStatement)) { 1747 Options.setATReg(1); 1748 Parser.Lex(); // Consume the EndOfStatement. 1749 return false; 1750 } else if (getLexer().is(AsmToken::Equal)) { 1751 getParser().Lex(); // Eat the '='. 1752 if (getLexer().isNot(AsmToken::Dollar)) { 1753 reportParseError("unexpected token in statement"); 1754 return false; 1755 } 1756 Parser.Lex(); // Eat the '$'. 1757 const AsmToken &Reg = Parser.getTok(); 1758 if (Reg.is(AsmToken::Identifier)) { 1759 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 1760 } else if (Reg.is(AsmToken::Integer)) { 1761 AtRegNo = Reg.getIntVal(); 1762 } else { 1763 reportParseError("unexpected token in statement"); 1764 return false; 1765 } 1766 1767 if (AtRegNo < 1 || AtRegNo > 31) { 1768 reportParseError("unexpected token in statement"); 1769 return false; 1770 } 1771 1772 if (!Options.setATReg(AtRegNo)) { 1773 reportParseError("unexpected token in statement"); 1774 return false; 1775 } 1776 getParser().Lex(); // Eat the register. 1777 1778 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1779 reportParseError("unexpected token in statement"); 1780 return false; 1781 } 1782 Parser.Lex(); // Consume the EndOfStatement. 1783 return false; 1784 } else { 1785 reportParseError("unexpected token in statement"); 1786 return false; 1787 } 1788} 1789 1790bool MipsAsmParser::parseSetReorderDirective() { 1791 Parser.Lex(); 1792 // If this is not the end of the statement, report an error. 1793 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1794 reportParseError("unexpected token in statement"); 1795 return false; 1796 } 1797 Options.setReorder(); 1798 Parser.Lex(); // Consume the EndOfStatement. 1799 return false; 1800} 1801 1802bool MipsAsmParser::parseSetNoReorderDirective() { 1803 Parser.Lex(); 1804 // If this is not the end of the statement, report an error. 1805 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1806 reportParseError("unexpected token in statement"); 1807 return false; 1808 } 1809 Options.setNoreorder(); 1810 Parser.Lex(); // Consume the EndOfStatement. 1811 return false; 1812} 1813 1814bool MipsAsmParser::parseSetMacroDirective() { 1815 Parser.Lex(); 1816 // If this is not the end of the statement, report an error. 1817 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1818 reportParseError("unexpected token in statement"); 1819 return false; 1820 } 1821 Options.setMacro(); 1822 Parser.Lex(); // Consume the EndOfStatement. 1823 return false; 1824} 1825 1826bool MipsAsmParser::parseSetNoMacroDirective() { 1827 Parser.Lex(); 1828 // If this is not the end of the statement, report an error. 1829 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1830 reportParseError("`noreorder' must be set before `nomacro'"); 1831 return false; 1832 } 1833 if (Options.isReorder()) { 1834 reportParseError("`noreorder' must be set before `nomacro'"); 1835 return false; 1836 } 1837 Options.setNomacro(); 1838 Parser.Lex(); // Consume the EndOfStatement. 1839 return false; 1840} 1841 1842bool MipsAsmParser::parseSetAssignment() { 1843 StringRef Name; 1844 const MCExpr *Value; 1845 1846 if (Parser.parseIdentifier(Name)) 1847 reportParseError("expected identifier after .set"); 1848 1849 if (getLexer().isNot(AsmToken::Comma)) 1850 return reportParseError("unexpected token in .set directive"); 1851 Lex(); // Eat comma 1852 1853 if (getLexer().is(AsmToken::Dollar)) { 1854 MCSymbol *Symbol; 1855 SMLoc DollarLoc = getLexer().getLoc(); 1856 // Consume the dollar sign, and check for a following identifier. 1857 Parser.Lex(); 1858 // We have a '$' followed by something, make sure they are adjacent. 1859 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1860 return true; 1861 StringRef Res = StringRef(DollarLoc.getPointer(), 1862 getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); 1863 Symbol = getContext().GetOrCreateSymbol(Res); 1864 Parser.Lex(); 1865 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 1866 getContext()); 1867 } else if (Parser.parseExpression(Value)) 1868 return reportParseError("expected valid expression after comma"); 1869 1870 // Check if the Name already exists as a symbol. 1871 MCSymbol *Sym = getContext().LookupSymbol(Name); 1872 if (Sym) 1873 return reportParseError("symbol already defined"); 1874 Sym = getContext().GetOrCreateSymbol(Name); 1875 Sym->setVariableValue(Value); 1876 1877 return false; 1878} 1879 1880bool MipsAsmParser::parseDirectiveSet() { 1881 1882 // Get the next token. 1883 const AsmToken &Tok = Parser.getTok(); 1884 1885 if (Tok.getString() == "noat") { 1886 return parseSetNoAtDirective(); 1887 } else if (Tok.getString() == "at") { 1888 return parseSetAtDirective(); 1889 } else if (Tok.getString() == "reorder") { 1890 return parseSetReorderDirective(); 1891 } else if (Tok.getString() == "noreorder") { 1892 return parseSetNoReorderDirective(); 1893 } else if (Tok.getString() == "macro") { 1894 return parseSetMacroDirective(); 1895 } else if (Tok.getString() == "nomacro") { 1896 return parseSetNoMacroDirective(); 1897 } else if (Tok.getString() == "nomips16") { 1898 // Ignore this directive for now. 1899 Parser.eatToEndOfStatement(); 1900 return false; 1901 } else if (Tok.getString() == "nomicromips") { 1902 // Ignore this directive for now. 1903 Parser.eatToEndOfStatement(); 1904 return false; 1905 } else { 1906 // It is just an identifier, look for an assignment. 1907 parseSetAssignment(); 1908 return false; 1909 } 1910 1911 return true; 1912} 1913 1914/// parseDirectiveWord 1915/// ::= .word [ expression (, expression)* ] 1916bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1917 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1918 for (;;) { 1919 const MCExpr *Value; 1920 if (getParser().parseExpression(Value)) 1921 return true; 1922 1923 getParser().getStreamer().EmitValue(Value, Size); 1924 1925 if (getLexer().is(AsmToken::EndOfStatement)) 1926 break; 1927 1928 // FIXME: Improve diagnostic. 1929 if (getLexer().isNot(AsmToken::Comma)) 1930 return Error(L, "unexpected token in directive"); 1931 Parser.Lex(); 1932 } 1933 } 1934 1935 Parser.Lex(); 1936 return false; 1937} 1938 1939bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1940 1941 StringRef IDVal = DirectiveID.getString(); 1942 1943 if (IDVal == ".ent") { 1944 // Ignore this directive for now. 1945 Parser.Lex(); 1946 return false; 1947 } 1948 1949 if (IDVal == ".end") { 1950 // Ignore this directive for now. 1951 Parser.Lex(); 1952 return false; 1953 } 1954 1955 if (IDVal == ".frame") { 1956 // Ignore this directive for now. 1957 Parser.eatToEndOfStatement(); 1958 return false; 1959 } 1960 1961 if (IDVal == ".set") { 1962 return parseDirectiveSet(); 1963 } 1964 1965 if (IDVal == ".fmask") { 1966 // Ignore this directive for now. 1967 Parser.eatToEndOfStatement(); 1968 return false; 1969 } 1970 1971 if (IDVal == ".mask") { 1972 // Ignore this directive for now. 1973 Parser.eatToEndOfStatement(); 1974 return false; 1975 } 1976 1977 if (IDVal == ".gpword") { 1978 // Ignore this directive for now. 1979 Parser.eatToEndOfStatement(); 1980 return false; 1981 } 1982 1983 if (IDVal == ".word") { 1984 parseDirectiveWord(4, DirectiveID.getLoc()); 1985 return false; 1986 } 1987 1988 return true; 1989} 1990 1991extern "C" void LLVMInitializeMipsAsmParser() { 1992 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1993 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1994 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1995 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1996} 1997 1998#define GET_REGISTER_MATCHER 1999#define GET_MATCHER_IMPLEMENTATION 2000#include "MipsGenAsmMatcher.inc" 2001