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