MipsAsmParser.cpp revision 37ed9c199ca639565f6ce88105f9e39e898d82d0
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/ADT/SmallVector.h" 17#include "llvm/MC/MCContext.h" 18#include "llvm/MC/MCExpr.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/MC/MCInstBuilder.h" 21#include "llvm/MC/MCParser/MCAsmLexer.h" 22#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 23#include "llvm/MC/MCStreamer.h" 24#include "llvm/MC/MCSubtargetInfo.h" 25#include "llvm/MC/MCSymbol.h" 26#include "llvm/MC/MCTargetAsmParser.h" 27#include "llvm/Support/Debug.h" 28#include "llvm/Support/MathExtras.h" 29#include "llvm/Support/TargetRegistry.h" 30#include "llvm/Support/SourceMgr.h" 31#include <memory> 32 33using namespace llvm; 34 35#define DEBUG_TYPE "mips-asm-parser" 36 37namespace llvm { 38class MCInstrInfo; 39} 40 41namespace { 42class MipsAssemblerOptions { 43public: 44 MipsAssemblerOptions(uint64_t Features_) : 45 ATReg(1), Reorder(true), Macro(true), Features(Features_) {} 46 47 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) { 48 ATReg = Opts->getATRegNum(); 49 Reorder = Opts->isReorder(); 50 Macro = Opts->isMacro(); 51 Features = Opts->getFeatures(); 52 } 53 54 unsigned getATRegNum() const { return ATReg; } 55 bool setATReg(unsigned Reg); 56 57 bool isReorder() const { return Reorder; } 58 void setReorder() { Reorder = true; } 59 void setNoReorder() { Reorder = false; } 60 61 bool isMacro() const { return Macro; } 62 void setMacro() { Macro = true; } 63 void setNoMacro() { Macro = false; } 64 65 uint64_t getFeatures() const { return Features; } 66 void setFeatures(uint64_t Features_) { Features = Features_; } 67 68 // Set of features that are either architecture features or referenced 69 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6). 70 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]). 71 // The reason we need this mask is explained in the selectArch function. 72 // FIXME: Ideally we would like TableGen to generate this information. 73 static const uint64_t AllArchRelatedMask = 74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 | 75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 | 76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 | 77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 | 78 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 | 79 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit | 80 Mips::FeatureGP64Bit | Mips::FeatureNaN2008; 81 82private: 83 unsigned ATReg; 84 bool Reorder; 85 bool Macro; 86 uint64_t Features; 87}; 88} 89 90namespace { 91class MipsAsmParser : public MCTargetAsmParser { 92 MipsTargetStreamer &getTargetStreamer() { 93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 94 return static_cast<MipsTargetStreamer &>(TS); 95 } 96 97 MCSubtargetInfo &STI; 98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions; 99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a 100 // nullptr, which indicates that no function is currently 101 // selected. This usually happens after an '.end func' 102 // directive. 103 104 // Print a warning along with its fix-it message at the given range. 105 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, 106 SMRange Range, bool ShowColors = true); 107 108#define GET_ASSEMBLER_HEADER 109#include "MipsGenAsmMatcher.inc" 110 111 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 112 113 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 114 OperandVector &Operands, MCStreamer &Out, 115 uint64_t &ErrorInfo, 116 bool MatchingInlineAsm) override; 117 118 /// Parse a register as used in CFI directives 119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 120 121 bool parseParenSuffix(StringRef Name, OperandVector &Operands); 122 123 bool parseBracketSuffix(StringRef Name, OperandVector &Operands); 124 125 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 126 SMLoc NameLoc, OperandVector &Operands) override; 127 128 bool ParseDirective(AsmToken DirectiveID) override; 129 130 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands); 131 132 MipsAsmParser::OperandMatchResultTy 133 matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 134 StringRef Identifier, SMLoc S); 135 136 MipsAsmParser::OperandMatchResultTy 137 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S); 138 139 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands); 140 141 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands); 142 143 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands); 144 145 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands); 146 147 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands); 148 149 MipsAsmParser::OperandMatchResultTy 150 parseRegisterList (OperandVector &Operands); 151 152 bool searchSymbolAlias(OperandVector &Operands); 153 154 bool parseOperand(OperandVector &, StringRef Mnemonic); 155 156 bool needsExpansion(MCInst &Inst); 157 158 // Expands assembly pseudo instructions. 159 // Returns false on success, true otherwise. 160 bool expandInstruction(MCInst &Inst, SMLoc IDLoc, 161 SmallVectorImpl<MCInst> &Instructions); 162 163 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, 164 SmallVectorImpl<MCInst> &Instructions); 165 166 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 167 SmallVectorImpl<MCInst> &Instructions); 168 169 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 170 SmallVectorImpl<MCInst> &Instructions); 171 172 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc, 173 SmallVectorImpl<MCInst> &Instructions); 174 175 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 176 SmallVectorImpl<MCInst> &Instructions, bool isLoad, 177 bool isImmOpnd); 178 bool reportParseError(Twine ErrorMsg); 179 bool reportParseError(SMLoc Loc, Twine ErrorMsg); 180 181 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 182 bool parseRelocOperand(const MCExpr *&Res); 183 184 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 185 186 bool isEvaluated(const MCExpr *Expr); 187 bool parseSetMips0Directive(); 188 bool parseSetArchDirective(); 189 bool parseSetFeature(uint64_t Feature); 190 bool parseDirectiveCpLoad(SMLoc Loc); 191 bool parseDirectiveCPSetup(); 192 bool parseDirectiveNaN(); 193 bool parseDirectiveSet(); 194 bool parseDirectiveOption(); 195 196 bool parseSetAtDirective(); 197 bool parseSetNoAtDirective(); 198 bool parseSetMacroDirective(); 199 bool parseSetNoMacroDirective(); 200 bool parseSetMsaDirective(); 201 bool parseSetNoMsaDirective(); 202 bool parseSetNoDspDirective(); 203 bool parseSetReorderDirective(); 204 bool parseSetNoReorderDirective(); 205 bool parseSetMips16Directive(); 206 bool parseSetNoMips16Directive(); 207 bool parseSetFpDirective(); 208 bool parseSetPopDirective(); 209 bool parseSetPushDirective(); 210 211 bool parseSetAssignment(); 212 213 bool parseDataDirective(unsigned Size, SMLoc L); 214 bool parseDirectiveGpWord(); 215 bool parseDirectiveGpDWord(); 216 bool parseDirectiveModule(); 217 bool parseDirectiveModuleFP(); 218 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 219 StringRef Directive); 220 221 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 222 223 bool eatComma(StringRef ErrorStr); 224 225 int matchCPURegisterName(StringRef Symbol); 226 227 int matchHWRegsRegisterName(StringRef Symbol); 228 229 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 230 231 int matchFPURegisterName(StringRef Name); 232 233 int matchFCCRegisterName(StringRef Name); 234 235 int matchACRegisterName(StringRef Name); 236 237 int matchMSA128RegisterName(StringRef Name); 238 239 int matchMSA128CtrlRegisterName(StringRef Name); 240 241 unsigned getReg(int RC, int RegNo); 242 243 unsigned getGPR(int RegNo); 244 245 int getATReg(SMLoc Loc); 246 247 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 248 SmallVectorImpl<MCInst> &Instructions); 249 250 // Helper function that checks if the value of a vector index is within the 251 // boundaries of accepted values for each RegisterKind 252 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 253 bool validateMSAIndex(int Val, int RegKind); 254 255 // Selects a new architecture by updating the FeatureBits with the necessary 256 // info including implied dependencies. 257 // Internally, it clears all the feature bits related to *any* architecture 258 // and selects the new one using the ToggleFeature functionality of the 259 // MCSubtargetInfo object that handles implied dependencies. The reason we 260 // clear all the arch related bits manually is because ToggleFeature only 261 // clears the features that imply the feature being cleared and not the 262 // features implied by the feature being cleared. This is easier to see 263 // with an example: 264 // -------------------------------------------------- 265 // | Feature | Implies | 266 // | -------------------------------------------------| 267 // | FeatureMips1 | None | 268 // | FeatureMips2 | FeatureMips1 | 269 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 | 270 // | FeatureMips4 | FeatureMips3 | 271 // | ... | | 272 // -------------------------------------------------- 273 // 274 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 | 275 // FeatureMipsGP64 | FeatureMips1) 276 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4). 277 void selectArch(StringRef ArchFeature) { 278 uint64_t FeatureBits = STI.getFeatureBits(); 279 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask; 280 STI.setFeatureBits(FeatureBits); 281 setAvailableFeatures( 282 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature))); 283 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 284 } 285 286 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 287 if (!(STI.getFeatureBits() & Feature)) { 288 setAvailableFeatures( 289 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 290 } 291 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 292 } 293 294 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 295 if (STI.getFeatureBits() & Feature) { 296 setAvailableFeatures( 297 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 298 } 299 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 300 } 301 302public: 303 enum MipsMatchResultTy { 304 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY 305#define GET_OPERAND_DIAGNOSTIC_TYPES 306#include "MipsGenAsmMatcher.inc" 307#undef GET_OPERAND_DIAGNOSTIC_TYPES 308 309 }; 310 311 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 312 const MCInstrInfo &MII, const MCTargetOptions &Options) 313 : MCTargetAsmParser(), STI(sti) { 314 MCAsmParserExtension::Initialize(parser); 315 316 // Initialize the set of available features. 317 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 318 319 // Remember the initial assembler options. The user can not modify these. 320 AssemblerOptions.push_back( 321 make_unique<MipsAssemblerOptions>(getAvailableFeatures())); 322 323 // Create an assembler options environment for the user to modify. 324 AssemblerOptions.push_back( 325 make_unique<MipsAssemblerOptions>(getAvailableFeatures())); 326 327 getTargetStreamer().updateABIInfo(*this); 328 329 // Assert exactly one ABI was chosen. 330 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + 331 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + 332 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + 333 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); 334 335 if (!isABI_O32() && !useOddSPReg() != 0) 336 report_fatal_error("-mno-odd-spreg requires the O32 ABI"); 337 338 CurrentFn = nullptr; 339 } 340 341 /// True if all of $fcc0 - $fcc7 exist for the current ISA. 342 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); } 343 344 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } 345 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; } 346 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; } 347 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 348 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; } 349 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; } 350 351 bool useOddSPReg() const { 352 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg); 353 } 354 355 bool inMicroMipsMode() const { 356 return STI.getFeatureBits() & Mips::FeatureMicroMips; 357 } 358 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; } 359 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; } 360 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } 361 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; } 362 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; } 363 bool hasMips32() const { 364 return (STI.getFeatureBits() & Mips::FeatureMips32); 365 } 366 bool hasMips64() const { 367 return (STI.getFeatureBits() & Mips::FeatureMips64); 368 } 369 bool hasMips32r2() const { 370 return (STI.getFeatureBits() & Mips::FeatureMips32r2); 371 } 372 bool hasMips64r2() const { 373 return (STI.getFeatureBits() & Mips::FeatureMips64r2); 374 } 375 bool hasMips32r6() const { 376 return (STI.getFeatureBits() & Mips::FeatureMips32r6); 377 } 378 bool hasMips64r6() const { 379 return (STI.getFeatureBits() & Mips::FeatureMips64r6); 380 } 381 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); } 382 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); } 383 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); } 384 385 bool inMips16Mode() const { 386 return STI.getFeatureBits() & Mips::FeatureMips16; 387 } 388 // TODO: see how can we get this info. 389 bool abiUsesSoftFloat() const { return false; } 390 391 /// Warn if RegNo is the current assembler temporary. 392 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc); 393}; 394} 395 396namespace { 397 398/// MipsOperand - Instances of this class represent a parsed Mips machine 399/// instruction. 400class MipsOperand : public MCParsedAsmOperand { 401public: 402 /// Broad categories of register classes 403 /// The exact class is finalized by the render method. 404 enum RegKind { 405 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit()) 406 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 407 /// isFP64bit()) 408 RegKind_FCC = 4, /// FCC 409 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 410 RegKind_MSACtrl = 16, /// MSA control registers 411 RegKind_COP2 = 32, /// COP2 412 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 413 /// context). 414 RegKind_CCR = 128, /// CCR 415 RegKind_HWRegs = 256, /// HWRegs 416 RegKind_COP3 = 512, /// COP3 417 418 /// Potentially any (e.g. $1) 419 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 420 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 421 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 422 }; 423 424private: 425 enum KindTy { 426 k_Immediate, /// An immediate (possibly involving symbol references) 427 k_Memory, /// Base + Offset Memory Address 428 k_PhysRegister, /// A physical register from the Mips namespace 429 k_RegisterIndex, /// A register index in one or more RegKind. 430 k_Token, /// A simple token 431 k_RegList /// A physical register list 432 } Kind; 433 434public: 435 MipsOperand(KindTy K, MipsAsmParser &Parser) 436 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 437 438private: 439 /// For diagnostics, and checking the assembler temporary 440 MipsAsmParser &AsmParser; 441 442 struct Token { 443 const char *Data; 444 unsigned Length; 445 }; 446 447 struct PhysRegOp { 448 unsigned Num; /// Register Number 449 }; 450 451 struct RegIdxOp { 452 unsigned Index; /// Index into the register class 453 RegKind Kind; /// Bitfield of the kinds it could possibly be 454 const MCRegisterInfo *RegInfo; 455 }; 456 457 struct ImmOp { 458 const MCExpr *Val; 459 }; 460 461 struct MemOp { 462 MipsOperand *Base; 463 const MCExpr *Off; 464 }; 465 466 struct RegListOp { 467 SmallVector<unsigned, 10> *List; 468 }; 469 470 union { 471 struct Token Tok; 472 struct PhysRegOp PhysReg; 473 struct RegIdxOp RegIdx; 474 struct ImmOp Imm; 475 struct MemOp Mem; 476 struct RegListOp RegList; 477 }; 478 479 SMLoc StartLoc, EndLoc; 480 481 /// Internal constructor for register kinds 482 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind, 483 const MCRegisterInfo *RegInfo, 484 SMLoc S, SMLoc E, 485 MipsAsmParser &Parser) { 486 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser); 487 Op->RegIdx.Index = Index; 488 Op->RegIdx.RegInfo = RegInfo; 489 Op->RegIdx.Kind = RegKind; 490 Op->StartLoc = S; 491 Op->EndLoc = E; 492 return Op; 493 } 494 495public: 496 /// Coerce the register to GPR32 and return the real register for the current 497 /// target. 498 unsigned getGPR32Reg() const { 499 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 500 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc); 501 unsigned ClassID = Mips::GPR32RegClassID; 502 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 503 } 504 505 /// Coerce the register to GPR32 and return the real register for the current 506 /// target. 507 unsigned getGPRMM16Reg() const { 508 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 509 unsigned ClassID = Mips::GPR32RegClassID; 510 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 511 } 512 513 /// Coerce the register to GPR64 and return the real register for the current 514 /// target. 515 unsigned getGPR64Reg() const { 516 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 517 unsigned ClassID = Mips::GPR64RegClassID; 518 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 519 } 520 521private: 522 /// Coerce the register to AFGR64 and return the real register for the current 523 /// target. 524 unsigned getAFGR64Reg() const { 525 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 526 if (RegIdx.Index % 2 != 0) 527 AsmParser.Warning(StartLoc, "Float register should be even."); 528 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 529 .getRegister(RegIdx.Index / 2); 530 } 531 532 /// Coerce the register to FGR64 and return the real register for the current 533 /// target. 534 unsigned getFGR64Reg() const { 535 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 536 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 537 .getRegister(RegIdx.Index); 538 } 539 540 /// Coerce the register to FGR32 and return the real register for the current 541 /// target. 542 unsigned getFGR32Reg() const { 543 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 544 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 545 .getRegister(RegIdx.Index); 546 } 547 548 /// Coerce the register to FGRH32 and return the real register for the current 549 /// target. 550 unsigned getFGRH32Reg() const { 551 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 552 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 553 .getRegister(RegIdx.Index); 554 } 555 556 /// Coerce the register to FCC and return the real register for the current 557 /// target. 558 unsigned getFCCReg() const { 559 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 560 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 561 .getRegister(RegIdx.Index); 562 } 563 564 /// Coerce the register to MSA128 and return the real register for the current 565 /// target. 566 unsigned getMSA128Reg() const { 567 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 568 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 569 // identical 570 unsigned ClassID = Mips::MSA128BRegClassID; 571 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 572 } 573 574 /// Coerce the register to MSACtrl and return the real register for the 575 /// current target. 576 unsigned getMSACtrlReg() const { 577 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 578 unsigned ClassID = Mips::MSACtrlRegClassID; 579 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 580 } 581 582 /// Coerce the register to COP2 and return the real register for the 583 /// current target. 584 unsigned getCOP2Reg() const { 585 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 586 unsigned ClassID = Mips::COP2RegClassID; 587 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 588 } 589 590 /// Coerce the register to COP3 and return the real register for the 591 /// current target. 592 unsigned getCOP3Reg() const { 593 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); 594 unsigned ClassID = Mips::COP3RegClassID; 595 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 596 } 597 598 /// Coerce the register to ACC64DSP and return the real register for the 599 /// current target. 600 unsigned getACC64DSPReg() const { 601 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 602 unsigned ClassID = Mips::ACC64DSPRegClassID; 603 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 604 } 605 606 /// Coerce the register to HI32DSP and return the real register for the 607 /// current target. 608 unsigned getHI32DSPReg() const { 609 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 610 unsigned ClassID = Mips::HI32DSPRegClassID; 611 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 612 } 613 614 /// Coerce the register to LO32DSP and return the real register for the 615 /// current target. 616 unsigned getLO32DSPReg() const { 617 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 618 unsigned ClassID = Mips::LO32DSPRegClassID; 619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 620 } 621 622 /// Coerce the register to CCR and return the real register for the 623 /// current target. 624 unsigned getCCRReg() const { 625 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 626 unsigned ClassID = Mips::CCRRegClassID; 627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 628 } 629 630 /// Coerce the register to HWRegs and return the real register for the 631 /// current target. 632 unsigned getHWRegsReg() const { 633 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 634 unsigned ClassID = Mips::HWRegsRegClassID; 635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 636 } 637 638public: 639 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 640 // Add as immediate when possible. Null MCExpr = 0. 641 if (!Expr) 642 Inst.addOperand(MCOperand::CreateImm(0)); 643 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 644 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 645 else 646 Inst.addOperand(MCOperand::CreateExpr(Expr)); 647 } 648 649 void addRegOperands(MCInst &Inst, unsigned N) const { 650 llvm_unreachable("Use a custom parser instead"); 651 } 652 653 /// Render the operand to an MCInst as a GPR32 654 /// Asserts if the wrong number of operands are requested, or the operand 655 /// is not a k_RegisterIndex compatible with RegKind_GPR 656 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 657 assert(N == 1 && "Invalid number of operands!"); 658 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); 659 } 660 661 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const { 662 assert(N == 1 && "Invalid number of operands!"); 663 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg())); 664 } 665 666 /// Render the operand to an MCInst as a GPR64 667 /// Asserts if the wrong number of operands are requested, or the operand 668 /// is not a k_RegisterIndex compatible with RegKind_GPR 669 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 670 assert(N == 1 && "Invalid number of operands!"); 671 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); 672 } 673 674 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 675 assert(N == 1 && "Invalid number of operands!"); 676 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); 677 } 678 679 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 680 assert(N == 1 && "Invalid number of operands!"); 681 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); 682 } 683 684 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 685 assert(N == 1 && "Invalid number of operands!"); 686 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); 687 // FIXME: We ought to do this for -integrated-as without -via-file-asm too. 688 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1) 689 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU " 690 "registers"); 691 } 692 693 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 694 assert(N == 1 && "Invalid number of operands!"); 695 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); 696 } 697 698 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 699 assert(N == 1 && "Invalid number of operands!"); 700 Inst.addOperand(MCOperand::CreateReg(getFCCReg())); 701 } 702 703 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 704 assert(N == 1 && "Invalid number of operands!"); 705 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); 706 } 707 708 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 709 assert(N == 1 && "Invalid number of operands!"); 710 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); 711 } 712 713 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 714 assert(N == 1 && "Invalid number of operands!"); 715 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); 716 } 717 718 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { 719 assert(N == 1 && "Invalid number of operands!"); 720 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg())); 721 } 722 723 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 724 assert(N == 1 && "Invalid number of operands!"); 725 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); 726 } 727 728 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 729 assert(N == 1 && "Invalid number of operands!"); 730 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); 731 } 732 733 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 734 assert(N == 1 && "Invalid number of operands!"); 735 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); 736 } 737 738 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 739 assert(N == 1 && "Invalid number of operands!"); 740 Inst.addOperand(MCOperand::CreateReg(getCCRReg())); 741 } 742 743 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 744 assert(N == 1 && "Invalid number of operands!"); 745 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); 746 } 747 748 void addImmOperands(MCInst &Inst, unsigned N) const { 749 assert(N == 1 && "Invalid number of operands!"); 750 const MCExpr *Expr = getImm(); 751 addExpr(Inst, Expr); 752 } 753 754 void addMemOperands(MCInst &Inst, unsigned N) const { 755 assert(N == 2 && "Invalid number of operands!"); 756 757 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); 758 759 const MCExpr *Expr = getMemOff(); 760 addExpr(Inst, Expr); 761 } 762 763 void addRegListOperands(MCInst &Inst, unsigned N) const { 764 assert(N == 1 && "Invalid number of operands!"); 765 766 for (auto RegNo : getRegList()) 767 Inst.addOperand(MCOperand::CreateReg(RegNo)); 768 } 769 770 bool isReg() const override { 771 // As a special case until we sort out the definition of div/divu, pretend 772 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 773 if (isGPRAsmReg() && RegIdx.Index == 0) 774 return true; 775 776 return Kind == k_PhysRegister; 777 } 778 bool isRegIdx() const { return Kind == k_RegisterIndex; } 779 bool isImm() const override { return Kind == k_Immediate; } 780 bool isConstantImm() const { 781 return isImm() && dyn_cast<MCConstantExpr>(getImm()); 782 } 783 bool isToken() const override { 784 // Note: It's not possible to pretend that other operand kinds are tokens. 785 // The matcher emitter checks tokens first. 786 return Kind == k_Token; 787 } 788 bool isMem() const override { return Kind == k_Memory; } 789 bool isConstantMemOff() const { 790 return isMem() && dyn_cast<MCConstantExpr>(getMemOff()); 791 } 792 template <unsigned Bits> bool isMemWithSimmOffset() const { 793 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()); 794 } 795 bool isInvNum() const { return Kind == k_Immediate; } 796 bool isLSAImm() const { 797 if (!isConstantImm()) 798 return false; 799 int64_t Val = getConstantImm(); 800 return 1 <= Val && Val <= 4; 801 } 802 bool isRegList() const { return Kind == k_RegList; } 803 804 StringRef getToken() const { 805 assert(Kind == k_Token && "Invalid access!"); 806 return StringRef(Tok.Data, Tok.Length); 807 } 808 809 unsigned getReg() const override { 810 // As a special case until we sort out the definition of div/divu, pretend 811 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 812 if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 813 RegIdx.Kind & RegKind_GPR) 814 return getGPR32Reg(); // FIXME: GPR64 too 815 816 assert(Kind == k_PhysRegister && "Invalid access!"); 817 return PhysReg.Num; 818 } 819 820 const MCExpr *getImm() const { 821 assert((Kind == k_Immediate) && "Invalid access!"); 822 return Imm.Val; 823 } 824 825 int64_t getConstantImm() const { 826 const MCExpr *Val = getImm(); 827 return static_cast<const MCConstantExpr *>(Val)->getValue(); 828 } 829 830 MipsOperand *getMemBase() const { 831 assert((Kind == k_Memory) && "Invalid access!"); 832 return Mem.Base; 833 } 834 835 const MCExpr *getMemOff() const { 836 assert((Kind == k_Memory) && "Invalid access!"); 837 return Mem.Off; 838 } 839 840 int64_t getConstantMemOff() const { 841 return static_cast<const MCConstantExpr *>(getMemOff())->getValue(); 842 } 843 844 const SmallVectorImpl<unsigned> &getRegList() const { 845 assert((Kind == k_RegList) && "Invalid access!"); 846 return *(RegList.List); 847 } 848 849 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, 850 MipsAsmParser &Parser) { 851 auto Op = make_unique<MipsOperand>(k_Token, Parser); 852 Op->Tok.Data = Str.data(); 853 Op->Tok.Length = Str.size(); 854 Op->StartLoc = S; 855 Op->EndLoc = S; 856 return Op; 857 } 858 859 /// Create a numeric register (e.g. $1). The exact register remains 860 /// unresolved until an instruction successfully matches 861 static std::unique_ptr<MipsOperand> 862 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 863 SMLoc E, MipsAsmParser &Parser) { 864 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n"); 865 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 866 } 867 868 /// Create a register that is definitely a GPR. 869 /// This is typically only used for named registers such as $gp. 870 static std::unique_ptr<MipsOperand> 871 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 872 MipsAsmParser &Parser) { 873 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 874 } 875 876 /// Create a register that is definitely a FGR. 877 /// This is typically only used for named registers such as $f0. 878 static std::unique_ptr<MipsOperand> 879 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 880 MipsAsmParser &Parser) { 881 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 882 } 883 884 /// Create a register that is definitely a HWReg. 885 /// This is typically only used for named registers such as $hwr_cpunum. 886 static std::unique_ptr<MipsOperand> 887 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo, 888 SMLoc S, SMLoc E, MipsAsmParser &Parser) { 889 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser); 890 } 891 892 /// Create a register that is definitely an FCC. 893 /// This is typically only used for named registers such as $fcc0. 894 static std::unique_ptr<MipsOperand> 895 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 896 MipsAsmParser &Parser) { 897 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 898 } 899 900 /// Create a register that is definitely an ACC. 901 /// This is typically only used for named registers such as $ac0. 902 static std::unique_ptr<MipsOperand> 903 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 904 MipsAsmParser &Parser) { 905 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 906 } 907 908 /// Create a register that is definitely an MSA128. 909 /// This is typically only used for named registers such as $w0. 910 static std::unique_ptr<MipsOperand> 911 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 912 SMLoc E, MipsAsmParser &Parser) { 913 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 914 } 915 916 /// Create a register that is definitely an MSACtrl. 917 /// This is typically only used for named registers such as $msaaccess. 918 static std::unique_ptr<MipsOperand> 919 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 920 SMLoc E, MipsAsmParser &Parser) { 921 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 922 } 923 924 static std::unique_ptr<MipsOperand> 925 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { 926 auto Op = make_unique<MipsOperand>(k_Immediate, Parser); 927 Op->Imm.Val = Val; 928 Op->StartLoc = S; 929 Op->EndLoc = E; 930 return Op; 931 } 932 933 static std::unique_ptr<MipsOperand> 934 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S, 935 SMLoc E, MipsAsmParser &Parser) { 936 auto Op = make_unique<MipsOperand>(k_Memory, Parser); 937 Op->Mem.Base = Base.release(); 938 Op->Mem.Off = Off; 939 Op->StartLoc = S; 940 Op->EndLoc = E; 941 return Op; 942 } 943 944 static std::unique_ptr<MipsOperand> 945 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc, 946 MipsAsmParser &Parser) { 947 assert (Regs.size() > 0 && "Empty list not allowed"); 948 949 auto Op = make_unique<MipsOperand>(k_RegList, Parser); 950 Op->RegList.List = new SmallVector<unsigned, 10>(); 951 for (auto Reg : Regs) 952 Op->RegList.List->push_back(Reg); 953 Op->StartLoc = StartLoc; 954 Op->EndLoc = EndLoc; 955 return Op; 956 } 957 958 bool isGPRAsmReg() const { 959 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 960 } 961 bool isMM16AsmReg() const { 962 if (!(isRegIdx() && RegIdx.Kind)) 963 return false; 964 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7) 965 || RegIdx.Index == 16 || RegIdx.Index == 17); 966 } 967 bool isFGRAsmReg() const { 968 // AFGR64 is $0-$15 but we handle this in getAFGR64() 969 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 970 } 971 bool isHWRegsAsmReg() const { 972 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 973 } 974 bool isCCRAsmReg() const { 975 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 976 } 977 bool isFCCAsmReg() const { 978 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) 979 return false; 980 if (!AsmParser.hasEightFccRegisters()) 981 return RegIdx.Index == 0; 982 return RegIdx.Index <= 7; 983 } 984 bool isACCAsmReg() const { 985 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 986 } 987 bool isCOP2AsmReg() const { 988 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 989 } 990 bool isCOP3AsmReg() const { 991 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; 992 } 993 bool isMSA128AsmReg() const { 994 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 995 } 996 bool isMSACtrlAsmReg() const { 997 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 998 } 999 1000 /// getStartLoc - Get the location of the first token of this operand. 1001 SMLoc getStartLoc() const override { return StartLoc; } 1002 /// getEndLoc - Get the location of the last token of this operand. 1003 SMLoc getEndLoc() const override { return EndLoc; } 1004 1005 virtual ~MipsOperand() { 1006 switch (Kind) { 1007 case k_Immediate: 1008 break; 1009 case k_Memory: 1010 delete Mem.Base; 1011 break; 1012 case k_RegList: 1013 delete RegList.List; 1014 case k_PhysRegister: 1015 case k_RegisterIndex: 1016 case k_Token: 1017 break; 1018 } 1019 } 1020 1021 void print(raw_ostream &OS) const override { 1022 switch (Kind) { 1023 case k_Immediate: 1024 OS << "Imm<"; 1025 Imm.Val->print(OS); 1026 OS << ">"; 1027 break; 1028 case k_Memory: 1029 OS << "Mem<"; 1030 Mem.Base->print(OS); 1031 OS << ", "; 1032 Mem.Off->print(OS); 1033 OS << ">"; 1034 break; 1035 case k_PhysRegister: 1036 OS << "PhysReg<" << PhysReg.Num << ">"; 1037 break; 1038 case k_RegisterIndex: 1039 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 1040 break; 1041 case k_Token: 1042 OS << Tok.Data; 1043 break; 1044 case k_RegList: 1045 OS << "RegList< "; 1046 for (auto Reg : (*RegList.List)) 1047 OS << Reg << " "; 1048 OS << ">"; 1049 break; 1050 } 1051 } 1052}; // class MipsOperand 1053} // namespace 1054 1055namespace llvm { 1056extern const MCInstrDesc MipsInsts[]; 1057} 1058static const MCInstrDesc &getInstDesc(unsigned Opcode) { 1059 return MipsInsts[Opcode]; 1060} 1061 1062static bool hasShortDelaySlot(unsigned Opcode) { 1063 switch (Opcode) { 1064 case Mips::JALS_MM: 1065 case Mips::JALRS_MM: 1066 case Mips::JALRS16_MM: 1067 case Mips::BGEZALS_MM: 1068 case Mips::BLTZALS_MM: 1069 return true; 1070 default: 1071 return false; 1072 } 1073} 1074 1075bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 1076 SmallVectorImpl<MCInst> &Instructions) { 1077 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 1078 1079 Inst.setLoc(IDLoc); 1080 1081 if (MCID.isBranch() || MCID.isCall()) { 1082 const unsigned Opcode = Inst.getOpcode(); 1083 MCOperand Offset; 1084 1085 switch (Opcode) { 1086 default: 1087 break; 1088 case Mips::BEQ: 1089 case Mips::BNE: 1090 case Mips::BEQ_MM: 1091 case Mips::BNE_MM: 1092 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 1093 Offset = Inst.getOperand(2); 1094 if (!Offset.isImm()) 1095 break; // We'll deal with this situation later on when applying fixups. 1096 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 1097 return Error(IDLoc, "branch target out of range"); 1098 if (OffsetToAlignment(Offset.getImm(), 1099 1LL << (inMicroMipsMode() ? 1 : 2))) 1100 return Error(IDLoc, "branch to misaligned address"); 1101 break; 1102 case Mips::BGEZ: 1103 case Mips::BGTZ: 1104 case Mips::BLEZ: 1105 case Mips::BLTZ: 1106 case Mips::BGEZAL: 1107 case Mips::BLTZAL: 1108 case Mips::BC1F: 1109 case Mips::BC1T: 1110 case Mips::BGEZ_MM: 1111 case Mips::BGTZ_MM: 1112 case Mips::BLEZ_MM: 1113 case Mips::BLTZ_MM: 1114 case Mips::BGEZAL_MM: 1115 case Mips::BLTZAL_MM: 1116 case Mips::BC1F_MM: 1117 case Mips::BC1T_MM: 1118 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 1119 Offset = Inst.getOperand(1); 1120 if (!Offset.isImm()) 1121 break; // We'll deal with this situation later on when applying fixups. 1122 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 1123 return Error(IDLoc, "branch target out of range"); 1124 if (OffsetToAlignment(Offset.getImm(), 1125 1LL << (inMicroMipsMode() ? 1 : 2))) 1126 return Error(IDLoc, "branch to misaligned address"); 1127 break; 1128 } 1129 } 1130 1131 // SSNOP is deprecated on MIPS32r6/MIPS64r6 1132 // We still accept it but it is a normal nop. 1133 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) { 1134 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6"; 1135 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a " 1136 "nop instruction"); 1137 } 1138 1139 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) { 1140 // If this instruction has a delay slot and .set reorder is active, 1141 // emit a NOP after it. 1142 Instructions.push_back(Inst); 1143 MCInst NopInst; 1144 if (hasShortDelaySlot(Inst.getOpcode())) { 1145 NopInst.setOpcode(Mips::MOVE16_MM); 1146 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1147 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1148 } else { 1149 NopInst.setOpcode(Mips::SLL); 1150 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1151 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1152 NopInst.addOperand(MCOperand::CreateImm(0)); 1153 } 1154 Instructions.push_back(NopInst); 1155 return false; 1156 } 1157 1158 if (MCID.mayLoad() || MCID.mayStore()) { 1159 // Check the offset of memory operand, if it is a symbol 1160 // reference or immediate we may have to expand instructions. 1161 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 1162 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 1163 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 1164 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 1165 MCOperand &Op = Inst.getOperand(i); 1166 if (Op.isImm()) { 1167 int MemOffset = Op.getImm(); 1168 if (MemOffset < -32768 || MemOffset > 32767) { 1169 // Offset can't exceed 16bit value. 1170 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 1171 return false; 1172 } 1173 } else if (Op.isExpr()) { 1174 const MCExpr *Expr = Op.getExpr(); 1175 if (Expr->getKind() == MCExpr::SymbolRef) { 1176 const MCSymbolRefExpr *SR = 1177 static_cast<const MCSymbolRefExpr *>(Expr); 1178 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 1179 // Expand symbol. 1180 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 1181 return false; 1182 } 1183 } else if (!isEvaluated(Expr)) { 1184 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 1185 return false; 1186 } 1187 } 1188 } 1189 } // for 1190 } // if load/store 1191 1192 // TODO: Handle this with the AsmOperandClass.PredicateMethod. 1193 if (inMicroMipsMode()) { 1194 MCOperand Opnd; 1195 int Imm; 1196 1197 switch (Inst.getOpcode()) { 1198 default: 1199 break; 1200 case Mips::ADDIUS5_MM: 1201 Opnd = Inst.getOperand(2); 1202 if (!Opnd.isImm()) 1203 return Error(IDLoc, "expected immediate operand kind"); 1204 Imm = Opnd.getImm(); 1205 if (Imm < -8 || Imm > 7) 1206 return Error(IDLoc, "immediate operand value out of range"); 1207 break; 1208 case Mips::ADDIUSP_MM: 1209 Opnd = Inst.getOperand(0); 1210 if (!Opnd.isImm()) 1211 return Error(IDLoc, "expected immediate operand kind"); 1212 Imm = Opnd.getImm(); 1213 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) || 1214 Imm % 4 != 0) 1215 return Error(IDLoc, "immediate operand value out of range"); 1216 break; 1217 case Mips::SLL16_MM: 1218 case Mips::SRL16_MM: 1219 Opnd = Inst.getOperand(2); 1220 if (!Opnd.isImm()) 1221 return Error(IDLoc, "expected immediate operand kind"); 1222 Imm = Opnd.getImm(); 1223 if (Imm < 1 || Imm > 8) 1224 return Error(IDLoc, "immediate operand value out of range"); 1225 break; 1226 case Mips::LI16_MM: 1227 Opnd = Inst.getOperand(1); 1228 if (!Opnd.isImm()) 1229 return Error(IDLoc, "expected immediate operand kind"); 1230 Imm = Opnd.getImm(); 1231 if (Imm < -1 || Imm > 126) 1232 return Error(IDLoc, "immediate operand value out of range"); 1233 break; 1234 case Mips::ADDIUR2_MM: 1235 Opnd = Inst.getOperand(2); 1236 if (!Opnd.isImm()) 1237 return Error(IDLoc, "expected immediate operand kind"); 1238 Imm = Opnd.getImm(); 1239 if (!(Imm == 1 || Imm == -1 || 1240 ((Imm % 4 == 0) && Imm < 28 && Imm > 0))) 1241 return Error(IDLoc, "immediate operand value out of range"); 1242 break; 1243 case Mips::ADDIUR1SP_MM: 1244 Opnd = Inst.getOperand(1); 1245 if (!Opnd.isImm()) 1246 return Error(IDLoc, "expected immediate operand kind"); 1247 Imm = Opnd.getImm(); 1248 if (OffsetToAlignment(Imm, 4LL)) 1249 return Error(IDLoc, "misaligned immediate operand value"); 1250 if (Imm < 0 || Imm > 255) 1251 return Error(IDLoc, "immediate operand value out of range"); 1252 break; 1253 case Mips::ANDI16_MM: 1254 Opnd = Inst.getOperand(2); 1255 if (!Opnd.isImm()) 1256 return Error(IDLoc, "expected immediate operand kind"); 1257 Imm = Opnd.getImm(); 1258 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 || 1259 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 || 1260 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535)) 1261 return Error(IDLoc, "immediate operand value out of range"); 1262 break; 1263 } 1264 } 1265 1266 if (needsExpansion(Inst)) 1267 return expandInstruction(Inst, IDLoc, Instructions); 1268 else 1269 Instructions.push_back(Inst); 1270 1271 return false; 1272} 1273 1274bool MipsAsmParser::needsExpansion(MCInst &Inst) { 1275 1276 switch (Inst.getOpcode()) { 1277 case Mips::LoadImm32Reg: 1278 case Mips::LoadAddr32Imm: 1279 case Mips::LoadAddr32Reg: 1280 case Mips::LoadImm64Reg: 1281 return true; 1282 default: 1283 return false; 1284 } 1285} 1286 1287bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 1288 SmallVectorImpl<MCInst> &Instructions) { 1289 switch (Inst.getOpcode()) { 1290 default: 1291 assert(0 && "unimplemented expansion"); 1292 return true; 1293 case Mips::LoadImm32Reg: 1294 return expandLoadImm(Inst, IDLoc, Instructions); 1295 case Mips::LoadImm64Reg: 1296 if (!isGP64bit()) { 1297 Error(IDLoc, "instruction requires a 64-bit architecture"); 1298 return true; 1299 } 1300 return expandLoadImm(Inst, IDLoc, Instructions); 1301 case Mips::LoadAddr32Imm: 1302 return expandLoadAddressImm(Inst, IDLoc, Instructions); 1303 case Mips::LoadAddr32Reg: 1304 return expandLoadAddressReg(Inst, IDLoc, Instructions); 1305 } 1306} 1307 1308namespace { 1309template <bool PerformShift> 1310void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc, 1311 SmallVectorImpl<MCInst> &Instructions) { 1312 MCInst tmpInst; 1313 if (PerformShift) { 1314 tmpInst.setOpcode(Mips::DSLL); 1315 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1316 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1317 tmpInst.addOperand(MCOperand::CreateImm(16)); 1318 tmpInst.setLoc(IDLoc); 1319 Instructions.push_back(tmpInst); 1320 tmpInst.clear(); 1321 } 1322 tmpInst.setOpcode(Mips::ORi); 1323 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1324 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1325 tmpInst.addOperand(Operand); 1326 tmpInst.setLoc(IDLoc); 1327 Instructions.push_back(tmpInst); 1328} 1329 1330template <int Shift, bool PerformShift> 1331void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc, 1332 SmallVectorImpl<MCInst> &Instructions) { 1333 createShiftOr<PerformShift>( 1334 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo, 1335 IDLoc, Instructions); 1336} 1337} 1338 1339bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 1340 SmallVectorImpl<MCInst> &Instructions) { 1341 MCInst tmpInst; 1342 const MCOperand &ImmOp = Inst.getOperand(1); 1343 assert(ImmOp.isImm() && "expected immediate operand kind"); 1344 const MCOperand &RegOp = Inst.getOperand(0); 1345 assert(RegOp.isReg() && "expected register operand kind"); 1346 1347 int64_t ImmValue = ImmOp.getImm(); 1348 tmpInst.setLoc(IDLoc); 1349 // FIXME: gas has a special case for values that are 000...1111, which 1350 // becomes a li -1 and then a dsrl 1351 if (0 <= ImmValue && ImmValue <= 65535) { 1352 // For 0 <= j <= 65535. 1353 // li d,j => ori d,$zero,j 1354 tmpInst.setOpcode(Mips::ORi); 1355 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1356 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1357 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1358 Instructions.push_back(tmpInst); 1359 } else if (ImmValue < 0 && ImmValue >= -32768) { 1360 // For -32768 <= j < 0. 1361 // li d,j => addiu d,$zero,j 1362 tmpInst.setOpcode(Mips::ADDiu); 1363 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1364 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1365 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1366 Instructions.push_back(tmpInst); 1367 } else if ((ImmValue & 0xffffffff) == ImmValue) { 1368 // For any value of j that is representable as a 32-bit integer, create 1369 // a sequence of: 1370 // li d,j => lui d,hi16(j) 1371 // ori d,d,lo16(j) 1372 tmpInst.setOpcode(Mips::LUi); 1373 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1374 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1375 Instructions.push_back(tmpInst); 1376 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1377 } else if ((ImmValue & (0xffffLL << 48)) == 0) { 1378 if (!isGP64bit()) { 1379 Error(IDLoc, "instruction requires a 64-bit architecture"); 1380 return true; 1381 } 1382 1383 // <------- lo32 ------> 1384 // <------- hi32 ------> 1385 // <- hi16 -> <- lo16 -> 1386 // _________________________________ 1387 // | | | | 1388 // | 16-bytes | 16-bytes | 16-bytes | 1389 // |__________|__________|__________| 1390 // 1391 // For any value of j that is representable as a 48-bit integer, create 1392 // a sequence of: 1393 // li d,j => lui d,hi16(j) 1394 // ori d,d,hi16(lo32(j)) 1395 // dsll d,d,16 1396 // ori d,d,lo16(lo32(j)) 1397 tmpInst.setOpcode(Mips::LUi); 1398 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1399 tmpInst.addOperand( 1400 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32)); 1401 Instructions.push_back(tmpInst); 1402 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1403 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1404 } else { 1405 if (!isGP64bit()) { 1406 Error(IDLoc, "instruction requires a 64-bit architecture"); 1407 return true; 1408 } 1409 1410 // <------- hi32 ------> <------- lo32 ------> 1411 // <- hi16 -> <- lo16 -> 1412 // ___________________________________________ 1413 // | | | | | 1414 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes | 1415 // |__________|__________|__________|__________| 1416 // 1417 // For any value of j that isn't representable as a 48-bit integer. 1418 // li d,j => lui d,hi16(j) 1419 // ori d,d,lo16(hi32(j)) 1420 // dsll d,d,16 1421 // ori d,d,hi16(lo32(j)) 1422 // dsll d,d,16 1423 // ori d,d,lo16(lo32(j)) 1424 tmpInst.setOpcode(Mips::LUi); 1425 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1426 tmpInst.addOperand( 1427 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48)); 1428 Instructions.push_back(tmpInst); 1429 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1430 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1431 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1432 } 1433 return false; 1434} 1435 1436bool 1437MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1438 SmallVectorImpl<MCInst> &Instructions) { 1439 MCInst tmpInst; 1440 const MCOperand &ImmOp = Inst.getOperand(2); 1441 assert((ImmOp.isImm() || ImmOp.isExpr()) && 1442 "expected immediate operand kind"); 1443 if (!ImmOp.isImm()) { 1444 expandLoadAddressSym(Inst, IDLoc, Instructions); 1445 return false; 1446 } 1447 const MCOperand &SrcRegOp = Inst.getOperand(1); 1448 assert(SrcRegOp.isReg() && "expected register operand kind"); 1449 const MCOperand &DstRegOp = Inst.getOperand(0); 1450 assert(DstRegOp.isReg() && "expected register operand kind"); 1451 int ImmValue = ImmOp.getImm(); 1452 if (-32768 <= ImmValue && ImmValue <= 65535) { 1453 // For -32768 <= j <= 65535. 1454 // la d,j(s) => addiu d,s,j 1455 tmpInst.setOpcode(Mips::ADDiu); 1456 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1457 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1458 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1459 Instructions.push_back(tmpInst); 1460 } else { 1461 // For any other value of j that is representable as a 32-bit integer. 1462 // la d,j(s) => lui d,hi16(j) 1463 // ori d,d,lo16(j) 1464 // addu d,d,s 1465 tmpInst.setOpcode(Mips::LUi); 1466 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1467 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1468 Instructions.push_back(tmpInst); 1469 tmpInst.clear(); 1470 tmpInst.setOpcode(Mips::ORi); 1471 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1472 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1473 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1474 Instructions.push_back(tmpInst); 1475 tmpInst.clear(); 1476 tmpInst.setOpcode(Mips::ADDu); 1477 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1478 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1479 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1480 Instructions.push_back(tmpInst); 1481 } 1482 return false; 1483} 1484 1485bool 1486MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1487 SmallVectorImpl<MCInst> &Instructions) { 1488 MCInst tmpInst; 1489 const MCOperand &ImmOp = Inst.getOperand(1); 1490 assert((ImmOp.isImm() || ImmOp.isExpr()) && 1491 "expected immediate operand kind"); 1492 if (!ImmOp.isImm()) { 1493 expandLoadAddressSym(Inst, IDLoc, Instructions); 1494 return false; 1495 } 1496 const MCOperand &RegOp = Inst.getOperand(0); 1497 assert(RegOp.isReg() && "expected register operand kind"); 1498 int ImmValue = ImmOp.getImm(); 1499 if (-32768 <= ImmValue && ImmValue <= 65535) { 1500 // For -32768 <= j <= 65535. 1501 // la d,j => addiu d,$zero,j 1502 tmpInst.setOpcode(Mips::ADDiu); 1503 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1504 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1505 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1506 Instructions.push_back(tmpInst); 1507 } else { 1508 // For any other value of j that is representable as a 32-bit integer. 1509 // la d,j => lui d,hi16(j) 1510 // ori d,d,lo16(j) 1511 tmpInst.setOpcode(Mips::LUi); 1512 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1513 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1514 Instructions.push_back(tmpInst); 1515 tmpInst.clear(); 1516 tmpInst.setOpcode(Mips::ORi); 1517 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1518 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1519 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1520 Instructions.push_back(tmpInst); 1521 } 1522 return false; 1523} 1524 1525void 1526MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc, 1527 SmallVectorImpl<MCInst> &Instructions) { 1528 // FIXME: If we do have a valid at register to use, we should generate a 1529 // slightly shorter sequence here. 1530 MCInst tmpInst; 1531 int ExprOperandNo = 1; 1532 // Sometimes the assembly parser will get the immediate expression as 1533 // a $zero + an immediate. 1534 if (Inst.getNumOperands() == 3) { 1535 assert(Inst.getOperand(1).getReg() == 1536 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO)); 1537 ExprOperandNo = 2; 1538 } 1539 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo); 1540 assert(SymOp.isExpr() && "expected symbol operand kind"); 1541 const MCOperand &RegOp = Inst.getOperand(0); 1542 unsigned RegNo = RegOp.getReg(); 1543 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr()); 1544 const MCSymbolRefExpr *HiExpr = 1545 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1546 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext()); 1547 const MCSymbolRefExpr *LoExpr = 1548 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1549 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext()); 1550 if (isGP64bit()) { 1551 // If it's a 64-bit architecture, expand to: 1552 // la d,sym => lui d,highest(sym) 1553 // ori d,d,higher(sym) 1554 // dsll d,d,16 1555 // ori d,d,hi16(sym) 1556 // dsll d,d,16 1557 // ori d,d,lo16(sym) 1558 const MCSymbolRefExpr *HighestExpr = 1559 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1560 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext()); 1561 const MCSymbolRefExpr *HigherExpr = 1562 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1563 MCSymbolRefExpr::VK_Mips_HIGHER, getContext()); 1564 1565 tmpInst.setOpcode(Mips::LUi); 1566 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1567 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr)); 1568 Instructions.push_back(tmpInst); 1569 1570 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(), 1571 Instructions); 1572 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(), 1573 Instructions); 1574 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(), 1575 Instructions); 1576 } else { 1577 // Otherwise, expand to: 1578 // la d,sym => lui d,hi16(sym) 1579 // ori d,d,lo16(sym) 1580 tmpInst.setOpcode(Mips::LUi); 1581 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1582 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1583 Instructions.push_back(tmpInst); 1584 1585 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(), 1586 Instructions); 1587 } 1588} 1589 1590void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 1591 SmallVectorImpl<MCInst> &Instructions, 1592 bool isLoad, bool isImmOpnd) { 1593 const MCSymbolRefExpr *SR; 1594 MCInst TempInst; 1595 unsigned ImmOffset, HiOffset, LoOffset; 1596 const MCExpr *ExprOffset; 1597 unsigned TmpRegNum; 1598 // 1st operand is either the source or destination register. 1599 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 1600 unsigned RegOpNum = Inst.getOperand(0).getReg(); 1601 // 2nd operand is the base register. 1602 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 1603 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 1604 // 3rd operand is either an immediate or expression. 1605 if (isImmOpnd) { 1606 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 1607 ImmOffset = Inst.getOperand(2).getImm(); 1608 LoOffset = ImmOffset & 0x0000ffff; 1609 HiOffset = (ImmOffset & 0xffff0000) >> 16; 1610 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 1611 if (LoOffset & 0x8000) 1612 HiOffset++; 1613 } else 1614 ExprOffset = Inst.getOperand(2).getExpr(); 1615 // All instructions will have the same location. 1616 TempInst.setLoc(IDLoc); 1617 // These are some of the types of expansions we perform here: 1618 // 1) lw $8, sym => lui $8, %hi(sym) 1619 // lw $8, %lo(sym)($8) 1620 // 2) lw $8, offset($9) => lui $8, %hi(offset) 1621 // add $8, $8, $9 1622 // lw $8, %lo(offset)($9) 1623 // 3) lw $8, offset($8) => lui $at, %hi(offset) 1624 // add $at, $at, $8 1625 // lw $8, %lo(offset)($at) 1626 // 4) sw $8, sym => lui $at, %hi(sym) 1627 // sw $8, %lo(sym)($at) 1628 // 5) sw $8, offset($8) => lui $at, %hi(offset) 1629 // add $at, $at, $8 1630 // sw $8, %lo(offset)($at) 1631 // 6) ldc1 $f0, sym => lui $at, %hi(sym) 1632 // ldc1 $f0, %lo(sym)($at) 1633 // 1634 // For load instructions we can use the destination register as a temporary 1635 // if base and dst are different (examples 1 and 2) and if the base register 1636 // is general purpose otherwise we must use $at (example 6) and error if it's 1637 // not available. For stores we must use $at (examples 4 and 5) because we 1638 // must not clobber the source register setting up the offset. 1639 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode()); 1640 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass; 1641 unsigned RegClassIDOp0 = 1642 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID(); 1643 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) || 1644 (RegClassIDOp0 == Mips::GPR64RegClassID); 1645 if (isLoad && IsGPR && (BaseRegNum != RegOpNum)) 1646 TmpRegNum = RegOpNum; 1647 else { 1648 int AT = getATReg(IDLoc); 1649 // At this point we need AT to perform the expansions and we exit if it is 1650 // not available. 1651 if (!AT) 1652 return; 1653 TmpRegNum = getReg( 1654 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT); 1655 } 1656 1657 TempInst.setOpcode(Mips::LUi); 1658 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1659 if (isImmOpnd) 1660 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 1661 else { 1662 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1663 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 1664 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 1665 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 1666 getContext()); 1667 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1668 } else { 1669 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 1670 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1671 } 1672 } 1673 // Add the instruction to the list. 1674 Instructions.push_back(TempInst); 1675 // Prepare TempInst for next instruction. 1676 TempInst.clear(); 1677 // Add temp register to base. 1678 TempInst.setOpcode(Mips::ADDu); 1679 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1680 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1681 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 1682 Instructions.push_back(TempInst); 1683 TempInst.clear(); 1684 // And finally, create original instruction with low part 1685 // of offset and new base. 1686 TempInst.setOpcode(Inst.getOpcode()); 1687 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 1688 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1689 if (isImmOpnd) 1690 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 1691 else { 1692 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1693 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 1694 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 1695 getContext()); 1696 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1697 } else { 1698 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 1699 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1700 } 1701 } 1702 Instructions.push_back(TempInst); 1703 TempInst.clear(); 1704} 1705 1706unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 1707 // As described by the Mips32r2 spec, the registers Rd and Rs for 1708 // jalr.hb must be different. 1709 unsigned Opcode = Inst.getOpcode(); 1710 1711 if (Opcode == Mips::JALR_HB && 1712 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())) 1713 return Match_RequiresDifferentSrcAndDst; 1714 1715 return Match_Success; 1716} 1717 1718bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1719 OperandVector &Operands, 1720 MCStreamer &Out, 1721 uint64_t &ErrorInfo, 1722 bool MatchingInlineAsm) { 1723 1724 MCInst Inst; 1725 SmallVector<MCInst, 8> Instructions; 1726 unsigned MatchResult = 1727 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 1728 1729 switch (MatchResult) { 1730 default: 1731 break; 1732 case Match_Success: { 1733 if (processInstruction(Inst, IDLoc, Instructions)) 1734 return true; 1735 for (unsigned i = 0; i < Instructions.size(); i++) 1736 Out.EmitInstruction(Instructions[i], STI); 1737 return false; 1738 } 1739 case Match_MissingFeature: 1740 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1741 return true; 1742 case Match_InvalidOperand: { 1743 SMLoc ErrorLoc = IDLoc; 1744 if (ErrorInfo != ~0ULL) { 1745 if (ErrorInfo >= Operands.size()) 1746 return Error(IDLoc, "too few operands for instruction"); 1747 1748 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc(); 1749 if (ErrorLoc == SMLoc()) 1750 ErrorLoc = IDLoc; 1751 } 1752 1753 return Error(ErrorLoc, "invalid operand for instruction"); 1754 } 1755 case Match_MnemonicFail: 1756 return Error(IDLoc, "invalid instruction"); 1757 case Match_RequiresDifferentSrcAndDst: 1758 return Error(IDLoc, "source and destination must be different"); 1759 } 1760 return true; 1761} 1762 1763void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { 1764 if ((RegIndex != 0) && 1765 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) { 1766 if (RegIndex == 1) 1767 Warning(Loc, "used $at without \".set noat\""); 1768 else 1769 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" + 1770 Twine(RegIndex) + "\""); 1771 } 1772} 1773 1774void 1775MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, 1776 SMRange Range, bool ShowColors) { 1777 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg, 1778 Range, SMFixIt(Range, FixMsg), 1779 ShowColors); 1780} 1781 1782int MipsAsmParser::matchCPURegisterName(StringRef Name) { 1783 int CC; 1784 1785 CC = StringSwitch<unsigned>(Name) 1786 .Case("zero", 0) 1787 .Case("at", 1) 1788 .Case("a0", 4) 1789 .Case("a1", 5) 1790 .Case("a2", 6) 1791 .Case("a3", 7) 1792 .Case("v0", 2) 1793 .Case("v1", 3) 1794 .Case("s0", 16) 1795 .Case("s1", 17) 1796 .Case("s2", 18) 1797 .Case("s3", 19) 1798 .Case("s4", 20) 1799 .Case("s5", 21) 1800 .Case("s6", 22) 1801 .Case("s7", 23) 1802 .Case("k0", 26) 1803 .Case("k1", 27) 1804 .Case("gp", 28) 1805 .Case("sp", 29) 1806 .Case("fp", 30) 1807 .Case("s8", 30) 1808 .Case("ra", 31) 1809 .Case("t0", 8) 1810 .Case("t1", 9) 1811 .Case("t2", 10) 1812 .Case("t3", 11) 1813 .Case("t4", 12) 1814 .Case("t5", 13) 1815 .Case("t6", 14) 1816 .Case("t7", 15) 1817 .Case("t8", 24) 1818 .Case("t9", 25) 1819 .Default(-1); 1820 1821 if (!(isABI_N32() || isABI_N64())) 1822 return CC; 1823 1824 if (12 <= CC && CC <= 15) { 1825 // Name is one of t4-t7 1826 AsmToken RegTok = getLexer().peekTok(); 1827 SMRange RegRange = RegTok.getLocRange(); 1828 1829 StringRef FixedName = StringSwitch<StringRef>(Name) 1830 .Case("t4", "t0") 1831 .Case("t5", "t1") 1832 .Case("t6", "t2") 1833 .Case("t7", "t3") 1834 .Default(""); 1835 assert(FixedName != "" && "Register name is not one of t4-t7."); 1836 1837 printWarningWithFixIt("register names $t4-$t7 are only available in O32.", 1838 "Did you mean $" + FixedName + "?", RegRange); 1839 } 1840 1841 // Although SGI documentation just cuts out t0-t3 for n32/n64, 1842 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 1843 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 1844 if (8 <= CC && CC <= 11) 1845 CC += 4; 1846 1847 if (CC == -1) 1848 CC = StringSwitch<unsigned>(Name) 1849 .Case("a4", 8) 1850 .Case("a5", 9) 1851 .Case("a6", 10) 1852 .Case("a7", 11) 1853 .Case("kt0", 26) 1854 .Case("kt1", 27) 1855 .Default(-1); 1856 1857 return CC; 1858} 1859 1860int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) { 1861 int CC; 1862 1863 CC = StringSwitch<unsigned>(Name) 1864 .Case("hwr_cpunum", 0) 1865 .Case("hwr_synci_step", 1) 1866 .Case("hwr_cc", 2) 1867 .Case("hwr_ccres", 3) 1868 .Case("hwr_ulr", 29) 1869 .Default(-1); 1870 1871 return CC; 1872} 1873 1874int MipsAsmParser::matchFPURegisterName(StringRef Name) { 1875 1876 if (Name[0] == 'f') { 1877 StringRef NumString = Name.substr(1); 1878 unsigned IntVal; 1879 if (NumString.getAsInteger(10, IntVal)) 1880 return -1; // This is not an integer. 1881 if (IntVal > 31) // Maximum index for fpu register. 1882 return -1; 1883 return IntVal; 1884 } 1885 return -1; 1886} 1887 1888int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 1889 1890 if (Name.startswith("fcc")) { 1891 StringRef NumString = Name.substr(3); 1892 unsigned IntVal; 1893 if (NumString.getAsInteger(10, IntVal)) 1894 return -1; // This is not an integer. 1895 if (IntVal > 7) // There are only 8 fcc registers. 1896 return -1; 1897 return IntVal; 1898 } 1899 return -1; 1900} 1901 1902int MipsAsmParser::matchACRegisterName(StringRef Name) { 1903 1904 if (Name.startswith("ac")) { 1905 StringRef NumString = Name.substr(2); 1906 unsigned IntVal; 1907 if (NumString.getAsInteger(10, IntVal)) 1908 return -1; // This is not an integer. 1909 if (IntVal > 3) // There are only 3 acc registers. 1910 return -1; 1911 return IntVal; 1912 } 1913 return -1; 1914} 1915 1916int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 1917 unsigned IntVal; 1918 1919 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 1920 return -1; 1921 1922 if (IntVal > 31) 1923 return -1; 1924 1925 return IntVal; 1926} 1927 1928int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 1929 int CC; 1930 1931 CC = StringSwitch<unsigned>(Name) 1932 .Case("msair", 0) 1933 .Case("msacsr", 1) 1934 .Case("msaaccess", 2) 1935 .Case("msasave", 3) 1936 .Case("msamodify", 4) 1937 .Case("msarequest", 5) 1938 .Case("msamap", 6) 1939 .Case("msaunmap", 7) 1940 .Default(-1); 1941 1942 return CC; 1943} 1944 1945bool MipsAssemblerOptions::setATReg(unsigned Reg) { 1946 if (Reg > 31) 1947 return false; 1948 1949 ATReg = Reg; 1950 return true; 1951} 1952 1953int MipsAsmParser::getATReg(SMLoc Loc) { 1954 int AT = AssemblerOptions.back()->getATRegNum(); 1955 if (AT == 0) 1956 reportParseError(Loc, 1957 "pseudo-instruction requires $at, which is not available"); 1958 return AT; 1959} 1960 1961unsigned MipsAsmParser::getReg(int RC, int RegNo) { 1962 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 1963} 1964 1965unsigned MipsAsmParser::getGPR(int RegNo) { 1966 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 1967 RegNo); 1968} 1969 1970int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 1971 if (RegNum > 1972 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 1973 return -1; 1974 1975 return getReg(RegClass, RegNum); 1976} 1977 1978bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1979 MCAsmParser &Parser = getParser(); 1980 DEBUG(dbgs() << "parseOperand\n"); 1981 1982 // Check if the current operand has a custom associated parser, if so, try to 1983 // custom parse the operand, or fallback to the general approach. 1984 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1985 if (ResTy == MatchOperand_Success) 1986 return false; 1987 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1988 // there was a match, but an error occurred, in which case, just return that 1989 // the operand parsing failed. 1990 if (ResTy == MatchOperand_ParseFail) 1991 return true; 1992 1993 DEBUG(dbgs() << ".. Generic Parser\n"); 1994 1995 switch (getLexer().getKind()) { 1996 default: 1997 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1998 return true; 1999 case AsmToken::Dollar: { 2000 // Parse the register. 2001 SMLoc S = Parser.getTok().getLoc(); 2002 2003 // Almost all registers have been parsed by custom parsers. There is only 2004 // one exception to this. $zero (and it's alias $0) will reach this point 2005 // for div, divu, and similar instructions because it is not an operand 2006 // to the instruction definition but an explicit register. Special case 2007 // this situation for now. 2008 if (parseAnyRegister(Operands) != MatchOperand_NoMatch) 2009 return false; 2010 2011 // Maybe it is a symbol reference. 2012 StringRef Identifier; 2013 if (Parser.parseIdentifier(Identifier)) 2014 return true; 2015 2016 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2017 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 2018 // Otherwise create a symbol reference. 2019 const MCExpr *Res = 2020 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 2021 2022 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 2023 return false; 2024 } 2025 // Else drop to expression parsing. 2026 case AsmToken::LParen: 2027 case AsmToken::Minus: 2028 case AsmToken::Plus: 2029 case AsmToken::Integer: 2030 case AsmToken::Tilde: 2031 case AsmToken::String: { 2032 DEBUG(dbgs() << ".. generic integer\n"); 2033 OperandMatchResultTy ResTy = parseImm(Operands); 2034 return ResTy != MatchOperand_Success; 2035 } 2036 case AsmToken::Percent: { 2037 // It is a symbol reference or constant expression. 2038 const MCExpr *IdVal; 2039 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 2040 if (parseRelocOperand(IdVal)) 2041 return true; 2042 2043 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2044 2045 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 2046 return false; 2047 } // case AsmToken::Percent 2048 } // switch(getLexer().getKind()) 2049 return true; 2050} 2051 2052const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 2053 StringRef RelocStr) { 2054 const MCExpr *Res; 2055 // Check the type of the expression. 2056 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 2057 // It's a constant, evaluate reloc value. 2058 int16_t Val; 2059 switch (getVariantKind(RelocStr)) { 2060 case MCSymbolRefExpr::VK_Mips_ABS_LO: 2061 // Get the 1st 16-bits. 2062 Val = MCE->getValue() & 0xffff; 2063 break; 2064 case MCSymbolRefExpr::VK_Mips_ABS_HI: 2065 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low 2066 // 16 bits being negative. 2067 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff; 2068 break; 2069 case MCSymbolRefExpr::VK_Mips_HIGHER: 2070 // Get the 3rd 16-bits. 2071 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff; 2072 break; 2073 case MCSymbolRefExpr::VK_Mips_HIGHEST: 2074 // Get the 4th 16-bits. 2075 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff; 2076 break; 2077 default: 2078 report_fatal_error("unsupported reloc value"); 2079 } 2080 return MCConstantExpr::Create(Val, getContext()); 2081 } 2082 2083 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 2084 // It's a symbol, create a symbolic expression from the symbol. 2085 StringRef Symbol = MSRE->getSymbol().getName(); 2086 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 2087 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 2088 return Res; 2089 } 2090 2091 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 2092 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 2093 2094 // Try to create target expression. 2095 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE)) 2096 return MipsMCExpr::Create(VK, Expr, getContext()); 2097 2098 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 2099 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 2100 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 2101 return Res; 2102 } 2103 2104 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 2105 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 2106 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 2107 return Res; 2108 } 2109 // Just return the original expression. 2110 return Expr; 2111} 2112 2113bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 2114 2115 switch (Expr->getKind()) { 2116 case MCExpr::Constant: 2117 return true; 2118 case MCExpr::SymbolRef: 2119 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 2120 case MCExpr::Binary: 2121 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 2122 if (!isEvaluated(BE->getLHS())) 2123 return false; 2124 return isEvaluated(BE->getRHS()); 2125 } 2126 case MCExpr::Unary: 2127 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 2128 case MCExpr::Target: 2129 return true; 2130 } 2131 return false; 2132} 2133 2134bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 2135 MCAsmParser &Parser = getParser(); 2136 Parser.Lex(); // Eat the % token. 2137 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 2138 if (Tok.isNot(AsmToken::Identifier)) 2139 return true; 2140 2141 std::string Str = Tok.getIdentifier().str(); 2142 2143 Parser.Lex(); // Eat the identifier. 2144 // Now make an expression from the rest of the operand. 2145 const MCExpr *IdVal; 2146 SMLoc EndLoc; 2147 2148 if (getLexer().getKind() == AsmToken::LParen) { 2149 while (1) { 2150 Parser.Lex(); // Eat the '(' token. 2151 if (getLexer().getKind() == AsmToken::Percent) { 2152 Parser.Lex(); // Eat the % token. 2153 const AsmToken &nextTok = Parser.getTok(); 2154 if (nextTok.isNot(AsmToken::Identifier)) 2155 return true; 2156 Str += "(%"; 2157 Str += nextTok.getIdentifier(); 2158 Parser.Lex(); // Eat the identifier. 2159 if (getLexer().getKind() != AsmToken::LParen) 2160 return true; 2161 } else 2162 break; 2163 } 2164 if (getParser().parseParenExpression(IdVal, EndLoc)) 2165 return true; 2166 2167 while (getLexer().getKind() == AsmToken::RParen) 2168 Parser.Lex(); // Eat the ')' token. 2169 2170 } else 2171 return true; // Parenthesis must follow the relocation operand. 2172 2173 Res = evaluateRelocExpr(IdVal, Str); 2174 return false; 2175} 2176 2177bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 2178 SMLoc &EndLoc) { 2179 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 2180 OperandMatchResultTy ResTy = parseAnyRegister(Operands); 2181 if (ResTy == MatchOperand_Success) { 2182 assert(Operands.size() == 1); 2183 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 2184 StartLoc = Operand.getStartLoc(); 2185 EndLoc = Operand.getEndLoc(); 2186 2187 // AFAIK, we only support numeric registers and named GPR's in CFI 2188 // directives. 2189 // Don't worry about eating tokens before failing. Using an unrecognised 2190 // register is a parse error. 2191 if (Operand.isGPRAsmReg()) { 2192 // Resolve to GPR32 or GPR64 appropriately. 2193 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 2194 } 2195 2196 return (RegNo == (unsigned)-1); 2197 } 2198 2199 assert(Operands.size() == 0); 2200 return (RegNo == (unsigned)-1); 2201} 2202 2203bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 2204 MCAsmParser &Parser = getParser(); 2205 SMLoc S; 2206 bool Result = true; 2207 2208 while (getLexer().getKind() == AsmToken::LParen) 2209 Parser.Lex(); 2210 2211 switch (getLexer().getKind()) { 2212 default: 2213 return true; 2214 case AsmToken::Identifier: 2215 case AsmToken::LParen: 2216 case AsmToken::Integer: 2217 case AsmToken::Minus: 2218 case AsmToken::Plus: 2219 if (isParenExpr) 2220 Result = getParser().parseParenExpression(Res, S); 2221 else 2222 Result = (getParser().parseExpression(Res)); 2223 while (getLexer().getKind() == AsmToken::RParen) 2224 Parser.Lex(); 2225 break; 2226 case AsmToken::Percent: 2227 Result = parseRelocOperand(Res); 2228 } 2229 return Result; 2230} 2231 2232MipsAsmParser::OperandMatchResultTy 2233MipsAsmParser::parseMemOperand(OperandVector &Operands) { 2234 MCAsmParser &Parser = getParser(); 2235 DEBUG(dbgs() << "parseMemOperand\n"); 2236 const MCExpr *IdVal = nullptr; 2237 SMLoc S; 2238 bool isParenExpr = false; 2239 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 2240 // First operand is the offset. 2241 S = Parser.getTok().getLoc(); 2242 2243 if (getLexer().getKind() == AsmToken::LParen) { 2244 Parser.Lex(); 2245 isParenExpr = true; 2246 } 2247 2248 if (getLexer().getKind() != AsmToken::Dollar) { 2249 if (parseMemOffset(IdVal, isParenExpr)) 2250 return MatchOperand_ParseFail; 2251 2252 const AsmToken &Tok = Parser.getTok(); // Get the next token. 2253 if (Tok.isNot(AsmToken::LParen)) { 2254 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 2255 if (Mnemonic.getToken() == "la") { 2256 SMLoc E = 2257 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2258 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 2259 return MatchOperand_Success; 2260 } 2261 if (Tok.is(AsmToken::EndOfStatement)) { 2262 SMLoc E = 2263 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2264 2265 // Zero register assumed, add a memory operand with ZERO as its base. 2266 // "Base" will be managed by k_Memory. 2267 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(), 2268 S, E, *this); 2269 Operands.push_back( 2270 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 2271 return MatchOperand_Success; 2272 } 2273 Error(Parser.getTok().getLoc(), "'(' expected"); 2274 return MatchOperand_ParseFail; 2275 } 2276 2277 Parser.Lex(); // Eat the '(' token. 2278 } 2279 2280 Res = parseAnyRegister(Operands); 2281 if (Res != MatchOperand_Success) 2282 return Res; 2283 2284 if (Parser.getTok().isNot(AsmToken::RParen)) { 2285 Error(Parser.getTok().getLoc(), "')' expected"); 2286 return MatchOperand_ParseFail; 2287 } 2288 2289 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2290 2291 Parser.Lex(); // Eat the ')' token. 2292 2293 if (!IdVal) 2294 IdVal = MCConstantExpr::Create(0, getContext()); 2295 2296 // Replace the register operand with the memory operand. 2297 std::unique_ptr<MipsOperand> op( 2298 static_cast<MipsOperand *>(Operands.back().release())); 2299 // Remove the register from the operands. 2300 // "op" will be managed by k_Memory. 2301 Operands.pop_back(); 2302 // Add the memory operand. 2303 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 2304 int64_t Imm; 2305 if (IdVal->EvaluateAsAbsolute(Imm)) 2306 IdVal = MCConstantExpr::Create(Imm, getContext()); 2307 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 2308 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 2309 getContext()); 2310 } 2311 2312 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 2313 return MatchOperand_Success; 2314} 2315 2316bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 2317 MCAsmParser &Parser = getParser(); 2318 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 2319 if (Sym) { 2320 SMLoc S = Parser.getTok().getLoc(); 2321 const MCExpr *Expr; 2322 if (Sym->isVariable()) 2323 Expr = Sym->getVariableValue(); 2324 else 2325 return false; 2326 if (Expr->getKind() == MCExpr::SymbolRef) { 2327 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 2328 StringRef DefSymbol = Ref->getSymbol().getName(); 2329 if (DefSymbol.startswith("$")) { 2330 OperandMatchResultTy ResTy = 2331 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 2332 if (ResTy == MatchOperand_Success) { 2333 Parser.Lex(); 2334 return true; 2335 } else if (ResTy == MatchOperand_ParseFail) 2336 llvm_unreachable("Should never ParseFail"); 2337 return false; 2338 } 2339 } else if (Expr->getKind() == MCExpr::Constant) { 2340 Parser.Lex(); 2341 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 2342 Operands.push_back( 2343 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this)); 2344 return true; 2345 } 2346 } 2347 return false; 2348} 2349 2350MipsAsmParser::OperandMatchResultTy 2351MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 2352 StringRef Identifier, 2353 SMLoc S) { 2354 int Index = matchCPURegisterName(Identifier); 2355 if (Index != -1) { 2356 Operands.push_back(MipsOperand::createGPRReg( 2357 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2358 return MatchOperand_Success; 2359 } 2360 2361 Index = matchHWRegsRegisterName(Identifier); 2362 if (Index != -1) { 2363 Operands.push_back(MipsOperand::createHWRegsReg( 2364 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2365 return MatchOperand_Success; 2366 } 2367 2368 Index = matchFPURegisterName(Identifier); 2369 if (Index != -1) { 2370 Operands.push_back(MipsOperand::createFGRReg( 2371 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2372 return MatchOperand_Success; 2373 } 2374 2375 Index = matchFCCRegisterName(Identifier); 2376 if (Index != -1) { 2377 Operands.push_back(MipsOperand::createFCCReg( 2378 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2379 return MatchOperand_Success; 2380 } 2381 2382 Index = matchACRegisterName(Identifier); 2383 if (Index != -1) { 2384 Operands.push_back(MipsOperand::createACCReg( 2385 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2386 return MatchOperand_Success; 2387 } 2388 2389 Index = matchMSA128RegisterName(Identifier); 2390 if (Index != -1) { 2391 Operands.push_back(MipsOperand::createMSA128Reg( 2392 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2393 return MatchOperand_Success; 2394 } 2395 2396 Index = matchMSA128CtrlRegisterName(Identifier); 2397 if (Index != -1) { 2398 Operands.push_back(MipsOperand::createMSACtrlReg( 2399 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2400 return MatchOperand_Success; 2401 } 2402 2403 return MatchOperand_NoMatch; 2404} 2405 2406MipsAsmParser::OperandMatchResultTy 2407MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 2408 MCAsmParser &Parser = getParser(); 2409 auto Token = Parser.getLexer().peekTok(false); 2410 2411 if (Token.is(AsmToken::Identifier)) { 2412 DEBUG(dbgs() << ".. identifier\n"); 2413 StringRef Identifier = Token.getIdentifier(); 2414 OperandMatchResultTy ResTy = 2415 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 2416 return ResTy; 2417 } else if (Token.is(AsmToken::Integer)) { 2418 DEBUG(dbgs() << ".. integer\n"); 2419 Operands.push_back(MipsOperand::createNumericReg( 2420 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 2421 *this)); 2422 return MatchOperand_Success; 2423 } 2424 2425 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 2426 2427 return MatchOperand_NoMatch; 2428} 2429 2430MipsAsmParser::OperandMatchResultTy 2431MipsAsmParser::parseAnyRegister(OperandVector &Operands) { 2432 MCAsmParser &Parser = getParser(); 2433 DEBUG(dbgs() << "parseAnyRegister\n"); 2434 2435 auto Token = Parser.getTok(); 2436 2437 SMLoc S = Token.getLoc(); 2438 2439 if (Token.isNot(AsmToken::Dollar)) { 2440 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 2441 if (Token.is(AsmToken::Identifier)) { 2442 if (searchSymbolAlias(Operands)) 2443 return MatchOperand_Success; 2444 } 2445 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 2446 return MatchOperand_NoMatch; 2447 } 2448 DEBUG(dbgs() << ".. $\n"); 2449 2450 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S); 2451 if (ResTy == MatchOperand_Success) { 2452 Parser.Lex(); // $ 2453 Parser.Lex(); // identifier 2454 } 2455 return ResTy; 2456} 2457 2458MipsAsmParser::OperandMatchResultTy 2459MipsAsmParser::parseImm(OperandVector &Operands) { 2460 MCAsmParser &Parser = getParser(); 2461 switch (getLexer().getKind()) { 2462 default: 2463 return MatchOperand_NoMatch; 2464 case AsmToken::LParen: 2465 case AsmToken::Minus: 2466 case AsmToken::Plus: 2467 case AsmToken::Integer: 2468 case AsmToken::Tilde: 2469 case AsmToken::String: 2470 break; 2471 } 2472 2473 const MCExpr *IdVal; 2474 SMLoc S = Parser.getTok().getLoc(); 2475 if (getParser().parseExpression(IdVal)) 2476 return MatchOperand_ParseFail; 2477 2478 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2479 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 2480 return MatchOperand_Success; 2481} 2482 2483MipsAsmParser::OperandMatchResultTy 2484MipsAsmParser::parseJumpTarget(OperandVector &Operands) { 2485 MCAsmParser &Parser = getParser(); 2486 DEBUG(dbgs() << "parseJumpTarget\n"); 2487 2488 SMLoc S = getLexer().getLoc(); 2489 2490 // Integers and expressions are acceptable 2491 OperandMatchResultTy ResTy = parseImm(Operands); 2492 if (ResTy != MatchOperand_NoMatch) 2493 return ResTy; 2494 2495 // Registers are a valid target and have priority over symbols. 2496 ResTy = parseAnyRegister(Operands); 2497 if (ResTy != MatchOperand_NoMatch) 2498 return ResTy; 2499 2500 const MCExpr *Expr = nullptr; 2501 if (Parser.parseExpression(Expr)) { 2502 // We have no way of knowing if a symbol was consumed so we must ParseFail 2503 return MatchOperand_ParseFail; 2504 } 2505 Operands.push_back( 2506 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 2507 return MatchOperand_Success; 2508} 2509 2510MipsAsmParser::OperandMatchResultTy 2511MipsAsmParser::parseInvNum(OperandVector &Operands) { 2512 MCAsmParser &Parser = getParser(); 2513 const MCExpr *IdVal; 2514 // If the first token is '$' we may have register operand. 2515 if (Parser.getTok().is(AsmToken::Dollar)) 2516 return MatchOperand_NoMatch; 2517 SMLoc S = Parser.getTok().getLoc(); 2518 if (getParser().parseExpression(IdVal)) 2519 return MatchOperand_ParseFail; 2520 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 2521 assert(MCE && "Unexpected MCExpr type."); 2522 int64_t Val = MCE->getValue(); 2523 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2524 Operands.push_back(MipsOperand::CreateImm( 2525 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); 2526 return MatchOperand_Success; 2527} 2528 2529MipsAsmParser::OperandMatchResultTy 2530MipsAsmParser::parseLSAImm(OperandVector &Operands) { 2531 MCAsmParser &Parser = getParser(); 2532 switch (getLexer().getKind()) { 2533 default: 2534 return MatchOperand_NoMatch; 2535 case AsmToken::LParen: 2536 case AsmToken::Plus: 2537 case AsmToken::Minus: 2538 case AsmToken::Integer: 2539 break; 2540 } 2541 2542 const MCExpr *Expr; 2543 SMLoc S = Parser.getTok().getLoc(); 2544 2545 if (getParser().parseExpression(Expr)) 2546 return MatchOperand_ParseFail; 2547 2548 int64_t Val; 2549 if (!Expr->EvaluateAsAbsolute(Val)) { 2550 Error(S, "expected immediate value"); 2551 return MatchOperand_ParseFail; 2552 } 2553 2554 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 2555 // and because the CPU always adds one to the immediate field, the allowed 2556 // range becomes 1..4. We'll only check the range here and will deal 2557 // with the addition/subtraction when actually decoding/encoding 2558 // the instruction. 2559 if (Val < 1 || Val > 4) { 2560 Error(S, "immediate not in range (1..4)"); 2561 return MatchOperand_ParseFail; 2562 } 2563 2564 Operands.push_back( 2565 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 2566 return MatchOperand_Success; 2567} 2568 2569MipsAsmParser::OperandMatchResultTy 2570MipsAsmParser::parseRegisterList(OperandVector &Operands) { 2571 MCAsmParser &Parser = getParser(); 2572 SmallVector<unsigned, 10> Regs; 2573 unsigned RegNo; 2574 unsigned PrevReg = Mips::NoRegister; 2575 bool RegRange = false; 2576 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands; 2577 2578 if (Parser.getTok().isNot(AsmToken::Dollar)) 2579 return MatchOperand_ParseFail; 2580 2581 SMLoc S = Parser.getTok().getLoc(); 2582 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) { 2583 SMLoc E = getLexer().getLoc(); 2584 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back()); 2585 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg(); 2586 if (RegRange) { 2587 // Remove last register operand because registers from register range 2588 // should be inserted first. 2589 if (RegNo == Mips::RA) { 2590 Regs.push_back(RegNo); 2591 } else { 2592 unsigned TmpReg = PrevReg + 1; 2593 while (TmpReg <= RegNo) { 2594 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) { 2595 Error(E, "invalid register operand"); 2596 return MatchOperand_ParseFail; 2597 } 2598 2599 PrevReg = TmpReg; 2600 Regs.push_back(TmpReg++); 2601 } 2602 } 2603 2604 RegRange = false; 2605 } else { 2606 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) && 2607 (RegNo != Mips::RA)) { 2608 Error(E, "$16 or $31 expected"); 2609 return MatchOperand_ParseFail; 2610 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) && 2611 (RegNo != Mips::FP) && (RegNo != Mips::RA)) { 2612 Error(E, "invalid register operand"); 2613 return MatchOperand_ParseFail; 2614 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) && 2615 (RegNo != Mips::FP) && (RegNo != Mips::RA)) { 2616 Error(E, "consecutive register numbers expected"); 2617 return MatchOperand_ParseFail; 2618 } 2619 2620 Regs.push_back(RegNo); 2621 } 2622 2623 if (Parser.getTok().is(AsmToken::Minus)) 2624 RegRange = true; 2625 2626 if (!Parser.getTok().isNot(AsmToken::Minus) && 2627 !Parser.getTok().isNot(AsmToken::Comma)) { 2628 Error(E, "',' or '-' expected"); 2629 return MatchOperand_ParseFail; 2630 } 2631 2632 Lex(); // Consume comma or minus 2633 if (Parser.getTok().isNot(AsmToken::Dollar)) 2634 break; 2635 2636 PrevReg = RegNo; 2637 } 2638 2639 SMLoc E = Parser.getTok().getLoc(); 2640 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); 2641 parseMemOperand(Operands); 2642 return MatchOperand_Success; 2643} 2644 2645MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 2646 2647 MCSymbolRefExpr::VariantKind VK = 2648 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 2649 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 2650 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 2651 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 2652 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 2653 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 2654 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 2655 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 2656 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 2657 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 2658 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 2659 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 2660 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 2661 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 2662 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 2663 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 2664 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 2665 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 2666 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16) 2667 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16) 2668 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16) 2669 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16) 2670 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER) 2671 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST) 2672 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16) 2673 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16) 2674 .Default(MCSymbolRefExpr::VK_None); 2675 2676 assert(VK != MCSymbolRefExpr::VK_None); 2677 2678 return VK; 2679} 2680 2681/// Sometimes (i.e. load/stores) the operand may be followed immediately by 2682/// either this. 2683/// ::= '(', register, ')' 2684/// handle it before we iterate so we don't get tripped up by the lack of 2685/// a comma. 2686bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) { 2687 MCAsmParser &Parser = getParser(); 2688 if (getLexer().is(AsmToken::LParen)) { 2689 Operands.push_back( 2690 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 2691 Parser.Lex(); 2692 if (parseOperand(Operands, Name)) { 2693 SMLoc Loc = getLexer().getLoc(); 2694 Parser.eatToEndOfStatement(); 2695 return Error(Loc, "unexpected token in argument list"); 2696 } 2697 if (Parser.getTok().isNot(AsmToken::RParen)) { 2698 SMLoc Loc = getLexer().getLoc(); 2699 Parser.eatToEndOfStatement(); 2700 return Error(Loc, "unexpected token, expected ')'"); 2701 } 2702 Operands.push_back( 2703 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 2704 Parser.Lex(); 2705 } 2706 return false; 2707} 2708 2709/// Sometimes (i.e. in MSA) the operand may be followed immediately by 2710/// either one of these. 2711/// ::= '[', register, ']' 2712/// ::= '[', integer, ']' 2713/// handle it before we iterate so we don't get tripped up by the lack of 2714/// a comma. 2715bool MipsAsmParser::parseBracketSuffix(StringRef Name, 2716 OperandVector &Operands) { 2717 MCAsmParser &Parser = getParser(); 2718 if (getLexer().is(AsmToken::LBrac)) { 2719 Operands.push_back( 2720 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 2721 Parser.Lex(); 2722 if (parseOperand(Operands, Name)) { 2723 SMLoc Loc = getLexer().getLoc(); 2724 Parser.eatToEndOfStatement(); 2725 return Error(Loc, "unexpected token in argument list"); 2726 } 2727 if (Parser.getTok().isNot(AsmToken::RBrac)) { 2728 SMLoc Loc = getLexer().getLoc(); 2729 Parser.eatToEndOfStatement(); 2730 return Error(Loc, "unexpected token, expected ']'"); 2731 } 2732 Operands.push_back( 2733 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 2734 Parser.Lex(); 2735 } 2736 return false; 2737} 2738 2739bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 2740 SMLoc NameLoc, OperandVector &Operands) { 2741 MCAsmParser &Parser = getParser(); 2742 DEBUG(dbgs() << "ParseInstruction\n"); 2743 2744 // We have reached first instruction, module directive are now forbidden. 2745 getTargetStreamer().forbidModuleDirective(); 2746 2747 // Check if we have valid mnemonic 2748 if (!mnemonicIsValid(Name, 0)) { 2749 Parser.eatToEndOfStatement(); 2750 return Error(NameLoc, "unknown instruction"); 2751 } 2752 // First operand in MCInst is instruction mnemonic. 2753 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 2754 2755 // Read the remaining operands. 2756 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2757 // Read the first operand. 2758 if (parseOperand(Operands, Name)) { 2759 SMLoc Loc = getLexer().getLoc(); 2760 Parser.eatToEndOfStatement(); 2761 return Error(Loc, "unexpected token in argument list"); 2762 } 2763 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands)) 2764 return true; 2765 // AFAIK, parenthesis suffixes are never on the first operand 2766 2767 while (getLexer().is(AsmToken::Comma)) { 2768 Parser.Lex(); // Eat the comma. 2769 // Parse and remember the operand. 2770 if (parseOperand(Operands, Name)) { 2771 SMLoc Loc = getLexer().getLoc(); 2772 Parser.eatToEndOfStatement(); 2773 return Error(Loc, "unexpected token in argument list"); 2774 } 2775 // Parse bracket and parenthesis suffixes before we iterate 2776 if (getLexer().is(AsmToken::LBrac)) { 2777 if (parseBracketSuffix(Name, Operands)) 2778 return true; 2779 } else if (getLexer().is(AsmToken::LParen) && 2780 parseParenSuffix(Name, Operands)) 2781 return true; 2782 } 2783 } 2784 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2785 SMLoc Loc = getLexer().getLoc(); 2786 Parser.eatToEndOfStatement(); 2787 return Error(Loc, "unexpected token in argument list"); 2788 } 2789 Parser.Lex(); // Consume the EndOfStatement. 2790 return false; 2791} 2792 2793bool MipsAsmParser::reportParseError(Twine ErrorMsg) { 2794 MCAsmParser &Parser = getParser(); 2795 SMLoc Loc = getLexer().getLoc(); 2796 Parser.eatToEndOfStatement(); 2797 return Error(Loc, ErrorMsg); 2798} 2799 2800bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) { 2801 return Error(Loc, ErrorMsg); 2802} 2803 2804bool MipsAsmParser::parseSetNoAtDirective() { 2805 MCAsmParser &Parser = getParser(); 2806 // Line should look like: ".set noat". 2807 // set at reg to 0. 2808 AssemblerOptions.back()->setATReg(0); 2809 // eat noat 2810 Parser.Lex(); 2811 // If this is not the end of the statement, report an error. 2812 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2813 reportParseError("unexpected token, expected end of statement"); 2814 return false; 2815 } 2816 Parser.Lex(); // Consume the EndOfStatement. 2817 return false; 2818} 2819 2820bool MipsAsmParser::parseSetAtDirective() { 2821 MCAsmParser &Parser = getParser(); 2822 // Line can be .set at - defaults to $1 2823 // or .set at=$reg 2824 int AtRegNo; 2825 getParser().Lex(); 2826 if (getLexer().is(AsmToken::EndOfStatement)) { 2827 AssemblerOptions.back()->setATReg(1); 2828 Parser.Lex(); // Consume the EndOfStatement. 2829 return false; 2830 } else if (getLexer().is(AsmToken::Equal)) { 2831 getParser().Lex(); // Eat the '='. 2832 if (getLexer().isNot(AsmToken::Dollar)) { 2833 reportParseError("unexpected token, expected dollar sign '$'"); 2834 return false; 2835 } 2836 Parser.Lex(); // Eat the '$'. 2837 const AsmToken &Reg = Parser.getTok(); 2838 if (Reg.is(AsmToken::Identifier)) { 2839 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 2840 } else if (Reg.is(AsmToken::Integer)) { 2841 AtRegNo = Reg.getIntVal(); 2842 } else { 2843 reportParseError("unexpected token, expected identifier or integer"); 2844 return false; 2845 } 2846 2847 if (AtRegNo < 0 || AtRegNo > 31) { 2848 reportParseError("unexpected token in statement"); 2849 return false; 2850 } 2851 2852 if (!AssemblerOptions.back()->setATReg(AtRegNo)) { 2853 reportParseError("invalid register"); 2854 return false; 2855 } 2856 getParser().Lex(); // Eat the register. 2857 2858 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2859 reportParseError("unexpected token, expected end of statement"); 2860 return false; 2861 } 2862 Parser.Lex(); // Consume the EndOfStatement. 2863 return false; 2864 } else { 2865 reportParseError("unexpected token in statement"); 2866 return false; 2867 } 2868} 2869 2870bool MipsAsmParser::parseSetReorderDirective() { 2871 MCAsmParser &Parser = getParser(); 2872 Parser.Lex(); 2873 // If this is not the end of the statement, report an error. 2874 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2875 reportParseError("unexpected token, expected end of statement"); 2876 return false; 2877 } 2878 AssemblerOptions.back()->setReorder(); 2879 getTargetStreamer().emitDirectiveSetReorder(); 2880 Parser.Lex(); // Consume the EndOfStatement. 2881 return false; 2882} 2883 2884bool MipsAsmParser::parseSetNoReorderDirective() { 2885 MCAsmParser &Parser = getParser(); 2886 Parser.Lex(); 2887 // If this is not the end of the statement, report an error. 2888 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2889 reportParseError("unexpected token, expected end of statement"); 2890 return false; 2891 } 2892 AssemblerOptions.back()->setNoReorder(); 2893 getTargetStreamer().emitDirectiveSetNoReorder(); 2894 Parser.Lex(); // Consume the EndOfStatement. 2895 return false; 2896} 2897 2898bool MipsAsmParser::parseSetMacroDirective() { 2899 MCAsmParser &Parser = getParser(); 2900 Parser.Lex(); 2901 // If this is not the end of the statement, report an error. 2902 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2903 reportParseError("unexpected token, expected end of statement"); 2904 return false; 2905 } 2906 AssemblerOptions.back()->setMacro(); 2907 Parser.Lex(); // Consume the EndOfStatement. 2908 return false; 2909} 2910 2911bool MipsAsmParser::parseSetNoMacroDirective() { 2912 MCAsmParser &Parser = getParser(); 2913 Parser.Lex(); 2914 // If this is not the end of the statement, report an error. 2915 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2916 reportParseError("unexpected token, expected end of statement"); 2917 return false; 2918 } 2919 if (AssemblerOptions.back()->isReorder()) { 2920 reportParseError("`noreorder' must be set before `nomacro'"); 2921 return false; 2922 } 2923 AssemblerOptions.back()->setNoMacro(); 2924 Parser.Lex(); // Consume the EndOfStatement. 2925 return false; 2926} 2927 2928bool MipsAsmParser::parseSetMsaDirective() { 2929 MCAsmParser &Parser = getParser(); 2930 Parser.Lex(); 2931 2932 // If this is not the end of the statement, report an error. 2933 if (getLexer().isNot(AsmToken::EndOfStatement)) 2934 return reportParseError("unexpected token, expected end of statement"); 2935 2936 setFeatureBits(Mips::FeatureMSA, "msa"); 2937 getTargetStreamer().emitDirectiveSetMsa(); 2938 return false; 2939} 2940 2941bool MipsAsmParser::parseSetNoMsaDirective() { 2942 MCAsmParser &Parser = getParser(); 2943 Parser.Lex(); 2944 2945 // If this is not the end of the statement, report an error. 2946 if (getLexer().isNot(AsmToken::EndOfStatement)) 2947 return reportParseError("unexpected token, expected end of statement"); 2948 2949 clearFeatureBits(Mips::FeatureMSA, "msa"); 2950 getTargetStreamer().emitDirectiveSetNoMsa(); 2951 return false; 2952} 2953 2954bool MipsAsmParser::parseSetNoDspDirective() { 2955 MCAsmParser &Parser = getParser(); 2956 Parser.Lex(); // Eat "nodsp". 2957 2958 // If this is not the end of the statement, report an error. 2959 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2960 reportParseError("unexpected token, expected end of statement"); 2961 return false; 2962 } 2963 2964 clearFeatureBits(Mips::FeatureDSP, "dsp"); 2965 getTargetStreamer().emitDirectiveSetNoDsp(); 2966 return false; 2967} 2968 2969bool MipsAsmParser::parseSetMips16Directive() { 2970 MCAsmParser &Parser = getParser(); 2971 Parser.Lex(); // Eat "mips16". 2972 2973 // If this is not the end of the statement, report an error. 2974 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2975 reportParseError("unexpected token, expected end of statement"); 2976 return false; 2977 } 2978 2979 setFeatureBits(Mips::FeatureMips16, "mips16"); 2980 getTargetStreamer().emitDirectiveSetMips16(); 2981 Parser.Lex(); // Consume the EndOfStatement. 2982 return false; 2983} 2984 2985bool MipsAsmParser::parseSetNoMips16Directive() { 2986 MCAsmParser &Parser = getParser(); 2987 Parser.Lex(); // Eat "nomips16". 2988 2989 // If this is not the end of the statement, report an error. 2990 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2991 reportParseError("unexpected token, expected end of statement"); 2992 return false; 2993 } 2994 2995 clearFeatureBits(Mips::FeatureMips16, "mips16"); 2996 getTargetStreamer().emitDirectiveSetNoMips16(); 2997 Parser.Lex(); // Consume the EndOfStatement. 2998 return false; 2999} 3000 3001bool MipsAsmParser::parseSetFpDirective() { 3002 MCAsmParser &Parser = getParser(); 3003 MipsABIFlagsSection::FpABIKind FpAbiVal; 3004 // Line can be: .set fp=32 3005 // .set fp=xx 3006 // .set fp=64 3007 Parser.Lex(); // Eat fp token 3008 AsmToken Tok = Parser.getTok(); 3009 if (Tok.isNot(AsmToken::Equal)) { 3010 reportParseError("unexpected token, expected equals sign '='"); 3011 return false; 3012 } 3013 Parser.Lex(); // Eat '=' token. 3014 Tok = Parser.getTok(); 3015 3016 if (!parseFpABIValue(FpAbiVal, ".set")) 3017 return false; 3018 3019 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3020 reportParseError("unexpected token, expected end of statement"); 3021 return false; 3022 } 3023 getTargetStreamer().emitDirectiveSetFp(FpAbiVal); 3024 Parser.Lex(); // Consume the EndOfStatement. 3025 return false; 3026} 3027 3028bool MipsAsmParser::parseSetPopDirective() { 3029 MCAsmParser &Parser = getParser(); 3030 SMLoc Loc = getLexer().getLoc(); 3031 3032 Parser.Lex(); 3033 if (getLexer().isNot(AsmToken::EndOfStatement)) 3034 return reportParseError("unexpected token, expected end of statement"); 3035 3036 // Always keep an element on the options "stack" to prevent the user 3037 // from changing the initial options. This is how we remember them. 3038 if (AssemblerOptions.size() == 2) 3039 return reportParseError(Loc, ".set pop with no .set push"); 3040 3041 AssemblerOptions.pop_back(); 3042 setAvailableFeatures(AssemblerOptions.back()->getFeatures()); 3043 3044 getTargetStreamer().emitDirectiveSetPop(); 3045 return false; 3046} 3047 3048bool MipsAsmParser::parseSetPushDirective() { 3049 MCAsmParser &Parser = getParser(); 3050 Parser.Lex(); 3051 if (getLexer().isNot(AsmToken::EndOfStatement)) 3052 return reportParseError("unexpected token, expected end of statement"); 3053 3054 // Create a copy of the current assembler options environment and push it. 3055 AssemblerOptions.push_back( 3056 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get())); 3057 3058 getTargetStreamer().emitDirectiveSetPush(); 3059 return false; 3060} 3061 3062bool MipsAsmParser::parseSetAssignment() { 3063 StringRef Name; 3064 const MCExpr *Value; 3065 MCAsmParser &Parser = getParser(); 3066 3067 if (Parser.parseIdentifier(Name)) 3068 reportParseError("expected identifier after .set"); 3069 3070 if (getLexer().isNot(AsmToken::Comma)) 3071 return reportParseError("unexpected token, expected comma"); 3072 Lex(); // Eat comma 3073 3074 if (Parser.parseExpression(Value)) 3075 return reportParseError("expected valid expression after comma"); 3076 3077 // Check if the Name already exists as a symbol. 3078 MCSymbol *Sym = getContext().LookupSymbol(Name); 3079 if (Sym) 3080 return reportParseError("symbol already defined"); 3081 Sym = getContext().GetOrCreateSymbol(Name); 3082 Sym->setVariableValue(Value); 3083 3084 return false; 3085} 3086 3087bool MipsAsmParser::parseSetMips0Directive() { 3088 MCAsmParser &Parser = getParser(); 3089 Parser.Lex(); 3090 if (getLexer().isNot(AsmToken::EndOfStatement)) 3091 return reportParseError("unexpected token, expected end of statement"); 3092 3093 // Reset assembler options to their initial values. 3094 setAvailableFeatures(AssemblerOptions.front()->getFeatures()); 3095 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures()); 3096 3097 getTargetStreamer().emitDirectiveSetMips0(); 3098 return false; 3099} 3100 3101bool MipsAsmParser::parseSetArchDirective() { 3102 MCAsmParser &Parser = getParser(); 3103 Parser.Lex(); 3104 if (getLexer().isNot(AsmToken::Equal)) 3105 return reportParseError("unexpected token, expected equals sign"); 3106 3107 Parser.Lex(); 3108 StringRef Arch; 3109 if (Parser.parseIdentifier(Arch)) 3110 return reportParseError("expected arch identifier"); 3111 3112 StringRef ArchFeatureName = 3113 StringSwitch<StringRef>(Arch) 3114 .Case("mips1", "mips1") 3115 .Case("mips2", "mips2") 3116 .Case("mips3", "mips3") 3117 .Case("mips4", "mips4") 3118 .Case("mips5", "mips5") 3119 .Case("mips32", "mips32") 3120 .Case("mips32r2", "mips32r2") 3121 .Case("mips32r6", "mips32r6") 3122 .Case("mips64", "mips64") 3123 .Case("mips64r2", "mips64r2") 3124 .Case("mips64r6", "mips64r6") 3125 .Case("cnmips", "cnmips") 3126 .Case("r4000", "mips3") // This is an implementation of Mips3. 3127 .Default(""); 3128 3129 if (ArchFeatureName.empty()) 3130 return reportParseError("unsupported architecture"); 3131 3132 selectArch(ArchFeatureName); 3133 getTargetStreamer().emitDirectiveSetArch(Arch); 3134 return false; 3135} 3136 3137bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 3138 MCAsmParser &Parser = getParser(); 3139 Parser.Lex(); 3140 if (getLexer().isNot(AsmToken::EndOfStatement)) 3141 return reportParseError("unexpected token, expected end of statement"); 3142 3143 switch (Feature) { 3144 default: 3145 llvm_unreachable("Unimplemented feature"); 3146 case Mips::FeatureDSP: 3147 setFeatureBits(Mips::FeatureDSP, "dsp"); 3148 getTargetStreamer().emitDirectiveSetDsp(); 3149 break; 3150 case Mips::FeatureMicroMips: 3151 getTargetStreamer().emitDirectiveSetMicroMips(); 3152 break; 3153 case Mips::FeatureMips1: 3154 selectArch("mips1"); 3155 getTargetStreamer().emitDirectiveSetMips1(); 3156 break; 3157 case Mips::FeatureMips2: 3158 selectArch("mips2"); 3159 getTargetStreamer().emitDirectiveSetMips2(); 3160 break; 3161 case Mips::FeatureMips3: 3162 selectArch("mips3"); 3163 getTargetStreamer().emitDirectiveSetMips3(); 3164 break; 3165 case Mips::FeatureMips4: 3166 selectArch("mips4"); 3167 getTargetStreamer().emitDirectiveSetMips4(); 3168 break; 3169 case Mips::FeatureMips5: 3170 selectArch("mips5"); 3171 getTargetStreamer().emitDirectiveSetMips5(); 3172 break; 3173 case Mips::FeatureMips32: 3174 selectArch("mips32"); 3175 getTargetStreamer().emitDirectiveSetMips32(); 3176 break; 3177 case Mips::FeatureMips32r2: 3178 selectArch("mips32r2"); 3179 getTargetStreamer().emitDirectiveSetMips32R2(); 3180 break; 3181 case Mips::FeatureMips32r6: 3182 selectArch("mips32r6"); 3183 getTargetStreamer().emitDirectiveSetMips32R6(); 3184 break; 3185 case Mips::FeatureMips64: 3186 selectArch("mips64"); 3187 getTargetStreamer().emitDirectiveSetMips64(); 3188 break; 3189 case Mips::FeatureMips64r2: 3190 selectArch("mips64r2"); 3191 getTargetStreamer().emitDirectiveSetMips64R2(); 3192 break; 3193 case Mips::FeatureMips64r6: 3194 selectArch("mips64r6"); 3195 getTargetStreamer().emitDirectiveSetMips64R6(); 3196 break; 3197 } 3198 return false; 3199} 3200 3201bool MipsAsmParser::eatComma(StringRef ErrorStr) { 3202 MCAsmParser &Parser = getParser(); 3203 if (getLexer().isNot(AsmToken::Comma)) { 3204 SMLoc Loc = getLexer().getLoc(); 3205 Parser.eatToEndOfStatement(); 3206 return Error(Loc, ErrorStr); 3207 } 3208 3209 Parser.Lex(); // Eat the comma. 3210 return true; 3211} 3212 3213bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) { 3214 if (AssemblerOptions.back()->isReorder()) 3215 Warning(Loc, ".cpload should be inside a noreorder section"); 3216 3217 if (inMips16Mode()) { 3218 reportParseError(".cpload is not supported in Mips16 mode"); 3219 return false; 3220 } 3221 3222 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 3223 OperandMatchResultTy ResTy = parseAnyRegister(Reg); 3224 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 3225 reportParseError("expected register containing function address"); 3226 return false; 3227 } 3228 3229 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 3230 if (!RegOpnd.isGPRAsmReg()) { 3231 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 3232 return false; 3233 } 3234 3235 // If this is not the end of the statement, report an error. 3236 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3237 reportParseError("unexpected token, expected end of statement"); 3238 return false; 3239 } 3240 3241 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg()); 3242 return false; 3243} 3244 3245bool MipsAsmParser::parseDirectiveCPSetup() { 3246 MCAsmParser &Parser = getParser(); 3247 unsigned FuncReg; 3248 unsigned Save; 3249 bool SaveIsReg = true; 3250 3251 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 3252 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 3253 if (ResTy == MatchOperand_NoMatch) { 3254 reportParseError("expected register containing function address"); 3255 Parser.eatToEndOfStatement(); 3256 return false; 3257 } 3258 3259 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 3260 if (!FuncRegOpnd.isGPRAsmReg()) { 3261 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 3262 Parser.eatToEndOfStatement(); 3263 return false; 3264 } 3265 3266 FuncReg = FuncRegOpnd.getGPR32Reg(); 3267 TmpReg.clear(); 3268 3269 if (!eatComma("unexpected token, expected comma")) 3270 return true; 3271 3272 ResTy = parseAnyRegister(TmpReg); 3273 if (ResTy == MatchOperand_NoMatch) { 3274 const AsmToken &Tok = Parser.getTok(); 3275 if (Tok.is(AsmToken::Integer)) { 3276 Save = Tok.getIntVal(); 3277 SaveIsReg = false; 3278 Parser.Lex(); 3279 } else { 3280 reportParseError("expected save register or stack offset"); 3281 Parser.eatToEndOfStatement(); 3282 return false; 3283 } 3284 } else { 3285 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 3286 if (!SaveOpnd.isGPRAsmReg()) { 3287 reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 3288 Parser.eatToEndOfStatement(); 3289 return false; 3290 } 3291 Save = SaveOpnd.getGPR32Reg(); 3292 } 3293 3294 if (!eatComma("unexpected token, expected comma")) 3295 return true; 3296 3297 StringRef Name; 3298 if (Parser.parseIdentifier(Name)) 3299 reportParseError("expected identifier"); 3300 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3301 3302 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg); 3303 return false; 3304} 3305 3306bool MipsAsmParser::parseDirectiveNaN() { 3307 MCAsmParser &Parser = getParser(); 3308 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3309 const AsmToken &Tok = Parser.getTok(); 3310 3311 if (Tok.getString() == "2008") { 3312 Parser.Lex(); 3313 getTargetStreamer().emitDirectiveNaN2008(); 3314 return false; 3315 } else if (Tok.getString() == "legacy") { 3316 Parser.Lex(); 3317 getTargetStreamer().emitDirectiveNaNLegacy(); 3318 return false; 3319 } 3320 } 3321 // If we don't recognize the option passed to the .nan 3322 // directive (e.g. no option or unknown option), emit an error. 3323 reportParseError("invalid option in .nan directive"); 3324 return false; 3325} 3326 3327bool MipsAsmParser::parseDirectiveSet() { 3328 MCAsmParser &Parser = getParser(); 3329 // Get the next token. 3330 const AsmToken &Tok = Parser.getTok(); 3331 3332 if (Tok.getString() == "noat") { 3333 return parseSetNoAtDirective(); 3334 } else if (Tok.getString() == "at") { 3335 return parseSetAtDirective(); 3336 } else if (Tok.getString() == "arch") { 3337 return parseSetArchDirective(); 3338 } else if (Tok.getString() == "fp") { 3339 return parseSetFpDirective(); 3340 } else if (Tok.getString() == "pop") { 3341 return parseSetPopDirective(); 3342 } else if (Tok.getString() == "push") { 3343 return parseSetPushDirective(); 3344 } else if (Tok.getString() == "reorder") { 3345 return parseSetReorderDirective(); 3346 } else if (Tok.getString() == "noreorder") { 3347 return parseSetNoReorderDirective(); 3348 } else if (Tok.getString() == "macro") { 3349 return parseSetMacroDirective(); 3350 } else if (Tok.getString() == "nomacro") { 3351 return parseSetNoMacroDirective(); 3352 } else if (Tok.getString() == "mips16") { 3353 return parseSetMips16Directive(); 3354 } else if (Tok.getString() == "nomips16") { 3355 return parseSetNoMips16Directive(); 3356 } else if (Tok.getString() == "nomicromips") { 3357 getTargetStreamer().emitDirectiveSetNoMicroMips(); 3358 Parser.eatToEndOfStatement(); 3359 return false; 3360 } else if (Tok.getString() == "micromips") { 3361 return parseSetFeature(Mips::FeatureMicroMips); 3362 } else if (Tok.getString() == "mips0") { 3363 return parseSetMips0Directive(); 3364 } else if (Tok.getString() == "mips1") { 3365 return parseSetFeature(Mips::FeatureMips1); 3366 } else if (Tok.getString() == "mips2") { 3367 return parseSetFeature(Mips::FeatureMips2); 3368 } else if (Tok.getString() == "mips3") { 3369 return parseSetFeature(Mips::FeatureMips3); 3370 } else if (Tok.getString() == "mips4") { 3371 return parseSetFeature(Mips::FeatureMips4); 3372 } else if (Tok.getString() == "mips5") { 3373 return parseSetFeature(Mips::FeatureMips5); 3374 } else if (Tok.getString() == "mips32") { 3375 return parseSetFeature(Mips::FeatureMips32); 3376 } else if (Tok.getString() == "mips32r2") { 3377 return parseSetFeature(Mips::FeatureMips32r2); 3378 } else if (Tok.getString() == "mips32r6") { 3379 return parseSetFeature(Mips::FeatureMips32r6); 3380 } else if (Tok.getString() == "mips64") { 3381 return parseSetFeature(Mips::FeatureMips64); 3382 } else if (Tok.getString() == "mips64r2") { 3383 return parseSetFeature(Mips::FeatureMips64r2); 3384 } else if (Tok.getString() == "mips64r6") { 3385 return parseSetFeature(Mips::FeatureMips64r6); 3386 } else if (Tok.getString() == "dsp") { 3387 return parseSetFeature(Mips::FeatureDSP); 3388 } else if (Tok.getString() == "nodsp") { 3389 return parseSetNoDspDirective(); 3390 } else if (Tok.getString() == "msa") { 3391 return parseSetMsaDirective(); 3392 } else if (Tok.getString() == "nomsa") { 3393 return parseSetNoMsaDirective(); 3394 } else { 3395 // It is just an identifier, look for an assignment. 3396 parseSetAssignment(); 3397 return false; 3398 } 3399 3400 return true; 3401} 3402 3403/// parseDataDirective 3404/// ::= .word [ expression (, expression)* ] 3405bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 3406 MCAsmParser &Parser = getParser(); 3407 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3408 for (;;) { 3409 const MCExpr *Value; 3410 if (getParser().parseExpression(Value)) 3411 return true; 3412 3413 getParser().getStreamer().EmitValue(Value, Size); 3414 3415 if (getLexer().is(AsmToken::EndOfStatement)) 3416 break; 3417 3418 if (getLexer().isNot(AsmToken::Comma)) 3419 return Error(L, "unexpected token, expected comma"); 3420 Parser.Lex(); 3421 } 3422 } 3423 3424 Parser.Lex(); 3425 return false; 3426} 3427 3428/// parseDirectiveGpWord 3429/// ::= .gpword local_sym 3430bool MipsAsmParser::parseDirectiveGpWord() { 3431 MCAsmParser &Parser = getParser(); 3432 const MCExpr *Value; 3433 // EmitGPRel32Value requires an expression, so we are using base class 3434 // method to evaluate the expression. 3435 if (getParser().parseExpression(Value)) 3436 return true; 3437 getParser().getStreamer().EmitGPRel32Value(Value); 3438 3439 if (getLexer().isNot(AsmToken::EndOfStatement)) 3440 return Error(getLexer().getLoc(), 3441 "unexpected token, expected end of statement"); 3442 Parser.Lex(); // Eat EndOfStatement token. 3443 return false; 3444} 3445 3446/// parseDirectiveGpDWord 3447/// ::= .gpdword local_sym 3448bool MipsAsmParser::parseDirectiveGpDWord() { 3449 MCAsmParser &Parser = getParser(); 3450 const MCExpr *Value; 3451 // EmitGPRel64Value requires an expression, so we are using base class 3452 // method to evaluate the expression. 3453 if (getParser().parseExpression(Value)) 3454 return true; 3455 getParser().getStreamer().EmitGPRel64Value(Value); 3456 3457 if (getLexer().isNot(AsmToken::EndOfStatement)) 3458 return Error(getLexer().getLoc(), 3459 "unexpected token, expected end of statement"); 3460 Parser.Lex(); // Eat EndOfStatement token. 3461 return false; 3462} 3463 3464bool MipsAsmParser::parseDirectiveOption() { 3465 MCAsmParser &Parser = getParser(); 3466 // Get the option token. 3467 AsmToken Tok = Parser.getTok(); 3468 // At the moment only identifiers are supported. 3469 if (Tok.isNot(AsmToken::Identifier)) { 3470 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier"); 3471 Parser.eatToEndOfStatement(); 3472 return false; 3473 } 3474 3475 StringRef Option = Tok.getIdentifier(); 3476 3477 if (Option == "pic0") { 3478 getTargetStreamer().emitDirectiveOptionPic0(); 3479 Parser.Lex(); 3480 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 3481 Error(Parser.getTok().getLoc(), 3482 "unexpected token, expected end of statement"); 3483 Parser.eatToEndOfStatement(); 3484 } 3485 return false; 3486 } 3487 3488 if (Option == "pic2") { 3489 getTargetStreamer().emitDirectiveOptionPic2(); 3490 Parser.Lex(); 3491 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 3492 Error(Parser.getTok().getLoc(), 3493 "unexpected token, expected end of statement"); 3494 Parser.eatToEndOfStatement(); 3495 } 3496 return false; 3497 } 3498 3499 // Unknown option. 3500 Warning(Parser.getTok().getLoc(), 3501 "unknown option, expected 'pic0' or 'pic2'"); 3502 Parser.eatToEndOfStatement(); 3503 return false; 3504} 3505 3506/// parseDirectiveModule 3507/// ::= .module oddspreg 3508/// ::= .module nooddspreg 3509/// ::= .module fp=value 3510bool MipsAsmParser::parseDirectiveModule() { 3511 MCAsmParser &Parser = getParser(); 3512 MCAsmLexer &Lexer = getLexer(); 3513 SMLoc L = Lexer.getLoc(); 3514 3515 if (!getTargetStreamer().isModuleDirectiveAllowed()) { 3516 // TODO : get a better message. 3517 reportParseError(".module directive must appear before any code"); 3518 return false; 3519 } 3520 3521 if (Lexer.is(AsmToken::Identifier)) { 3522 StringRef Option = Parser.getTok().getString(); 3523 Parser.Lex(); 3524 3525 if (Option == "oddspreg") { 3526 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32()); 3527 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 3528 3529 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3530 reportParseError("unexpected token, expected end of statement"); 3531 return false; 3532 } 3533 3534 return false; 3535 } else if (Option == "nooddspreg") { 3536 if (!isABI_O32()) { 3537 Error(L, "'.module nooddspreg' requires the O32 ABI"); 3538 return false; 3539 } 3540 3541 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32()); 3542 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 3543 3544 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3545 reportParseError("unexpected token, expected end of statement"); 3546 return false; 3547 } 3548 3549 return false; 3550 } else if (Option == "fp") { 3551 return parseDirectiveModuleFP(); 3552 } 3553 3554 return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); 3555 } 3556 3557 return false; 3558} 3559 3560/// parseDirectiveModuleFP 3561/// ::= =32 3562/// ::= =xx 3563/// ::= =64 3564bool MipsAsmParser::parseDirectiveModuleFP() { 3565 MCAsmParser &Parser = getParser(); 3566 MCAsmLexer &Lexer = getLexer(); 3567 3568 if (Lexer.isNot(AsmToken::Equal)) { 3569 reportParseError("unexpected token, expected equals sign '='"); 3570 return false; 3571 } 3572 Parser.Lex(); // Eat '=' token. 3573 3574 MipsABIFlagsSection::FpABIKind FpABI; 3575 if (!parseFpABIValue(FpABI, ".module")) 3576 return false; 3577 3578 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3579 reportParseError("unexpected token, expected end of statement"); 3580 return false; 3581 } 3582 3583 // Emit appropriate flags. 3584 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32()); 3585 Parser.Lex(); // Consume the EndOfStatement. 3586 return false; 3587} 3588 3589bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 3590 StringRef Directive) { 3591 MCAsmParser &Parser = getParser(); 3592 MCAsmLexer &Lexer = getLexer(); 3593 3594 if (Lexer.is(AsmToken::Identifier)) { 3595 StringRef Value = Parser.getTok().getString(); 3596 Parser.Lex(); 3597 3598 if (Value != "xx") { 3599 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 3600 return false; 3601 } 3602 3603 if (!isABI_O32()) { 3604 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI"); 3605 return false; 3606 } 3607 3608 FpABI = MipsABIFlagsSection::FpABIKind::XX; 3609 return true; 3610 } 3611 3612 if (Lexer.is(AsmToken::Integer)) { 3613 unsigned Value = Parser.getTok().getIntVal(); 3614 Parser.Lex(); 3615 3616 if (Value != 32 && Value != 64) { 3617 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 3618 return false; 3619 } 3620 3621 if (Value == 32) { 3622 if (!isABI_O32()) { 3623 reportParseError("'" + Directive + " fp=32' requires the O32 ABI"); 3624 return false; 3625 } 3626 3627 FpABI = MipsABIFlagsSection::FpABIKind::S32; 3628 } else 3629 FpABI = MipsABIFlagsSection::FpABIKind::S64; 3630 3631 return true; 3632 } 3633 3634 return false; 3635} 3636 3637bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 3638 MCAsmParser &Parser = getParser(); 3639 StringRef IDVal = DirectiveID.getString(); 3640 3641 if (IDVal == ".cpload") 3642 return parseDirectiveCpLoad(DirectiveID.getLoc()); 3643 if (IDVal == ".dword") { 3644 parseDataDirective(8, DirectiveID.getLoc()); 3645 return false; 3646 } 3647 if (IDVal == ".ent") { 3648 StringRef SymbolName; 3649 3650 if (Parser.parseIdentifier(SymbolName)) { 3651 reportParseError("expected identifier after .ent"); 3652 return false; 3653 } 3654 3655 // There's an undocumented extension that allows an integer to 3656 // follow the name of the procedure which AFAICS is ignored by GAS. 3657 // Example: .ent foo,2 3658 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3659 if (getLexer().isNot(AsmToken::Comma)) { 3660 // Even though we accept this undocumented extension for compatibility 3661 // reasons, the additional integer argument does not actually change 3662 // the behaviour of the '.ent' directive, so we would like to discourage 3663 // its use. We do this by not referring to the extended version in 3664 // error messages which are not directly related to its use. 3665 reportParseError("unexpected token, expected end of statement"); 3666 return false; 3667 } 3668 Parser.Lex(); // Eat the comma. 3669 const MCExpr *DummyNumber; 3670 int64_t DummyNumberVal; 3671 // If the user was explicitly trying to use the extended version, 3672 // we still give helpful extension-related error messages. 3673 if (Parser.parseExpression(DummyNumber)) { 3674 reportParseError("expected number after comma"); 3675 return false; 3676 } 3677 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) { 3678 reportParseError("expected an absolute expression after comma"); 3679 return false; 3680 } 3681 } 3682 3683 // If this is not the end of the statement, report an error. 3684 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3685 reportParseError("unexpected token, expected end of statement"); 3686 return false; 3687 } 3688 3689 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); 3690 3691 getTargetStreamer().emitDirectiveEnt(*Sym); 3692 CurrentFn = Sym; 3693 return false; 3694 } 3695 3696 if (IDVal == ".end") { 3697 StringRef SymbolName; 3698 3699 if (Parser.parseIdentifier(SymbolName)) { 3700 reportParseError("expected identifier after .end"); 3701 return false; 3702 } 3703 3704 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3705 reportParseError("unexpected token, expected end of statement"); 3706 return false; 3707 } 3708 3709 if (CurrentFn == nullptr) { 3710 reportParseError(".end used without .ent"); 3711 return false; 3712 } 3713 3714 if ((SymbolName != CurrentFn->getName())) { 3715 reportParseError(".end symbol does not match .ent symbol"); 3716 return false; 3717 } 3718 3719 getTargetStreamer().emitDirectiveEnd(SymbolName); 3720 CurrentFn = nullptr; 3721 return false; 3722 } 3723 3724 if (IDVal == ".frame") { 3725 // .frame $stack_reg, frame_size_in_bytes, $return_reg 3726 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 3727 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 3728 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 3729 reportParseError("expected stack register"); 3730 return false; 3731 } 3732 3733 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 3734 if (!StackRegOpnd.isGPRAsmReg()) { 3735 reportParseError(StackRegOpnd.getStartLoc(), 3736 "expected general purpose register"); 3737 return false; 3738 } 3739 unsigned StackReg = StackRegOpnd.getGPR32Reg(); 3740 3741 if (Parser.getTok().is(AsmToken::Comma)) 3742 Parser.Lex(); 3743 else { 3744 reportParseError("unexpected token, expected comma"); 3745 return false; 3746 } 3747 3748 // Parse the frame size. 3749 const MCExpr *FrameSize; 3750 int64_t FrameSizeVal; 3751 3752 if (Parser.parseExpression(FrameSize)) { 3753 reportParseError("expected frame size value"); 3754 return false; 3755 } 3756 3757 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) { 3758 reportParseError("frame size not an absolute expression"); 3759 return false; 3760 } 3761 3762 if (Parser.getTok().is(AsmToken::Comma)) 3763 Parser.Lex(); 3764 else { 3765 reportParseError("unexpected token, expected comma"); 3766 return false; 3767 } 3768 3769 // Parse the return register. 3770 TmpReg.clear(); 3771 ResTy = parseAnyRegister(TmpReg); 3772 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 3773 reportParseError("expected return register"); 3774 return false; 3775 } 3776 3777 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 3778 if (!ReturnRegOpnd.isGPRAsmReg()) { 3779 reportParseError(ReturnRegOpnd.getStartLoc(), 3780 "expected general purpose register"); 3781 return false; 3782 } 3783 3784 // If this is not the end of the statement, report an error. 3785 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3786 reportParseError("unexpected token, expected end of statement"); 3787 return false; 3788 } 3789 3790 getTargetStreamer().emitFrame(StackReg, FrameSizeVal, 3791 ReturnRegOpnd.getGPR32Reg()); 3792 return false; 3793 } 3794 3795 if (IDVal == ".set") { 3796 return parseDirectiveSet(); 3797 } 3798 3799 if (IDVal == ".mask" || IDVal == ".fmask") { 3800 // .mask bitmask, frame_offset 3801 // bitmask: One bit for each register used. 3802 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where 3803 // first register is expected to be saved. 3804 // Examples: 3805 // .mask 0x80000000, -4 3806 // .fmask 0x80000000, -4 3807 // 3808 3809 // Parse the bitmask 3810 const MCExpr *BitMask; 3811 int64_t BitMaskVal; 3812 3813 if (Parser.parseExpression(BitMask)) { 3814 reportParseError("expected bitmask value"); 3815 return false; 3816 } 3817 3818 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) { 3819 reportParseError("bitmask not an absolute expression"); 3820 return false; 3821 } 3822 3823 if (Parser.getTok().is(AsmToken::Comma)) 3824 Parser.Lex(); 3825 else { 3826 reportParseError("unexpected token, expected comma"); 3827 return false; 3828 } 3829 3830 // Parse the frame_offset 3831 const MCExpr *FrameOffset; 3832 int64_t FrameOffsetVal; 3833 3834 if (Parser.parseExpression(FrameOffset)) { 3835 reportParseError("expected frame offset value"); 3836 return false; 3837 } 3838 3839 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) { 3840 reportParseError("frame offset not an absolute expression"); 3841 return false; 3842 } 3843 3844 // If this is not the end of the statement, report an error. 3845 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3846 reportParseError("unexpected token, expected end of statement"); 3847 return false; 3848 } 3849 3850 if (IDVal == ".mask") 3851 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal); 3852 else 3853 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal); 3854 return false; 3855 } 3856 3857 if (IDVal == ".nan") 3858 return parseDirectiveNaN(); 3859 3860 if (IDVal == ".gpword") { 3861 parseDirectiveGpWord(); 3862 return false; 3863 } 3864 3865 if (IDVal == ".gpdword") { 3866 parseDirectiveGpDWord(); 3867 return false; 3868 } 3869 3870 if (IDVal == ".word") { 3871 parseDataDirective(4, DirectiveID.getLoc()); 3872 return false; 3873 } 3874 3875 if (IDVal == ".option") 3876 return parseDirectiveOption(); 3877 3878 if (IDVal == ".abicalls") { 3879 getTargetStreamer().emitDirectiveAbiCalls(); 3880 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 3881 Error(Parser.getTok().getLoc(), 3882 "unexpected token, expected end of statement"); 3883 // Clear line 3884 Parser.eatToEndOfStatement(); 3885 } 3886 return false; 3887 } 3888 3889 if (IDVal == ".cpsetup") 3890 return parseDirectiveCPSetup(); 3891 3892 if (IDVal == ".module") 3893 return parseDirectiveModule(); 3894 3895 return true; 3896} 3897 3898extern "C" void LLVMInitializeMipsAsmParser() { 3899 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 3900 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 3901 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 3902 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 3903} 3904 3905#define GET_REGISTER_MATCHER 3906#define GET_MATCHER_IMPLEMENTATION 3907#include "MipsGenAsmMatcher.inc" 3908