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