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/MipsMCExpr.h" 11 #include "MCTargetDesc/MipsMCTargetDesc.h" 12 #include "MipsRegisterInfo.h" 13 #include "MipsTargetStreamer.h" 14 #include "llvm/ADT/APInt.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCInstBuilder.h" 20 #include "llvm/MC/MCParser/MCAsmLexer.h" 21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 22 #include "llvm/MC/MCStreamer.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/MC/MCSymbol.h" 25 #include "llvm/MC/MCTargetAsmParser.h" 26 #include "llvm/Support/Debug.h" 27 #include "llvm/Support/MathExtras.h" 28 #include "llvm/Support/TargetRegistry.h" 29 30 using namespace llvm; 31 32 namespace llvm { 33 class MCInstrInfo; 34 } 35 36 namespace { 37 class MipsAssemblerOptions { 38 public: 39 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {} 40 41 unsigned getATRegNum() { return aTReg; } 42 bool setATReg(unsigned Reg); 43 44 bool isReorder() { return reorder; } 45 void setReorder() { reorder = true; } 46 void setNoreorder() { reorder = false; } 47 48 bool isMacro() { return macro; } 49 void setMacro() { macro = true; } 50 void setNomacro() { macro = false; } 51 52 private: 53 unsigned aTReg; 54 bool reorder; 55 bool macro; 56 }; 57 } 58 59 namespace { 60 class MipsAsmParser : public MCTargetAsmParser { 61 MipsTargetStreamer &getTargetStreamer() { 62 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer(); 63 return static_cast<MipsTargetStreamer &>(TS); 64 } 65 66 MCSubtargetInfo &STI; 67 MCAsmParser &Parser; 68 MipsAssemblerOptions Options; 69 70 #define GET_ASSEMBLER_HEADER 71 #include "MipsGenAsmMatcher.inc" 72 73 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 74 SmallVectorImpl<MCParsedAsmOperand *> &Operands, 75 MCStreamer &Out, unsigned &ErrorInfo, 76 bool MatchingInlineAsm); 77 78 /// Parse a register as used in CFI directives 79 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 80 81 bool ParseParenSuffix(StringRef Name, 82 SmallVectorImpl<MCParsedAsmOperand *> &Operands); 83 84 bool ParseBracketSuffix(StringRef Name, 85 SmallVectorImpl<MCParsedAsmOperand *> &Operands); 86 87 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 88 SMLoc NameLoc, 89 SmallVectorImpl<MCParsedAsmOperand *> &Operands); 90 91 bool ParseDirective(AsmToken DirectiveID); 92 93 MipsAsmParser::OperandMatchResultTy 94 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 95 96 MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar( 97 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier, 98 SMLoc S); 99 100 MipsAsmParser::OperandMatchResultTy 101 MatchAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 102 SMLoc S); 103 104 MipsAsmParser::OperandMatchResultTy 105 ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 106 107 MipsAsmParser::OperandMatchResultTy 108 ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 109 110 MipsAsmParser::OperandMatchResultTy 111 ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 112 113 MipsAsmParser::OperandMatchResultTy 114 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 115 116 MipsAsmParser::OperandMatchResultTy 117 ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 118 119 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 120 121 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &, 122 StringRef Mnemonic); 123 124 bool needsExpansion(MCInst &Inst); 125 126 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 127 SmallVectorImpl<MCInst> &Instructions); 128 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 129 SmallVectorImpl<MCInst> &Instructions); 130 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 131 SmallVectorImpl<MCInst> &Instructions); 132 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 133 SmallVectorImpl<MCInst> &Instructions); 134 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 135 SmallVectorImpl<MCInst> &Instructions, bool isLoad, 136 bool isImmOpnd); 137 bool reportParseError(StringRef ErrorMsg); 138 139 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 140 bool parseRelocOperand(const MCExpr *&Res); 141 142 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 143 144 bool isEvaluated(const MCExpr *Expr); 145 bool parseSetFeature(uint64_t Feature); 146 bool parseDirectiveCPSetup(); 147 bool parseDirectiveNaN(); 148 bool parseDirectiveSet(); 149 bool parseDirectiveOption(); 150 151 bool parseSetAtDirective(); 152 bool parseSetNoAtDirective(); 153 bool parseSetMacroDirective(); 154 bool parseSetNoMacroDirective(); 155 bool parseSetReorderDirective(); 156 bool parseSetNoReorderDirective(); 157 bool parseSetNoMips16Directive(); 158 159 bool parseSetAssignment(); 160 161 bool parseDataDirective(unsigned Size, SMLoc L); 162 bool parseDirectiveGpWord(); 163 bool parseDirectiveGpDWord(); 164 165 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 166 167 bool isGP64() const { 168 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0; 169 } 170 171 bool isFP64() const { 172 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 173 } 174 175 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; } 176 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 177 178 bool isMicroMips() const { 179 return STI.getFeatureBits() & Mips::FeatureMicroMips; 180 } 181 182 bool parseRegister(unsigned &RegNum); 183 184 bool eatComma(StringRef ErrorStr); 185 186 int matchCPURegisterName(StringRef Symbol); 187 188 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 189 190 int matchFPURegisterName(StringRef Name); 191 192 int matchFCCRegisterName(StringRef Name); 193 194 int matchACRegisterName(StringRef Name); 195 196 int matchMSA128RegisterName(StringRef Name); 197 198 int matchMSA128CtrlRegisterName(StringRef Name); 199 200 unsigned getReg(int RC, int RegNo); 201 202 unsigned getGPR(int RegNo); 203 204 int getATReg(); 205 206 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 207 SmallVectorImpl<MCInst> &Instructions); 208 209 // Helper function that checks if the value of a vector index is within the 210 // boundaries of accepted values for each RegisterKind 211 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 212 bool validateMSAIndex(int Val, int RegKind); 213 214 void setFeatureBits(unsigned Feature, StringRef FeatureString) { 215 if (!(STI.getFeatureBits() & Feature)) { 216 setAvailableFeatures(ComputeAvailableFeatures( 217 STI.ToggleFeature(FeatureString))); 218 } 219 } 220 221 void clearFeatureBits(unsigned Feature, StringRef FeatureString) { 222 if (STI.getFeatureBits() & Feature) { 223 setAvailableFeatures(ComputeAvailableFeatures( 224 STI.ToggleFeature(FeatureString))); 225 } 226 } 227 228 public: 229 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 230 const MCInstrInfo &MII) 231 : MCTargetAsmParser(), STI(sti), Parser(parser) { 232 // Initialize the set of available features. 233 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 234 235 // Assert exactly one ABI was chosen. 236 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + 237 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + 238 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + 239 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); 240 } 241 242 MCAsmParser &getParser() const { return Parser; } 243 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 244 245 /// Warn if RegNo is the current assembler temporary. 246 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc); 247 }; 248 } 249 250 namespace { 251 252 /// MipsOperand - Instances of this class represent a parsed Mips machine 253 /// instruction. 254 class MipsOperand : public MCParsedAsmOperand { 255 public: 256 /// Broad categories of register classes 257 /// The exact class is finalized by the render method. 258 enum RegKind { 259 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64()) 260 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 261 /// isFP64()) 262 RegKind_FCC = 4, /// FCC 263 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 264 RegKind_MSACtrl = 16, /// MSA control registers 265 RegKind_COP2 = 32, /// COP2 266 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 267 /// context). 268 RegKind_CCR = 128, /// CCR 269 RegKind_HWRegs = 256, /// HWRegs 270 271 /// Potentially any (e.g. $1) 272 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 273 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 274 RegKind_CCR | RegKind_HWRegs 275 }; 276 277 private: 278 enum KindTy { 279 k_Immediate, /// An immediate (possibly involving symbol references) 280 k_Memory, /// Base + Offset Memory Address 281 k_PhysRegister, /// A physical register from the Mips namespace 282 k_RegisterIndex, /// A register index in one or more RegKind. 283 k_Token /// A simple token 284 } Kind; 285 286 MipsOperand(KindTy K, MipsAsmParser &Parser) 287 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 288 289 /// For diagnostics, and checking the assembler temporary 290 MipsAsmParser &AsmParser; 291 292 struct Token { 293 const char *Data; 294 unsigned Length; 295 }; 296 297 struct PhysRegOp { 298 unsigned Num; /// Register Number 299 }; 300 301 struct RegIdxOp { 302 unsigned Index; /// Index into the register class 303 RegKind Kind; /// Bitfield of the kinds it could possibly be 304 const MCRegisterInfo *RegInfo; 305 }; 306 307 struct ImmOp { 308 const MCExpr *Val; 309 }; 310 311 struct MemOp { 312 MipsOperand *Base; 313 const MCExpr *Off; 314 }; 315 316 union { 317 struct Token Tok; 318 struct PhysRegOp PhysReg; 319 struct RegIdxOp RegIdx; 320 struct ImmOp Imm; 321 struct MemOp Mem; 322 }; 323 324 SMLoc StartLoc, EndLoc; 325 326 /// Internal constructor for register kinds 327 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind, 328 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 329 MipsAsmParser &Parser) { 330 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser); 331 Op->RegIdx.Index = Index; 332 Op->RegIdx.RegInfo = RegInfo; 333 Op->RegIdx.Kind = RegKind; 334 Op->StartLoc = S; 335 Op->EndLoc = E; 336 return Op; 337 } 338 339 public: 340 /// Coerce the register to GPR32 and return the real register for the current 341 /// target. 342 unsigned getGPR32Reg() const { 343 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 344 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc); 345 unsigned ClassID = Mips::GPR32RegClassID; 346 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 347 } 348 349 /// Coerce the register to GPR64 and return the real register for the current 350 /// target. 351 unsigned getGPR64Reg() const { 352 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 353 unsigned ClassID = Mips::GPR64RegClassID; 354 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 355 } 356 357 private: 358 /// Coerce the register to AFGR64 and return the real register for the current 359 /// target. 360 unsigned getAFGR64Reg() const { 361 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 362 if (RegIdx.Index % 2 != 0) 363 AsmParser.Warning(StartLoc, "Float register should be even."); 364 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 365 .getRegister(RegIdx.Index / 2); 366 } 367 368 /// Coerce the register to FGR64 and return the real register for the current 369 /// target. 370 unsigned getFGR64Reg() const { 371 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 372 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 373 .getRegister(RegIdx.Index); 374 } 375 376 /// Coerce the register to FGR32 and return the real register for the current 377 /// target. 378 unsigned getFGR32Reg() const { 379 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 380 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 381 .getRegister(RegIdx.Index); 382 } 383 384 /// Coerce the register to FGRH32 and return the real register for the current 385 /// target. 386 unsigned getFGRH32Reg() const { 387 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 388 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 389 .getRegister(RegIdx.Index); 390 } 391 392 /// Coerce the register to FCC and return the real register for the current 393 /// target. 394 unsigned getFCCReg() const { 395 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 396 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 397 .getRegister(RegIdx.Index); 398 } 399 400 /// Coerce the register to MSA128 and return the real register for the current 401 /// target. 402 unsigned getMSA128Reg() const { 403 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 404 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 405 // identical 406 unsigned ClassID = Mips::MSA128BRegClassID; 407 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 408 } 409 410 /// Coerce the register to MSACtrl and return the real register for the 411 /// current target. 412 unsigned getMSACtrlReg() const { 413 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 414 unsigned ClassID = Mips::MSACtrlRegClassID; 415 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 416 } 417 418 /// Coerce the register to COP2 and return the real register for the 419 /// current target. 420 unsigned getCOP2Reg() const { 421 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 422 unsigned ClassID = Mips::COP2RegClassID; 423 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 424 } 425 426 /// Coerce the register to ACC64DSP and return the real register for the 427 /// current target. 428 unsigned getACC64DSPReg() const { 429 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 430 unsigned ClassID = Mips::ACC64DSPRegClassID; 431 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 432 } 433 434 /// Coerce the register to HI32DSP and return the real register for the 435 /// current target. 436 unsigned getHI32DSPReg() const { 437 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 438 unsigned ClassID = Mips::HI32DSPRegClassID; 439 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 440 } 441 442 /// Coerce the register to LO32DSP and return the real register for the 443 /// current target. 444 unsigned getLO32DSPReg() const { 445 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 446 unsigned ClassID = Mips::LO32DSPRegClassID; 447 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 448 } 449 450 /// Coerce the register to CCR and return the real register for the 451 /// current target. 452 unsigned getCCRReg() const { 453 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 454 unsigned ClassID = Mips::CCRRegClassID; 455 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 456 } 457 458 /// Coerce the register to HWRegs and return the real register for the 459 /// current target. 460 unsigned getHWRegsReg() const { 461 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 462 unsigned ClassID = Mips::HWRegsRegClassID; 463 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 464 } 465 466 public: 467 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 468 // Add as immediate when possible. Null MCExpr = 0. 469 if (Expr == 0) 470 Inst.addOperand(MCOperand::CreateImm(0)); 471 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 472 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 473 else 474 Inst.addOperand(MCOperand::CreateExpr(Expr)); 475 } 476 477 void addRegOperands(MCInst &Inst, unsigned N) const { 478 llvm_unreachable("Use a custom parser instead"); 479 } 480 481 /// Render the operand to an MCInst as a GPR32 482 /// Asserts if the wrong number of operands are requested, or the operand 483 /// is not a k_RegisterIndex compatible with RegKind_GPR 484 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 485 assert(N == 1 && "Invalid number of operands!"); 486 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); 487 } 488 489 /// Render the operand to an MCInst as a GPR64 490 /// Asserts if the wrong number of operands are requested, or the operand 491 /// is not a k_RegisterIndex compatible with RegKind_GPR 492 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 493 assert(N == 1 && "Invalid number of operands!"); 494 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); 495 } 496 497 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 498 assert(N == 1 && "Invalid number of operands!"); 499 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); 500 } 501 502 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 503 assert(N == 1 && "Invalid number of operands!"); 504 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); 505 } 506 507 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 508 assert(N == 1 && "Invalid number of operands!"); 509 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); 510 } 511 512 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 513 assert(N == 1 && "Invalid number of operands!"); 514 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); 515 } 516 517 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 518 assert(N == 1 && "Invalid number of operands!"); 519 Inst.addOperand(MCOperand::CreateReg(getFCCReg())); 520 } 521 522 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 523 assert(N == 1 && "Invalid number of operands!"); 524 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); 525 } 526 527 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 528 assert(N == 1 && "Invalid number of operands!"); 529 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); 530 } 531 532 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 533 assert(N == 1 && "Invalid number of operands!"); 534 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); 535 } 536 537 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 538 assert(N == 1 && "Invalid number of operands!"); 539 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); 540 } 541 542 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 543 assert(N == 1 && "Invalid number of operands!"); 544 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); 545 } 546 547 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 548 assert(N == 1 && "Invalid number of operands!"); 549 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); 550 } 551 552 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 553 assert(N == 1 && "Invalid number of operands!"); 554 Inst.addOperand(MCOperand::CreateReg(getCCRReg())); 555 } 556 557 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 558 assert(N == 1 && "Invalid number of operands!"); 559 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); 560 } 561 562 void addImmOperands(MCInst &Inst, unsigned N) const { 563 assert(N == 1 && "Invalid number of operands!"); 564 const MCExpr *Expr = getImm(); 565 addExpr(Inst, Expr); 566 } 567 568 void addMemOperands(MCInst &Inst, unsigned N) const { 569 assert(N == 2 && "Invalid number of operands!"); 570 571 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); 572 573 const MCExpr *Expr = getMemOff(); 574 addExpr(Inst, Expr); 575 } 576 577 bool isReg() const { 578 // As a special case until we sort out the definition of div/divu, pretend 579 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 580 if (isGPRAsmReg() && RegIdx.Index == 0) 581 return true; 582 583 return Kind == k_PhysRegister; 584 } 585 bool isRegIdx() const { return Kind == k_RegisterIndex; } 586 bool isImm() const { return Kind == k_Immediate; } 587 bool isConstantImm() const { 588 return isImm() && dyn_cast<MCConstantExpr>(getImm()); 589 } 590 bool isToken() const { 591 // Note: It's not possible to pretend that other operand kinds are tokens. 592 // The matcher emitter checks tokens first. 593 return Kind == k_Token; 594 } 595 bool isMem() const { return Kind == k_Memory; } 596 bool isInvNum() const { return Kind == k_Immediate; } 597 bool isLSAImm() const { 598 if (!isConstantImm()) 599 return false; 600 int64_t Val = getConstantImm(); 601 return 1 <= Val && Val <= 4; 602 } 603 604 StringRef getToken() const { 605 assert(Kind == k_Token && "Invalid access!"); 606 return StringRef(Tok.Data, Tok.Length); 607 } 608 609 unsigned getReg() const { 610 // As a special case until we sort out the definition of div/divu, pretend 611 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 612 if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 613 RegIdx.Kind & RegKind_GPR) 614 return getGPR32Reg(); // FIXME: GPR64 too 615 616 assert(Kind == k_PhysRegister && "Invalid access!"); 617 return PhysReg.Num; 618 } 619 620 const MCExpr *getImm() const { 621 assert((Kind == k_Immediate) && "Invalid access!"); 622 return Imm.Val; 623 } 624 625 int64_t getConstantImm() const { 626 const MCExpr *Val = getImm(); 627 return static_cast<const MCConstantExpr *>(Val)->getValue(); 628 } 629 630 MipsOperand *getMemBase() const { 631 assert((Kind == k_Memory) && "Invalid access!"); 632 return Mem.Base; 633 } 634 635 const MCExpr *getMemOff() const { 636 assert((Kind == k_Memory) && "Invalid access!"); 637 return Mem.Off; 638 } 639 640 static MipsOperand *CreateToken(StringRef Str, SMLoc S, 641 MipsAsmParser &Parser) { 642 MipsOperand *Op = new MipsOperand(k_Token, Parser); 643 Op->Tok.Data = Str.data(); 644 Op->Tok.Length = Str.size(); 645 Op->StartLoc = S; 646 Op->EndLoc = S; 647 return Op; 648 } 649 650 /// Create a numeric register (e.g. $1). The exact register remains 651 /// unresolved until an instruction successfully matches 652 static MipsOperand *CreateNumericReg(unsigned Index, 653 const MCRegisterInfo *RegInfo, SMLoc S, 654 SMLoc E, MipsAsmParser &Parser) { 655 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n"); 656 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 657 } 658 659 /// Create a register that is definitely a GPR. 660 /// This is typically only used for named registers such as $gp. 661 static MipsOperand *CreateGPRReg(unsigned Index, 662 const MCRegisterInfo *RegInfo, SMLoc S, 663 SMLoc E, MipsAsmParser &Parser) { 664 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 665 } 666 667 /// Create a register that is definitely a FGR. 668 /// This is typically only used for named registers such as $f0. 669 static MipsOperand *CreateFGRReg(unsigned Index, 670 const MCRegisterInfo *RegInfo, SMLoc S, 671 SMLoc E, MipsAsmParser &Parser) { 672 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 673 } 674 675 /// Create a register that is definitely an FCC. 676 /// This is typically only used for named registers such as $fcc0. 677 static MipsOperand *CreateFCCReg(unsigned Index, 678 const MCRegisterInfo *RegInfo, SMLoc S, 679 SMLoc E, MipsAsmParser &Parser) { 680 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 681 } 682 683 /// Create a register that is definitely an ACC. 684 /// This is typically only used for named registers such as $ac0. 685 static MipsOperand *CreateACCReg(unsigned Index, 686 const MCRegisterInfo *RegInfo, SMLoc S, 687 SMLoc E, MipsAsmParser &Parser) { 688 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 689 } 690 691 /// Create a register that is definitely an MSA128. 692 /// This is typically only used for named registers such as $w0. 693 static MipsOperand *CreateMSA128Reg(unsigned Index, 694 const MCRegisterInfo *RegInfo, SMLoc S, 695 SMLoc E, MipsAsmParser &Parser) { 696 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 697 } 698 699 /// Create a register that is definitely an MSACtrl. 700 /// This is typically only used for named registers such as $msaaccess. 701 static MipsOperand *CreateMSACtrlReg(unsigned Index, 702 const MCRegisterInfo *RegInfo, SMLoc S, 703 SMLoc E, MipsAsmParser &Parser) { 704 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 705 } 706 707 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, 708 MipsAsmParser &Parser) { 709 MipsOperand *Op = new MipsOperand(k_Immediate, Parser); 710 Op->Imm.Val = Val; 711 Op->StartLoc = S; 712 Op->EndLoc = E; 713 return Op; 714 } 715 716 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S, 717 SMLoc E, MipsAsmParser &Parser) { 718 MipsOperand *Op = new MipsOperand(k_Memory, Parser); 719 Op->Mem.Base = Base; 720 Op->Mem.Off = Off; 721 Op->StartLoc = S; 722 Op->EndLoc = E; 723 return Op; 724 } 725 726 bool isGPRAsmReg() const { 727 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 728 } 729 bool isFGRAsmReg() const { 730 // AFGR64 is $0-$15 but we handle this in getAFGR64() 731 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 732 } 733 bool isHWRegsAsmReg() const { 734 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 735 } 736 bool isCCRAsmReg() const { 737 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 738 } 739 bool isFCCAsmReg() const { 740 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7; 741 } 742 bool isACCAsmReg() const { 743 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 744 } 745 bool isCOP2AsmReg() const { 746 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 747 } 748 bool isMSA128AsmReg() const { 749 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 750 } 751 bool isMSACtrlAsmReg() const { 752 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 753 } 754 755 /// getStartLoc - Get the location of the first token of this operand. 756 SMLoc getStartLoc() const { return StartLoc; } 757 /// getEndLoc - Get the location of the last token of this operand. 758 SMLoc getEndLoc() const { return EndLoc; } 759 760 virtual ~MipsOperand() { 761 switch (Kind) { 762 case k_Immediate: 763 break; 764 case k_Memory: 765 delete Mem.Base; 766 break; 767 case k_PhysRegister: 768 case k_RegisterIndex: 769 case k_Token: 770 break; 771 } 772 } 773 774 virtual void print(raw_ostream &OS) const { 775 switch (Kind) { 776 case k_Immediate: 777 OS << "Imm<"; 778 Imm.Val->print(OS); 779 OS << ">"; 780 break; 781 case k_Memory: 782 OS << "Mem<"; 783 Mem.Base->print(OS); 784 OS << ", "; 785 Mem.Off->print(OS); 786 OS << ">"; 787 break; 788 case k_PhysRegister: 789 OS << "PhysReg<" << PhysReg.Num << ">"; 790 break; 791 case k_RegisterIndex: 792 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 793 break; 794 case k_Token: 795 OS << Tok.Data; 796 break; 797 } 798 } 799 }; // class MipsOperand 800 } // namespace 801 802 namespace llvm { 803 extern const MCInstrDesc MipsInsts[]; 804 } 805 static const MCInstrDesc &getInstDesc(unsigned Opcode) { 806 return MipsInsts[Opcode]; 807 } 808 809 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 810 SmallVectorImpl<MCInst> &Instructions) { 811 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 812 813 Inst.setLoc(IDLoc); 814 815 if (MCID.isBranch() || MCID.isCall()) { 816 const unsigned Opcode = Inst.getOpcode(); 817 MCOperand Offset; 818 819 switch (Opcode) { 820 default: 821 break; 822 case Mips::BEQ: 823 case Mips::BNE: 824 case Mips::BEQ_MM: 825 case Mips::BNE_MM: 826 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 827 Offset = Inst.getOperand(2); 828 if (!Offset.isImm()) 829 break; // We'll deal with this situation later on when applying fixups. 830 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm())) 831 return Error(IDLoc, "branch target out of range"); 832 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2))) 833 return Error(IDLoc, "branch to misaligned address"); 834 break; 835 case Mips::BGEZ: 836 case Mips::BGTZ: 837 case Mips::BLEZ: 838 case Mips::BLTZ: 839 case Mips::BGEZAL: 840 case Mips::BLTZAL: 841 case Mips::BC1F: 842 case Mips::BC1T: 843 case Mips::BGEZ_MM: 844 case Mips::BGTZ_MM: 845 case Mips::BLEZ_MM: 846 case Mips::BLTZ_MM: 847 case Mips::BGEZAL_MM: 848 case Mips::BLTZAL_MM: 849 case Mips::BC1F_MM: 850 case Mips::BC1T_MM: 851 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 852 Offset = Inst.getOperand(1); 853 if (!Offset.isImm()) 854 break; // We'll deal with this situation later on when applying fixups. 855 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm())) 856 return Error(IDLoc, "branch target out of range"); 857 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2))) 858 return Error(IDLoc, "branch to misaligned address"); 859 break; 860 } 861 } 862 863 if (MCID.hasDelaySlot() && Options.isReorder()) { 864 // If this instruction has a delay slot and .set reorder is active, 865 // emit a NOP after it. 866 Instructions.push_back(Inst); 867 MCInst NopInst; 868 NopInst.setOpcode(Mips::SLL); 869 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 870 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 871 NopInst.addOperand(MCOperand::CreateImm(0)); 872 Instructions.push_back(NopInst); 873 return false; 874 } 875 876 if (MCID.mayLoad() || MCID.mayStore()) { 877 // Check the offset of memory operand, if it is a symbol 878 // reference or immediate we may have to expand instructions. 879 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 880 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 881 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 882 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 883 MCOperand &Op = Inst.getOperand(i); 884 if (Op.isImm()) { 885 int MemOffset = Op.getImm(); 886 if (MemOffset < -32768 || MemOffset > 32767) { 887 // Offset can't exceed 16bit value. 888 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 889 return false; 890 } 891 } else if (Op.isExpr()) { 892 const MCExpr *Expr = Op.getExpr(); 893 if (Expr->getKind() == MCExpr::SymbolRef) { 894 const MCSymbolRefExpr *SR = 895 static_cast<const MCSymbolRefExpr *>(Expr); 896 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 897 // Expand symbol. 898 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 899 return false; 900 } 901 } else if (!isEvaluated(Expr)) { 902 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 903 return false; 904 } 905 } 906 } 907 } // for 908 } // if load/store 909 910 if (needsExpansion(Inst)) 911 expandInstruction(Inst, IDLoc, Instructions); 912 else 913 Instructions.push_back(Inst); 914 915 return false; 916 } 917 918 bool MipsAsmParser::needsExpansion(MCInst &Inst) { 919 920 switch (Inst.getOpcode()) { 921 case Mips::LoadImm32Reg: 922 case Mips::LoadAddr32Imm: 923 case Mips::LoadAddr32Reg: 924 return true; 925 default: 926 return false; 927 } 928 } 929 930 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 931 SmallVectorImpl<MCInst> &Instructions) { 932 switch (Inst.getOpcode()) { 933 case Mips::LoadImm32Reg: 934 return expandLoadImm(Inst, IDLoc, Instructions); 935 case Mips::LoadAddr32Imm: 936 return expandLoadAddressImm(Inst, IDLoc, Instructions); 937 case Mips::LoadAddr32Reg: 938 return expandLoadAddressReg(Inst, IDLoc, Instructions); 939 } 940 } 941 942 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 943 SmallVectorImpl<MCInst> &Instructions) { 944 MCInst tmpInst; 945 const MCOperand &ImmOp = Inst.getOperand(1); 946 assert(ImmOp.isImm() && "expected immediate operand kind"); 947 const MCOperand &RegOp = Inst.getOperand(0); 948 assert(RegOp.isReg() && "expected register operand kind"); 949 950 int ImmValue = ImmOp.getImm(); 951 tmpInst.setLoc(IDLoc); 952 if (0 <= ImmValue && ImmValue <= 65535) { 953 // For 0 <= j <= 65535. 954 // li d,j => ori d,$zero,j 955 tmpInst.setOpcode(Mips::ORi); 956 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 957 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 958 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 959 Instructions.push_back(tmpInst); 960 } else if (ImmValue < 0 && ImmValue >= -32768) { 961 // For -32768 <= j < 0. 962 // li d,j => addiu d,$zero,j 963 tmpInst.setOpcode(Mips::ADDiu); 964 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 965 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 966 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 967 Instructions.push_back(tmpInst); 968 } else { 969 // For any other value of j that is representable as a 32-bit integer. 970 // li d,j => lui d,hi16(j) 971 // ori d,d,lo16(j) 972 tmpInst.setOpcode(Mips::LUi); 973 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 974 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 975 Instructions.push_back(tmpInst); 976 tmpInst.clear(); 977 tmpInst.setOpcode(Mips::ORi); 978 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 979 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 980 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 981 tmpInst.setLoc(IDLoc); 982 Instructions.push_back(tmpInst); 983 } 984 } 985 986 void 987 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 988 SmallVectorImpl<MCInst> &Instructions) { 989 MCInst tmpInst; 990 const MCOperand &ImmOp = Inst.getOperand(2); 991 assert(ImmOp.isImm() && "expected immediate operand kind"); 992 const MCOperand &SrcRegOp = Inst.getOperand(1); 993 assert(SrcRegOp.isReg() && "expected register operand kind"); 994 const MCOperand &DstRegOp = Inst.getOperand(0); 995 assert(DstRegOp.isReg() && "expected register operand kind"); 996 int ImmValue = ImmOp.getImm(); 997 if (-32768 <= ImmValue && ImmValue <= 65535) { 998 // For -32768 <= j <= 65535. 999 // la d,j(s) => addiu d,s,j 1000 tmpInst.setOpcode(Mips::ADDiu); 1001 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1002 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1003 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1004 Instructions.push_back(tmpInst); 1005 } else { 1006 // For any other value of j that is representable as a 32-bit integer. 1007 // la d,j(s) => lui d,hi16(j) 1008 // ori d,d,lo16(j) 1009 // addu d,d,s 1010 tmpInst.setOpcode(Mips::LUi); 1011 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1012 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1013 Instructions.push_back(tmpInst); 1014 tmpInst.clear(); 1015 tmpInst.setOpcode(Mips::ORi); 1016 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1017 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1018 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1019 Instructions.push_back(tmpInst); 1020 tmpInst.clear(); 1021 tmpInst.setOpcode(Mips::ADDu); 1022 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1023 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1024 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1025 Instructions.push_back(tmpInst); 1026 } 1027 } 1028 1029 void 1030 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1031 SmallVectorImpl<MCInst> &Instructions) { 1032 MCInst tmpInst; 1033 const MCOperand &ImmOp = Inst.getOperand(1); 1034 assert(ImmOp.isImm() && "expected immediate operand kind"); 1035 const MCOperand &RegOp = Inst.getOperand(0); 1036 assert(RegOp.isReg() && "expected register operand kind"); 1037 int ImmValue = ImmOp.getImm(); 1038 if (-32768 <= ImmValue && ImmValue <= 65535) { 1039 // For -32768 <= j <= 65535. 1040 // la d,j => addiu d,$zero,j 1041 tmpInst.setOpcode(Mips::ADDiu); 1042 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1043 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1044 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1045 Instructions.push_back(tmpInst); 1046 } else { 1047 // For any other value of j that is representable as a 32-bit integer. 1048 // la d,j => lui d,hi16(j) 1049 // ori d,d,lo16(j) 1050 tmpInst.setOpcode(Mips::LUi); 1051 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1052 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1053 Instructions.push_back(tmpInst); 1054 tmpInst.clear(); 1055 tmpInst.setOpcode(Mips::ORi); 1056 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1057 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1058 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1059 Instructions.push_back(tmpInst); 1060 } 1061 } 1062 1063 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 1064 SmallVectorImpl<MCInst> &Instructions, 1065 bool isLoad, bool isImmOpnd) { 1066 const MCSymbolRefExpr *SR; 1067 MCInst TempInst; 1068 unsigned ImmOffset, HiOffset, LoOffset; 1069 const MCExpr *ExprOffset; 1070 unsigned TmpRegNum; 1071 unsigned AtRegNum = getReg( 1072 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg()); 1073 // 1st operand is either the source or destination register. 1074 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 1075 unsigned RegOpNum = Inst.getOperand(0).getReg(); 1076 // 2nd operand is the base register. 1077 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 1078 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 1079 // 3rd operand is either an immediate or expression. 1080 if (isImmOpnd) { 1081 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 1082 ImmOffset = Inst.getOperand(2).getImm(); 1083 LoOffset = ImmOffset & 0x0000ffff; 1084 HiOffset = (ImmOffset & 0xffff0000) >> 16; 1085 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 1086 if (LoOffset & 0x8000) 1087 HiOffset++; 1088 } else 1089 ExprOffset = Inst.getOperand(2).getExpr(); 1090 // All instructions will have the same location. 1091 TempInst.setLoc(IDLoc); 1092 // 1st instruction in expansion is LUi. For load instruction we can use 1093 // the dst register as a temporary if base and dst are different, 1094 // but for stores we must use $at. 1095 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 1096 TempInst.setOpcode(Mips::LUi); 1097 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1098 if (isImmOpnd) 1099 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 1100 else { 1101 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1102 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 1103 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 1104 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 1105 getContext()); 1106 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1107 } else { 1108 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 1109 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1110 } 1111 } 1112 // Add the instruction to the list. 1113 Instructions.push_back(TempInst); 1114 // Prepare TempInst for next instruction. 1115 TempInst.clear(); 1116 // Add temp register to base. 1117 TempInst.setOpcode(Mips::ADDu); 1118 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1119 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1120 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 1121 Instructions.push_back(TempInst); 1122 TempInst.clear(); 1123 // And finally, create original instruction with low part 1124 // of offset and new base. 1125 TempInst.setOpcode(Inst.getOpcode()); 1126 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 1127 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1128 if (isImmOpnd) 1129 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 1130 else { 1131 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1132 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 1133 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 1134 getContext()); 1135 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1136 } else { 1137 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 1138 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1139 } 1140 } 1141 Instructions.push_back(TempInst); 1142 TempInst.clear(); 1143 } 1144 1145 bool MipsAsmParser::MatchAndEmitInstruction( 1146 SMLoc IDLoc, unsigned &Opcode, 1147 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out, 1148 unsigned &ErrorInfo, bool MatchingInlineAsm) { 1149 MCInst Inst; 1150 SmallVector<MCInst, 8> Instructions; 1151 unsigned MatchResult = 1152 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 1153 1154 switch (MatchResult) { 1155 default: 1156 break; 1157 case Match_Success: { 1158 if (processInstruction(Inst, IDLoc, Instructions)) 1159 return true; 1160 for (unsigned i = 0; i < Instructions.size(); i++) 1161 Out.EmitInstruction(Instructions[i], STI); 1162 return false; 1163 } 1164 case Match_MissingFeature: 1165 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1166 return true; 1167 case Match_InvalidOperand: { 1168 SMLoc ErrorLoc = IDLoc; 1169 if (ErrorInfo != ~0U) { 1170 if (ErrorInfo >= Operands.size()) 1171 return Error(IDLoc, "too few operands for instruction"); 1172 1173 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc(); 1174 if (ErrorLoc == SMLoc()) 1175 ErrorLoc = IDLoc; 1176 } 1177 1178 return Error(ErrorLoc, "invalid operand for instruction"); 1179 } 1180 case Match_MnemonicFail: 1181 return Error(IDLoc, "invalid instruction"); 1182 } 1183 return true; 1184 } 1185 1186 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { 1187 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) { 1188 if (RegIndex == 1) 1189 Warning(Loc, "Used $at without \".set noat\""); 1190 else 1191 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" + 1192 Twine(RegIndex) + "\""); 1193 } 1194 } 1195 1196 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 1197 int CC; 1198 1199 CC = StringSwitch<unsigned>(Name) 1200 .Case("zero", 0) 1201 .Case("at", 1) 1202 .Case("a0", 4) 1203 .Case("a1", 5) 1204 .Case("a2", 6) 1205 .Case("a3", 7) 1206 .Case("v0", 2) 1207 .Case("v1", 3) 1208 .Case("s0", 16) 1209 .Case("s1", 17) 1210 .Case("s2", 18) 1211 .Case("s3", 19) 1212 .Case("s4", 20) 1213 .Case("s5", 21) 1214 .Case("s6", 22) 1215 .Case("s7", 23) 1216 .Case("k0", 26) 1217 .Case("k1", 27) 1218 .Case("gp", 28) 1219 .Case("sp", 29) 1220 .Case("fp", 30) 1221 .Case("s8", 30) 1222 .Case("ra", 31) 1223 .Case("t0", 8) 1224 .Case("t1", 9) 1225 .Case("t2", 10) 1226 .Case("t3", 11) 1227 .Case("t4", 12) 1228 .Case("t5", 13) 1229 .Case("t6", 14) 1230 .Case("t7", 15) 1231 .Case("t8", 24) 1232 .Case("t9", 25) 1233 .Default(-1); 1234 1235 if (isN32() || isN64()) { 1236 // Although SGI documentation just cuts out t0-t3 for n32/n64, 1237 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 1238 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 1239 if (8 <= CC && CC <= 11) 1240 CC += 4; 1241 1242 if (CC == -1) 1243 CC = StringSwitch<unsigned>(Name) 1244 .Case("a4", 8) 1245 .Case("a5", 9) 1246 .Case("a6", 10) 1247 .Case("a7", 11) 1248 .Case("kt0", 26) 1249 .Case("kt1", 27) 1250 .Default(-1); 1251 } 1252 1253 return CC; 1254 } 1255 1256 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 1257 1258 if (Name[0] == 'f') { 1259 StringRef NumString = Name.substr(1); 1260 unsigned IntVal; 1261 if (NumString.getAsInteger(10, IntVal)) 1262 return -1; // This is not an integer. 1263 if (IntVal > 31) // Maximum index for fpu register. 1264 return -1; 1265 return IntVal; 1266 } 1267 return -1; 1268 } 1269 1270 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 1271 1272 if (Name.startswith("fcc")) { 1273 StringRef NumString = Name.substr(3); 1274 unsigned IntVal; 1275 if (NumString.getAsInteger(10, IntVal)) 1276 return -1; // This is not an integer. 1277 if (IntVal > 7) // There are only 8 fcc registers. 1278 return -1; 1279 return IntVal; 1280 } 1281 return -1; 1282 } 1283 1284 int MipsAsmParser::matchACRegisterName(StringRef Name) { 1285 1286 if (Name.startswith("ac")) { 1287 StringRef NumString = Name.substr(2); 1288 unsigned IntVal; 1289 if (NumString.getAsInteger(10, IntVal)) 1290 return -1; // This is not an integer. 1291 if (IntVal > 3) // There are only 3 acc registers. 1292 return -1; 1293 return IntVal; 1294 } 1295 return -1; 1296 } 1297 1298 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 1299 unsigned IntVal; 1300 1301 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 1302 return -1; 1303 1304 if (IntVal > 31) 1305 return -1; 1306 1307 return IntVal; 1308 } 1309 1310 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 1311 int CC; 1312 1313 CC = StringSwitch<unsigned>(Name) 1314 .Case("msair", 0) 1315 .Case("msacsr", 1) 1316 .Case("msaaccess", 2) 1317 .Case("msasave", 3) 1318 .Case("msamodify", 4) 1319 .Case("msarequest", 5) 1320 .Case("msamap", 6) 1321 .Case("msaunmap", 7) 1322 .Default(-1); 1323 1324 return CC; 1325 } 1326 1327 bool MipsAssemblerOptions::setATReg(unsigned Reg) { 1328 if (Reg > 31) 1329 return false; 1330 1331 aTReg = Reg; 1332 return true; 1333 } 1334 1335 int MipsAsmParser::getATReg() { 1336 int AT = Options.getATRegNum(); 1337 if (AT == 0) 1338 TokError("Pseudo instruction requires $at, which is not available"); 1339 return AT; 1340 } 1341 1342 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 1343 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 1344 } 1345 1346 unsigned MipsAsmParser::getGPR(int RegNo) { 1347 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 1348 RegNo); 1349 } 1350 1351 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 1352 if (RegNum > 1353 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 1354 return -1; 1355 1356 return getReg(RegClass, RegNum); 1357 } 1358 1359 bool 1360 MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 1361 StringRef Mnemonic) { 1362 DEBUG(dbgs() << "ParseOperand\n"); 1363 1364 // Check if the current operand has a custom associated parser, if so, try to 1365 // custom parse the operand, or fallback to the general approach. 1366 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1367 if (ResTy == MatchOperand_Success) 1368 return false; 1369 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1370 // there was a match, but an error occurred, in which case, just return that 1371 // the operand parsing failed. 1372 if (ResTy == MatchOperand_ParseFail) 1373 return true; 1374 1375 DEBUG(dbgs() << ".. Generic Parser\n"); 1376 1377 switch (getLexer().getKind()) { 1378 default: 1379 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1380 return true; 1381 case AsmToken::Dollar: { 1382 // Parse the register. 1383 SMLoc S = Parser.getTok().getLoc(); 1384 1385 // Almost all registers have been parsed by custom parsers. There is only 1386 // one exception to this. $zero (and it's alias $0) will reach this point 1387 // for div, divu, and similar instructions because it is not an operand 1388 // to the instruction definition but an explicit register. Special case 1389 // this situation for now. 1390 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch) 1391 return false; 1392 1393 // Maybe it is a symbol reference. 1394 StringRef Identifier; 1395 if (Parser.parseIdentifier(Identifier)) 1396 return true; 1397 1398 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1399 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 1400 // Otherwise create a symbol reference. 1401 const MCExpr *Res = 1402 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1403 1404 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 1405 return false; 1406 } 1407 // Else drop to expression parsing. 1408 case AsmToken::LParen: 1409 case AsmToken::Minus: 1410 case AsmToken::Plus: 1411 case AsmToken::Integer: 1412 case AsmToken::String: { 1413 DEBUG(dbgs() << ".. generic integer\n"); 1414 OperandMatchResultTy ResTy = ParseImm(Operands); 1415 return ResTy != MatchOperand_Success; 1416 } 1417 case AsmToken::Percent: { 1418 // It is a symbol reference or constant expression. 1419 const MCExpr *IdVal; 1420 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1421 if (parseRelocOperand(IdVal)) 1422 return true; 1423 1424 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1425 1426 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1427 return false; 1428 } // case AsmToken::Percent 1429 } // switch(getLexer().getKind()) 1430 return true; 1431 } 1432 1433 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 1434 StringRef RelocStr) { 1435 const MCExpr *Res; 1436 // Check the type of the expression. 1437 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 1438 // It's a constant, evaluate reloc value. 1439 int16_t Val; 1440 switch (getVariantKind(RelocStr)) { 1441 case MCSymbolRefExpr::VK_Mips_ABS_LO: 1442 // Get the 1st 16-bits. 1443 Val = MCE->getValue() & 0xffff; 1444 break; 1445 case MCSymbolRefExpr::VK_Mips_ABS_HI: 1446 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low 1447 // 16 bits being negative. 1448 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff; 1449 break; 1450 case MCSymbolRefExpr::VK_Mips_HIGHER: 1451 // Get the 3rd 16-bits. 1452 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff; 1453 break; 1454 case MCSymbolRefExpr::VK_Mips_HIGHEST: 1455 // Get the 4th 16-bits. 1456 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff; 1457 break; 1458 default: 1459 report_fatal_error("Unsupported reloc value!"); 1460 } 1461 return MCConstantExpr::Create(Val, getContext()); 1462 } 1463 1464 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 1465 // It's a symbol, create a symbolic expression from the symbol. 1466 StringRef Symbol = MSRE->getSymbol().getName(); 1467 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1468 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 1469 return Res; 1470 } 1471 1472 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1473 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1474 1475 // Try to create target expression. 1476 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE)) 1477 return MipsMCExpr::Create(VK, Expr, getContext()); 1478 1479 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 1480 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 1481 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 1482 return Res; 1483 } 1484 1485 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 1486 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 1487 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 1488 return Res; 1489 } 1490 // Just return the original expression. 1491 return Expr; 1492 } 1493 1494 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 1495 1496 switch (Expr->getKind()) { 1497 case MCExpr::Constant: 1498 return true; 1499 case MCExpr::SymbolRef: 1500 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 1501 case MCExpr::Binary: 1502 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1503 if (!isEvaluated(BE->getLHS())) 1504 return false; 1505 return isEvaluated(BE->getRHS()); 1506 } 1507 case MCExpr::Unary: 1508 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1509 case MCExpr::Target: 1510 return true; 1511 } 1512 return false; 1513 } 1514 1515 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 1516 Parser.Lex(); // Eat the % token. 1517 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 1518 if (Tok.isNot(AsmToken::Identifier)) 1519 return true; 1520 1521 std::string Str = Tok.getIdentifier().str(); 1522 1523 Parser.Lex(); // Eat the identifier. 1524 // Now make an expression from the rest of the operand. 1525 const MCExpr *IdVal; 1526 SMLoc EndLoc; 1527 1528 if (getLexer().getKind() == AsmToken::LParen) { 1529 while (1) { 1530 Parser.Lex(); // Eat the '(' token. 1531 if (getLexer().getKind() == AsmToken::Percent) { 1532 Parser.Lex(); // Eat the % token. 1533 const AsmToken &nextTok = Parser.getTok(); 1534 if (nextTok.isNot(AsmToken::Identifier)) 1535 return true; 1536 Str += "(%"; 1537 Str += nextTok.getIdentifier(); 1538 Parser.Lex(); // Eat the identifier. 1539 if (getLexer().getKind() != AsmToken::LParen) 1540 return true; 1541 } else 1542 break; 1543 } 1544 if (getParser().parseParenExpression(IdVal, EndLoc)) 1545 return true; 1546 1547 while (getLexer().getKind() == AsmToken::RParen) 1548 Parser.Lex(); // Eat the ')' token. 1549 1550 } else 1551 return true; // Parenthesis must follow the relocation operand. 1552 1553 Res = evaluateRelocExpr(IdVal, Str); 1554 return false; 1555 } 1556 1557 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1558 SMLoc &EndLoc) { 1559 SmallVector<MCParsedAsmOperand *, 1> Operands; 1560 OperandMatchResultTy ResTy = ParseAnyRegister(Operands); 1561 if (ResTy == MatchOperand_Success) { 1562 assert(Operands.size() == 1); 1563 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front()); 1564 StartLoc = Operand.getStartLoc(); 1565 EndLoc = Operand.getEndLoc(); 1566 1567 // AFAIK, we only support numeric registers and named GPR's in CFI 1568 // directives. 1569 // Don't worry about eating tokens before failing. Using an unrecognised 1570 // register is a parse error. 1571 if (Operand.isGPRAsmReg()) { 1572 // Resolve to GPR32 or GPR64 appropriately. 1573 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 1574 } 1575 1576 delete &Operand; 1577 1578 return (RegNo == (unsigned)-1); 1579 } 1580 1581 assert(Operands.size() == 0); 1582 return (RegNo == (unsigned)-1); 1583 } 1584 1585 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1586 SMLoc S; 1587 bool Result = true; 1588 1589 while (getLexer().getKind() == AsmToken::LParen) 1590 Parser.Lex(); 1591 1592 switch (getLexer().getKind()) { 1593 default: 1594 return true; 1595 case AsmToken::Identifier: 1596 case AsmToken::LParen: 1597 case AsmToken::Integer: 1598 case AsmToken::Minus: 1599 case AsmToken::Plus: 1600 if (isParenExpr) 1601 Result = getParser().parseParenExpression(Res, S); 1602 else 1603 Result = (getParser().parseExpression(Res)); 1604 while (getLexer().getKind() == AsmToken::RParen) 1605 Parser.Lex(); 1606 break; 1607 case AsmToken::Percent: 1608 Result = parseRelocOperand(Res); 1609 } 1610 return Result; 1611 } 1612 1613 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 1614 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1615 DEBUG(dbgs() << "parseMemOperand\n"); 1616 const MCExpr *IdVal = 0; 1617 SMLoc S; 1618 bool isParenExpr = false; 1619 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 1620 // First operand is the offset. 1621 S = Parser.getTok().getLoc(); 1622 1623 if (getLexer().getKind() == AsmToken::LParen) { 1624 Parser.Lex(); 1625 isParenExpr = true; 1626 } 1627 1628 if (getLexer().getKind() != AsmToken::Dollar) { 1629 if (parseMemOffset(IdVal, isParenExpr)) 1630 return MatchOperand_ParseFail; 1631 1632 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1633 if (Tok.isNot(AsmToken::LParen)) { 1634 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]); 1635 if (Mnemonic->getToken() == "la") { 1636 SMLoc E = 1637 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1638 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1639 return MatchOperand_Success; 1640 } 1641 if (Tok.is(AsmToken::EndOfStatement)) { 1642 SMLoc E = 1643 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1644 1645 // Zero register assumed, add a memory operand with ZERO as its base. 1646 // "Base" will be managed by k_Memory. 1647 MipsOperand *Base = MipsOperand::CreateGPRReg( 1648 0, getContext().getRegisterInfo(), S, E, *this); 1649 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this)); 1650 return MatchOperand_Success; 1651 } 1652 Error(Parser.getTok().getLoc(), "'(' expected"); 1653 return MatchOperand_ParseFail; 1654 } 1655 1656 Parser.Lex(); // Eat the '(' token. 1657 } 1658 1659 Res = ParseAnyRegister(Operands); 1660 if (Res != MatchOperand_Success) 1661 return Res; 1662 1663 if (Parser.getTok().isNot(AsmToken::RParen)) { 1664 Error(Parser.getTok().getLoc(), "')' expected"); 1665 return MatchOperand_ParseFail; 1666 } 1667 1668 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1669 1670 Parser.Lex(); // Eat the ')' token. 1671 1672 if (IdVal == 0) 1673 IdVal = MCConstantExpr::Create(0, getContext()); 1674 1675 // Replace the register operand with the memory operand. 1676 MipsOperand *op = static_cast<MipsOperand *>(Operands.back()); 1677 // Remove the register from the operands. 1678 // "op" will be managed by k_Memory. 1679 Operands.pop_back(); 1680 // Add the memory operand. 1681 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 1682 int64_t Imm; 1683 if (IdVal->EvaluateAsAbsolute(Imm)) 1684 IdVal = MCConstantExpr::Create(Imm, getContext()); 1685 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 1686 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 1687 getContext()); 1688 } 1689 1690 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this)); 1691 return MatchOperand_Success; 1692 } 1693 1694 bool MipsAsmParser::searchSymbolAlias( 1695 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1696 1697 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1698 if (Sym) { 1699 SMLoc S = Parser.getTok().getLoc(); 1700 const MCExpr *Expr; 1701 if (Sym->isVariable()) 1702 Expr = Sym->getVariableValue(); 1703 else 1704 return false; 1705 if (Expr->getKind() == MCExpr::SymbolRef) { 1706 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 1707 const StringRef DefSymbol = Ref->getSymbol().getName(); 1708 if (DefSymbol.startswith("$")) { 1709 OperandMatchResultTy ResTy = 1710 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 1711 if (ResTy == MatchOperand_Success) { 1712 Parser.Lex(); 1713 return true; 1714 } else if (ResTy == MatchOperand_ParseFail) 1715 llvm_unreachable("Should never ParseFail"); 1716 return false; 1717 } 1718 } else if (Expr->getKind() == MCExpr::Constant) { 1719 Parser.Lex(); 1720 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 1721 MipsOperand *op = 1722 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this); 1723 Operands.push_back(op); 1724 return true; 1725 } 1726 } 1727 return false; 1728 } 1729 1730 MipsAsmParser::OperandMatchResultTy 1731 MipsAsmParser::MatchAnyRegisterNameWithoutDollar( 1732 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier, 1733 SMLoc S) { 1734 int Index = matchCPURegisterName(Identifier); 1735 if (Index != -1) { 1736 Operands.push_back(MipsOperand::CreateGPRReg( 1737 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1738 return MatchOperand_Success; 1739 } 1740 1741 Index = matchFPURegisterName(Identifier); 1742 if (Index != -1) { 1743 Operands.push_back(MipsOperand::CreateFGRReg( 1744 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1745 return MatchOperand_Success; 1746 } 1747 1748 Index = matchFCCRegisterName(Identifier); 1749 if (Index != -1) { 1750 Operands.push_back(MipsOperand::CreateFCCReg( 1751 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1752 return MatchOperand_Success; 1753 } 1754 1755 Index = matchACRegisterName(Identifier); 1756 if (Index != -1) { 1757 Operands.push_back(MipsOperand::CreateACCReg( 1758 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1759 return MatchOperand_Success; 1760 } 1761 1762 Index = matchMSA128RegisterName(Identifier); 1763 if (Index != -1) { 1764 Operands.push_back(MipsOperand::CreateMSA128Reg( 1765 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1766 return MatchOperand_Success; 1767 } 1768 1769 Index = matchMSA128CtrlRegisterName(Identifier); 1770 if (Index != -1) { 1771 Operands.push_back(MipsOperand::CreateMSACtrlReg( 1772 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1773 return MatchOperand_Success; 1774 } 1775 1776 return MatchOperand_NoMatch; 1777 } 1778 1779 MipsAsmParser::OperandMatchResultTy 1780 MipsAsmParser::MatchAnyRegisterWithoutDollar( 1781 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) { 1782 auto Token = Parser.getLexer().peekTok(false); 1783 1784 if (Token.is(AsmToken::Identifier)) { 1785 DEBUG(dbgs() << ".. identifier\n"); 1786 StringRef Identifier = Token.getIdentifier(); 1787 OperandMatchResultTy ResTy = 1788 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 1789 return ResTy; 1790 } else if (Token.is(AsmToken::Integer)) { 1791 DEBUG(dbgs() << ".. integer\n"); 1792 Operands.push_back(MipsOperand::CreateNumericReg( 1793 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 1794 *this)); 1795 return MatchOperand_Success; 1796 } 1797 1798 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 1799 1800 return MatchOperand_NoMatch; 1801 } 1802 1803 MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister( 1804 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1805 DEBUG(dbgs() << "ParseAnyRegister\n"); 1806 1807 auto Token = Parser.getTok(); 1808 1809 SMLoc S = Token.getLoc(); 1810 1811 if (Token.isNot(AsmToken::Dollar)) { 1812 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 1813 if (Token.is(AsmToken::Identifier)) { 1814 if (searchSymbolAlias(Operands)) 1815 return MatchOperand_Success; 1816 } 1817 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 1818 return MatchOperand_NoMatch; 1819 } 1820 DEBUG(dbgs() << ".. $\n"); 1821 1822 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S); 1823 if (ResTy == MatchOperand_Success) { 1824 Parser.Lex(); // $ 1825 Parser.Lex(); // identifier 1826 } 1827 return ResTy; 1828 } 1829 1830 MipsAsmParser::OperandMatchResultTy 1831 MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1832 switch (getLexer().getKind()) { 1833 default: 1834 return MatchOperand_NoMatch; 1835 case AsmToken::LParen: 1836 case AsmToken::Minus: 1837 case AsmToken::Plus: 1838 case AsmToken::Integer: 1839 case AsmToken::String: 1840 break; 1841 } 1842 1843 const MCExpr *IdVal; 1844 SMLoc S = Parser.getTok().getLoc(); 1845 if (getParser().parseExpression(IdVal)) 1846 return MatchOperand_ParseFail; 1847 1848 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1849 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1850 return MatchOperand_Success; 1851 } 1852 1853 MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget( 1854 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1855 DEBUG(dbgs() << "ParseJumpTarget\n"); 1856 1857 SMLoc S = getLexer().getLoc(); 1858 1859 // Integers and expressions are acceptable 1860 OperandMatchResultTy ResTy = ParseImm(Operands); 1861 if (ResTy != MatchOperand_NoMatch) 1862 return ResTy; 1863 1864 // Registers are a valid target and have priority over symbols. 1865 ResTy = ParseAnyRegister(Operands); 1866 if (ResTy != MatchOperand_NoMatch) 1867 return ResTy; 1868 1869 const MCExpr *Expr = nullptr; 1870 if (Parser.parseExpression(Expr)) { 1871 // We have no way of knowing if a symbol was consumed so we must ParseFail 1872 return MatchOperand_ParseFail; 1873 } 1874 Operands.push_back( 1875 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 1876 return MatchOperand_Success; 1877 } 1878 1879 MipsAsmParser::OperandMatchResultTy 1880 MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1881 const MCExpr *IdVal; 1882 // If the first token is '$' we may have register operand. 1883 if (Parser.getTok().is(AsmToken::Dollar)) 1884 return MatchOperand_NoMatch; 1885 SMLoc S = Parser.getTok().getLoc(); 1886 if (getParser().parseExpression(IdVal)) 1887 return MatchOperand_ParseFail; 1888 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 1889 assert(MCE && "Unexpected MCExpr type."); 1890 int64_t Val = MCE->getValue(); 1891 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1892 Operands.push_back(MipsOperand::CreateImm( 1893 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); 1894 return MatchOperand_Success; 1895 } 1896 1897 MipsAsmParser::OperandMatchResultTy 1898 MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1899 switch (getLexer().getKind()) { 1900 default: 1901 return MatchOperand_NoMatch; 1902 case AsmToken::LParen: 1903 case AsmToken::Plus: 1904 case AsmToken::Minus: 1905 case AsmToken::Integer: 1906 break; 1907 } 1908 1909 const MCExpr *Expr; 1910 SMLoc S = Parser.getTok().getLoc(); 1911 1912 if (getParser().parseExpression(Expr)) 1913 return MatchOperand_ParseFail; 1914 1915 int64_t Val; 1916 if (!Expr->EvaluateAsAbsolute(Val)) { 1917 Error(S, "expected immediate value"); 1918 return MatchOperand_ParseFail; 1919 } 1920 1921 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 1922 // and because the CPU always adds one to the immediate field, the allowed 1923 // range becomes 1..4. We'll only check the range here and will deal 1924 // with the addition/subtraction when actually decoding/encoding 1925 // the instruction. 1926 if (Val < 1 || Val > 4) { 1927 Error(S, "immediate not in range (1..4)"); 1928 return MatchOperand_ParseFail; 1929 } 1930 1931 Operands.push_back( 1932 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 1933 return MatchOperand_Success; 1934 } 1935 1936 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1937 1938 MCSymbolRefExpr::VariantKind VK = 1939 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1940 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1941 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1942 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1943 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1944 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1945 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1946 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1947 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1948 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1949 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1950 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1951 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1952 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1953 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1954 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1955 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1956 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1957 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16) 1958 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16) 1959 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16) 1960 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16) 1961 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER) 1962 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST) 1963 .Default(MCSymbolRefExpr::VK_None); 1964 1965 assert (VK != MCSymbolRefExpr::VK_None); 1966 1967 return VK; 1968 } 1969 1970 /// Sometimes (i.e. load/stores) the operand may be followed immediately by 1971 /// either this. 1972 /// ::= '(', register, ')' 1973 /// handle it before we iterate so we don't get tripped up by the lack of 1974 /// a comma. 1975 bool MipsAsmParser::ParseParenSuffix( 1976 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1977 if (getLexer().is(AsmToken::LParen)) { 1978 Operands.push_back( 1979 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 1980 Parser.Lex(); 1981 if (ParseOperand(Operands, Name)) { 1982 SMLoc Loc = getLexer().getLoc(); 1983 Parser.eatToEndOfStatement(); 1984 return Error(Loc, "unexpected token in argument list"); 1985 } 1986 if (Parser.getTok().isNot(AsmToken::RParen)) { 1987 SMLoc Loc = getLexer().getLoc(); 1988 Parser.eatToEndOfStatement(); 1989 return Error(Loc, "unexpected token, expected ')'"); 1990 } 1991 Operands.push_back( 1992 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 1993 Parser.Lex(); 1994 } 1995 return false; 1996 } 1997 1998 /// Sometimes (i.e. in MSA) the operand may be followed immediately by 1999 /// either one of these. 2000 /// ::= '[', register, ']' 2001 /// ::= '[', integer, ']' 2002 /// handle it before we iterate so we don't get tripped up by the lack of 2003 /// a comma. 2004 bool MipsAsmParser::ParseBracketSuffix( 2005 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2006 if (getLexer().is(AsmToken::LBrac)) { 2007 Operands.push_back( 2008 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 2009 Parser.Lex(); 2010 if (ParseOperand(Operands, Name)) { 2011 SMLoc Loc = getLexer().getLoc(); 2012 Parser.eatToEndOfStatement(); 2013 return Error(Loc, "unexpected token in argument list"); 2014 } 2015 if (Parser.getTok().isNot(AsmToken::RBrac)) { 2016 SMLoc Loc = getLexer().getLoc(); 2017 Parser.eatToEndOfStatement(); 2018 return Error(Loc, "unexpected token, expected ']'"); 2019 } 2020 Operands.push_back( 2021 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 2022 Parser.Lex(); 2023 } 2024 return false; 2025 } 2026 2027 bool MipsAsmParser::ParseInstruction( 2028 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 2029 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2030 DEBUG(dbgs() << "ParseInstruction\n"); 2031 // Check if we have valid mnemonic 2032 if (!mnemonicIsValid(Name, 0)) { 2033 Parser.eatToEndOfStatement(); 2034 return Error(NameLoc, "Unknown instruction"); 2035 } 2036 // First operand in MCInst is instruction mnemonic. 2037 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 2038 2039 // Read the remaining operands. 2040 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2041 // Read the first operand. 2042 if (ParseOperand(Operands, Name)) { 2043 SMLoc Loc = getLexer().getLoc(); 2044 Parser.eatToEndOfStatement(); 2045 return Error(Loc, "unexpected token in argument list"); 2046 } 2047 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands)) 2048 return true; 2049 // AFAIK, parenthesis suffixes are never on the first operand 2050 2051 while (getLexer().is(AsmToken::Comma)) { 2052 Parser.Lex(); // Eat the comma. 2053 // Parse and remember the operand. 2054 if (ParseOperand(Operands, Name)) { 2055 SMLoc Loc = getLexer().getLoc(); 2056 Parser.eatToEndOfStatement(); 2057 return Error(Loc, "unexpected token in argument list"); 2058 } 2059 // Parse bracket and parenthesis suffixes before we iterate 2060 if (getLexer().is(AsmToken::LBrac)) { 2061 if (ParseBracketSuffix(Name, Operands)) 2062 return true; 2063 } else if (getLexer().is(AsmToken::LParen) && 2064 ParseParenSuffix(Name, Operands)) 2065 return true; 2066 } 2067 } 2068 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2069 SMLoc Loc = getLexer().getLoc(); 2070 Parser.eatToEndOfStatement(); 2071 return Error(Loc, "unexpected token in argument list"); 2072 } 2073 Parser.Lex(); // Consume the EndOfStatement. 2074 return false; 2075 } 2076 2077 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 2078 SMLoc Loc = getLexer().getLoc(); 2079 Parser.eatToEndOfStatement(); 2080 return Error(Loc, ErrorMsg); 2081 } 2082 2083 bool MipsAsmParser::parseSetNoAtDirective() { 2084 // Line should look like: ".set noat". 2085 // set at reg to 0. 2086 Options.setATReg(0); 2087 // eat noat 2088 Parser.Lex(); 2089 // If this is not the end of the statement, report an error. 2090 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2091 reportParseError("unexpected token in statement"); 2092 return false; 2093 } 2094 Parser.Lex(); // Consume the EndOfStatement. 2095 return false; 2096 } 2097 2098 bool MipsAsmParser::parseSetAtDirective() { 2099 // Line can be .set at - defaults to $1 2100 // or .set at=$reg 2101 int AtRegNo; 2102 getParser().Lex(); 2103 if (getLexer().is(AsmToken::EndOfStatement)) { 2104 Options.setATReg(1); 2105 Parser.Lex(); // Consume the EndOfStatement. 2106 return false; 2107 } else if (getLexer().is(AsmToken::Equal)) { 2108 getParser().Lex(); // Eat the '='. 2109 if (getLexer().isNot(AsmToken::Dollar)) { 2110 reportParseError("unexpected token in statement"); 2111 return false; 2112 } 2113 Parser.Lex(); // Eat the '$'. 2114 const AsmToken &Reg = Parser.getTok(); 2115 if (Reg.is(AsmToken::Identifier)) { 2116 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 2117 } else if (Reg.is(AsmToken::Integer)) { 2118 AtRegNo = Reg.getIntVal(); 2119 } else { 2120 reportParseError("unexpected token in statement"); 2121 return false; 2122 } 2123 2124 if (AtRegNo < 0 || AtRegNo > 31) { 2125 reportParseError("unexpected token in statement"); 2126 return false; 2127 } 2128 2129 if (!Options.setATReg(AtRegNo)) { 2130 reportParseError("unexpected token in statement"); 2131 return false; 2132 } 2133 getParser().Lex(); // Eat the register. 2134 2135 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2136 reportParseError("unexpected token in statement"); 2137 return false; 2138 } 2139 Parser.Lex(); // Consume the EndOfStatement. 2140 return false; 2141 } else { 2142 reportParseError("unexpected token in statement"); 2143 return false; 2144 } 2145 } 2146 2147 bool MipsAsmParser::parseSetReorderDirective() { 2148 Parser.Lex(); 2149 // If this is not the end of the statement, report an error. 2150 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2151 reportParseError("unexpected token in statement"); 2152 return false; 2153 } 2154 Options.setReorder(); 2155 getTargetStreamer().emitDirectiveSetReorder(); 2156 Parser.Lex(); // Consume the EndOfStatement. 2157 return false; 2158 } 2159 2160 bool MipsAsmParser::parseSetNoReorderDirective() { 2161 Parser.Lex(); 2162 // If this is not the end of the statement, report an error. 2163 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2164 reportParseError("unexpected token in statement"); 2165 return false; 2166 } 2167 Options.setNoreorder(); 2168 getTargetStreamer().emitDirectiveSetNoReorder(); 2169 Parser.Lex(); // Consume the EndOfStatement. 2170 return false; 2171 } 2172 2173 bool MipsAsmParser::parseSetMacroDirective() { 2174 Parser.Lex(); 2175 // If this is not the end of the statement, report an error. 2176 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2177 reportParseError("unexpected token in statement"); 2178 return false; 2179 } 2180 Options.setMacro(); 2181 Parser.Lex(); // Consume the EndOfStatement. 2182 return false; 2183 } 2184 2185 bool MipsAsmParser::parseSetNoMacroDirective() { 2186 Parser.Lex(); 2187 // If this is not the end of the statement, report an error. 2188 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2189 reportParseError("`noreorder' must be set before `nomacro'"); 2190 return false; 2191 } 2192 if (Options.isReorder()) { 2193 reportParseError("`noreorder' must be set before `nomacro'"); 2194 return false; 2195 } 2196 Options.setNomacro(); 2197 Parser.Lex(); // Consume the EndOfStatement. 2198 return false; 2199 } 2200 2201 bool MipsAsmParser::parseSetNoMips16Directive() { 2202 Parser.Lex(); 2203 // If this is not the end of the statement, report an error. 2204 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2205 reportParseError("unexpected token in statement"); 2206 return false; 2207 } 2208 // For now do nothing. 2209 Parser.Lex(); // Consume the EndOfStatement. 2210 return false; 2211 } 2212 2213 bool MipsAsmParser::parseSetAssignment() { 2214 StringRef Name; 2215 const MCExpr *Value; 2216 2217 if (Parser.parseIdentifier(Name)) 2218 reportParseError("expected identifier after .set"); 2219 2220 if (getLexer().isNot(AsmToken::Comma)) 2221 return reportParseError("unexpected token in .set directive"); 2222 Lex(); // Eat comma 2223 2224 if (Parser.parseExpression(Value)) 2225 return reportParseError("expected valid expression after comma"); 2226 2227 // Check if the Name already exists as a symbol. 2228 MCSymbol *Sym = getContext().LookupSymbol(Name); 2229 if (Sym) 2230 return reportParseError("symbol already defined"); 2231 Sym = getContext().GetOrCreateSymbol(Name); 2232 Sym->setVariableValue(Value); 2233 2234 return false; 2235 } 2236 2237 bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 2238 Parser.Lex(); 2239 if (getLexer().isNot(AsmToken::EndOfStatement)) 2240 return reportParseError("unexpected token in .set directive"); 2241 2242 switch(Feature) { 2243 default: llvm_unreachable("Unimplemented feature"); 2244 case Mips::FeatureDSP: 2245 setFeatureBits(Mips::FeatureDSP, "dsp"); 2246 getTargetStreamer().emitDirectiveSetDsp(); 2247 break; 2248 case Mips::FeatureMicroMips: 2249 getTargetStreamer().emitDirectiveSetMicroMips(); 2250 break; 2251 case Mips::FeatureMips16: 2252 getTargetStreamer().emitDirectiveSetMips16(); 2253 break; 2254 case Mips::FeatureMips32r2: 2255 setFeatureBits(Mips::FeatureMips32r2, "mips32r2"); 2256 getTargetStreamer().emitDirectiveSetMips32R2(); 2257 break; 2258 case Mips::FeatureMips64: 2259 setFeatureBits(Mips::FeatureMips64, "mips64"); 2260 getTargetStreamer().emitDirectiveSetMips64(); 2261 break; 2262 case Mips::FeatureMips64r2: 2263 setFeatureBits(Mips::FeatureMips64r2, "mips64r2"); 2264 getTargetStreamer().emitDirectiveSetMips64R2(); 2265 break; 2266 } 2267 return false; 2268 } 2269 2270 bool MipsAsmParser::parseRegister(unsigned &RegNum) { 2271 if (!getLexer().is(AsmToken::Dollar)) 2272 return false; 2273 2274 Parser.Lex(); 2275 2276 const AsmToken &Reg = Parser.getTok(); 2277 if (Reg.is(AsmToken::Identifier)) { 2278 RegNum = matchCPURegisterName(Reg.getIdentifier()); 2279 } else if (Reg.is(AsmToken::Integer)) { 2280 RegNum = Reg.getIntVal(); 2281 } else { 2282 return false; 2283 } 2284 2285 Parser.Lex(); 2286 return true; 2287 } 2288 2289 bool MipsAsmParser::eatComma(StringRef ErrorStr) { 2290 if (getLexer().isNot(AsmToken::Comma)) { 2291 SMLoc Loc = getLexer().getLoc(); 2292 Parser.eatToEndOfStatement(); 2293 return Error(Loc, ErrorStr); 2294 } 2295 2296 Parser.Lex(); // Eat the comma. 2297 return true; 2298 } 2299 2300 bool MipsAsmParser::parseDirectiveCPSetup() { 2301 unsigned FuncReg; 2302 unsigned Save; 2303 bool SaveIsReg = true; 2304 2305 if (!parseRegister(FuncReg)) 2306 return reportParseError("expected register containing function address"); 2307 FuncReg = getGPR(FuncReg); 2308 2309 if (!eatComma("expected comma parsing directive")) 2310 return true; 2311 2312 if (!parseRegister(Save)) { 2313 const AsmToken &Tok = Parser.getTok(); 2314 if (Tok.is(AsmToken::Integer)) { 2315 Save = Tok.getIntVal(); 2316 SaveIsReg = false; 2317 Parser.Lex(); 2318 } else 2319 return reportParseError("expected save register or stack offset"); 2320 } else 2321 Save = getGPR(Save); 2322 2323 if (!eatComma("expected comma parsing directive")) 2324 return true; 2325 2326 StringRef Name; 2327 if (Parser.parseIdentifier(Name)) 2328 reportParseError("expected identifier"); 2329 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2330 unsigned GPReg = getGPR(matchCPURegisterName("gp")); 2331 2332 // FIXME: The code below this point should be in the TargetStreamers. 2333 // Only N32 and N64 emit anything for .cpsetup 2334 // FIXME: We should only emit something for PIC mode too. 2335 if (!isN32() && !isN64()) 2336 return false; 2337 2338 MCStreamer &TS = getStreamer(); 2339 MCInst Inst; 2340 // Either store the old $gp in a register or on the stack 2341 if (SaveIsReg) { 2342 // move $save, $gpreg 2343 Inst.setOpcode(Mips::DADDu); 2344 Inst.addOperand(MCOperand::CreateReg(Save)); 2345 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2346 Inst.addOperand(MCOperand::CreateReg(getGPR(0))); 2347 } else { 2348 // sd $gpreg, offset($sp) 2349 Inst.setOpcode(Mips::SD); 2350 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2351 Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp")))); 2352 Inst.addOperand(MCOperand::CreateImm(Save)); 2353 } 2354 TS.EmitInstruction(Inst, STI); 2355 Inst.clear(); 2356 2357 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 2358 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, 2359 getContext()); 2360 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 2361 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, 2362 getContext()); 2363 // lui $gp, %hi(%neg(%gp_rel(funcSym))) 2364 Inst.setOpcode(Mips::LUi); 2365 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2366 Inst.addOperand(MCOperand::CreateExpr(HiExpr)); 2367 TS.EmitInstruction(Inst, STI); 2368 Inst.clear(); 2369 2370 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) 2371 Inst.setOpcode(Mips::ADDiu); 2372 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2373 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2374 Inst.addOperand(MCOperand::CreateExpr(LoExpr)); 2375 TS.EmitInstruction(Inst, STI); 2376 Inst.clear(); 2377 2378 // daddu $gp, $gp, $funcreg 2379 Inst.setOpcode(Mips::DADDu); 2380 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2381 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2382 Inst.addOperand(MCOperand::CreateReg(FuncReg)); 2383 TS.EmitInstruction(Inst, STI); 2384 return false; 2385 } 2386 2387 bool MipsAsmParser::parseDirectiveNaN() { 2388 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2389 const AsmToken &Tok = Parser.getTok(); 2390 2391 if (Tok.getString() == "2008") { 2392 Parser.Lex(); 2393 getTargetStreamer().emitDirectiveNaN2008(); 2394 return false; 2395 } else if (Tok.getString() == "legacy") { 2396 Parser.Lex(); 2397 getTargetStreamer().emitDirectiveNaNLegacy(); 2398 return false; 2399 } 2400 } 2401 // If we don't recognize the option passed to the .nan 2402 // directive (e.g. no option or unknown option), emit an error. 2403 reportParseError("invalid option in .nan directive"); 2404 return false; 2405 } 2406 2407 bool MipsAsmParser::parseDirectiveSet() { 2408 2409 // Get the next token. 2410 const AsmToken &Tok = Parser.getTok(); 2411 2412 if (Tok.getString() == "noat") { 2413 return parseSetNoAtDirective(); 2414 } else if (Tok.getString() == "at") { 2415 return parseSetAtDirective(); 2416 } else if (Tok.getString() == "reorder") { 2417 return parseSetReorderDirective(); 2418 } else if (Tok.getString() == "noreorder") { 2419 return parseSetNoReorderDirective(); 2420 } else if (Tok.getString() == "macro") { 2421 return parseSetMacroDirective(); 2422 } else if (Tok.getString() == "nomacro") { 2423 return parseSetNoMacroDirective(); 2424 } else if (Tok.getString() == "mips16") { 2425 return parseSetFeature(Mips::FeatureMips16); 2426 } else if (Tok.getString() == "nomips16") { 2427 return parseSetNoMips16Directive(); 2428 } else if (Tok.getString() == "nomicromips") { 2429 getTargetStreamer().emitDirectiveSetNoMicroMips(); 2430 Parser.eatToEndOfStatement(); 2431 return false; 2432 } else if (Tok.getString() == "micromips") { 2433 return parseSetFeature(Mips::FeatureMicroMips); 2434 } else if (Tok.getString() == "mips32r2") { 2435 return parseSetFeature(Mips::FeatureMips32r2); 2436 } else if (Tok.getString() == "mips64") { 2437 return parseSetFeature(Mips::FeatureMips64); 2438 } else if (Tok.getString() == "mips64r2") { 2439 return parseSetFeature(Mips::FeatureMips64r2); 2440 } else if (Tok.getString() == "dsp") { 2441 return parseSetFeature(Mips::FeatureDSP); 2442 } else { 2443 // It is just an identifier, look for an assignment. 2444 parseSetAssignment(); 2445 return false; 2446 } 2447 2448 return true; 2449 } 2450 2451 /// parseDataDirective 2452 /// ::= .word [ expression (, expression)* ] 2453 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 2454 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2455 for (;;) { 2456 const MCExpr *Value; 2457 if (getParser().parseExpression(Value)) 2458 return true; 2459 2460 getParser().getStreamer().EmitValue(Value, Size); 2461 2462 if (getLexer().is(AsmToken::EndOfStatement)) 2463 break; 2464 2465 // FIXME: Improve diagnostic. 2466 if (getLexer().isNot(AsmToken::Comma)) 2467 return Error(L, "unexpected token in directive"); 2468 Parser.Lex(); 2469 } 2470 } 2471 2472 Parser.Lex(); 2473 return false; 2474 } 2475 2476 /// parseDirectiveGpWord 2477 /// ::= .gpword local_sym 2478 bool MipsAsmParser::parseDirectiveGpWord() { 2479 const MCExpr *Value; 2480 // EmitGPRel32Value requires an expression, so we are using base class 2481 // method to evaluate the expression. 2482 if (getParser().parseExpression(Value)) 2483 return true; 2484 getParser().getStreamer().EmitGPRel32Value(Value); 2485 2486 if (getLexer().isNot(AsmToken::EndOfStatement)) 2487 return Error(getLexer().getLoc(), "unexpected token in directive"); 2488 Parser.Lex(); // Eat EndOfStatement token. 2489 return false; 2490 } 2491 2492 /// parseDirectiveGpDWord 2493 /// ::= .gpdword local_sym 2494 bool MipsAsmParser::parseDirectiveGpDWord() { 2495 const MCExpr *Value; 2496 // EmitGPRel64Value requires an expression, so we are using base class 2497 // method to evaluate the expression. 2498 if (getParser().parseExpression(Value)) 2499 return true; 2500 getParser().getStreamer().EmitGPRel64Value(Value); 2501 2502 if (getLexer().isNot(AsmToken::EndOfStatement)) 2503 return Error(getLexer().getLoc(), "unexpected token in directive"); 2504 Parser.Lex(); // Eat EndOfStatement token. 2505 return false; 2506 } 2507 2508 bool MipsAsmParser::parseDirectiveOption() { 2509 // Get the option token. 2510 AsmToken Tok = Parser.getTok(); 2511 // At the moment only identifiers are supported. 2512 if (Tok.isNot(AsmToken::Identifier)) { 2513 Error(Parser.getTok().getLoc(), "unexpected token in .option directive"); 2514 Parser.eatToEndOfStatement(); 2515 return false; 2516 } 2517 2518 StringRef Option = Tok.getIdentifier(); 2519 2520 if (Option == "pic0") { 2521 getTargetStreamer().emitDirectiveOptionPic0(); 2522 Parser.Lex(); 2523 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2524 Error(Parser.getTok().getLoc(), 2525 "unexpected token in .option pic0 directive"); 2526 Parser.eatToEndOfStatement(); 2527 } 2528 return false; 2529 } 2530 2531 if (Option == "pic2") { 2532 getTargetStreamer().emitDirectiveOptionPic2(); 2533 Parser.Lex(); 2534 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2535 Error(Parser.getTok().getLoc(), 2536 "unexpected token in .option pic2 directive"); 2537 Parser.eatToEndOfStatement(); 2538 } 2539 return false; 2540 } 2541 2542 // Unknown option. 2543 Warning(Parser.getTok().getLoc(), "unknown option in .option directive"); 2544 Parser.eatToEndOfStatement(); 2545 return false; 2546 } 2547 2548 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 2549 StringRef IDVal = DirectiveID.getString(); 2550 2551 if (IDVal == ".dword") { 2552 parseDataDirective(8, DirectiveID.getLoc()); 2553 return false; 2554 } 2555 2556 if (IDVal == ".ent") { 2557 // Ignore this directive for now. 2558 Parser.Lex(); 2559 return false; 2560 } 2561 2562 if (IDVal == ".end") { 2563 // Ignore this directive for now. 2564 Parser.Lex(); 2565 return false; 2566 } 2567 2568 if (IDVal == ".frame") { 2569 // Ignore this directive for now. 2570 Parser.eatToEndOfStatement(); 2571 return false; 2572 } 2573 2574 if (IDVal == ".set") { 2575 return parseDirectiveSet(); 2576 } 2577 2578 if (IDVal == ".fmask") { 2579 // Ignore this directive for now. 2580 Parser.eatToEndOfStatement(); 2581 return false; 2582 } 2583 2584 if (IDVal == ".mask") { 2585 // Ignore this directive for now. 2586 Parser.eatToEndOfStatement(); 2587 return false; 2588 } 2589 2590 if (IDVal == ".nan") 2591 return parseDirectiveNaN(); 2592 2593 if (IDVal == ".gpword") { 2594 parseDirectiveGpWord(); 2595 return false; 2596 } 2597 2598 if (IDVal == ".gpdword") { 2599 parseDirectiveGpDWord(); 2600 return false; 2601 } 2602 2603 if (IDVal == ".word") { 2604 parseDataDirective(4, DirectiveID.getLoc()); 2605 return false; 2606 } 2607 2608 if (IDVal == ".option") 2609 return parseDirectiveOption(); 2610 2611 if (IDVal == ".abicalls") { 2612 getTargetStreamer().emitDirectiveAbiCalls(); 2613 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2614 Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2615 // Clear line 2616 Parser.eatToEndOfStatement(); 2617 } 2618 return false; 2619 } 2620 2621 if (IDVal == ".cpsetup") 2622 return parseDirectiveCPSetup(); 2623 2624 return true; 2625 } 2626 2627 extern "C" void LLVMInitializeMipsAsmParser() { 2628 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 2629 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 2630 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 2631 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 2632 } 2633 2634 #define GET_REGISTER_MATCHER 2635 #define GET_MATCHER_IMPLEMENTATION 2636 #include "MipsGenAsmMatcher.inc" 2637