LLVM API Documentation
00001 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MCTargetDesc/MipsMCExpr.h" 00011 #include "MCTargetDesc/MipsMCTargetDesc.h" 00012 #include "MipsRegisterInfo.h" 00013 #include "MipsTargetStreamer.h" 00014 #include "llvm/ADT/APInt.h" 00015 #include "llvm/ADT/StringSwitch.h" 00016 #include "llvm/ADT/SmallVector.h" 00017 #include "llvm/MC/MCContext.h" 00018 #include "llvm/MC/MCExpr.h" 00019 #include "llvm/MC/MCInst.h" 00020 #include "llvm/MC/MCInstBuilder.h" 00021 #include "llvm/MC/MCParser/MCAsmLexer.h" 00022 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 00023 #include "llvm/MC/MCStreamer.h" 00024 #include "llvm/MC/MCSubtargetInfo.h" 00025 #include "llvm/MC/MCSymbol.h" 00026 #include "llvm/MC/MCTargetAsmParser.h" 00027 #include "llvm/Support/Debug.h" 00028 #include "llvm/Support/MathExtras.h" 00029 #include "llvm/Support/TargetRegistry.h" 00030 #include <memory> 00031 00032 using namespace llvm; 00033 00034 #define DEBUG_TYPE "mips-asm-parser" 00035 00036 namespace llvm { 00037 class MCInstrInfo; 00038 } 00039 00040 namespace { 00041 class MipsAssemblerOptions { 00042 public: 00043 MipsAssemblerOptions(uint64_t Features_) : 00044 ATReg(1), Reorder(true), Macro(true), Features(Features_) {} 00045 00046 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) { 00047 ATReg = Opts->getATRegNum(); 00048 Reorder = Opts->isReorder(); 00049 Macro = Opts->isMacro(); 00050 Features = Opts->getFeatures(); 00051 } 00052 00053 unsigned getATRegNum() const { return ATReg; } 00054 bool setATReg(unsigned Reg); 00055 00056 bool isReorder() const { return Reorder; } 00057 void setReorder() { Reorder = true; } 00058 void setNoReorder() { Reorder = false; } 00059 00060 bool isMacro() const { return Macro; } 00061 void setMacro() { Macro = true; } 00062 void setNoMacro() { Macro = false; } 00063 00064 uint64_t getFeatures() const { return Features; } 00065 void setFeatures(uint64_t Features_) { Features = Features_; } 00066 00067 // Set of features that are either architecture features or referenced 00068 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6). 00069 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]). 00070 // The reason we need this mask is explained in the selectArch function. 00071 // FIXME: Ideally we would like TableGen to generate this information. 00072 static const uint64_t AllArchRelatedMask = 00073 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 | 00074 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 | 00075 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 | 00076 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 | 00077 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 | 00078 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit | 00079 Mips::FeatureGP64Bit | Mips::FeatureNaN2008; 00080 00081 private: 00082 unsigned ATReg; 00083 bool Reorder; 00084 bool Macro; 00085 uint64_t Features; 00086 }; 00087 } 00088 00089 namespace { 00090 class MipsAsmParser : public MCTargetAsmParser { 00091 MipsTargetStreamer &getTargetStreamer() { 00092 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer(); 00093 return static_cast<MipsTargetStreamer &>(TS); 00094 } 00095 00096 MCSubtargetInfo &STI; 00097 MCAsmParser &Parser; 00098 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions; 00099 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a 00100 // nullptr, which indicates that no function is currently 00101 // selected. This usually happens after an '.end func' 00102 // directive. 00103 00104 #define GET_ASSEMBLER_HEADER 00105 #include "MipsGenAsmMatcher.inc" 00106 00107 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 00108 00109 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 00110 OperandVector &Operands, MCStreamer &Out, 00111 uint64_t &ErrorInfo, 00112 bool MatchingInlineAsm) override; 00113 00114 /// Parse a register as used in CFI directives 00115 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 00116 00117 bool parseParenSuffix(StringRef Name, OperandVector &Operands); 00118 00119 bool parseBracketSuffix(StringRef Name, OperandVector &Operands); 00120 00121 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 00122 SMLoc NameLoc, OperandVector &Operands) override; 00123 00124 bool ParseDirective(AsmToken DirectiveID) override; 00125 00126 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands); 00127 00128 MipsAsmParser::OperandMatchResultTy 00129 matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 00130 StringRef Identifier, SMLoc S); 00131 00132 MipsAsmParser::OperandMatchResultTy 00133 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S); 00134 00135 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands); 00136 00137 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands); 00138 00139 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands); 00140 00141 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands); 00142 00143 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands); 00144 00145 bool searchSymbolAlias(OperandVector &Operands); 00146 00147 bool parseOperand(OperandVector &, StringRef Mnemonic); 00148 00149 bool needsExpansion(MCInst &Inst); 00150 00151 // Expands assembly pseudo instructions. 00152 // Returns false on success, true otherwise. 00153 bool expandInstruction(MCInst &Inst, SMLoc IDLoc, 00154 SmallVectorImpl<MCInst> &Instructions); 00155 00156 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, 00157 SmallVectorImpl<MCInst> &Instructions); 00158 00159 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 00160 SmallVectorImpl<MCInst> &Instructions); 00161 00162 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 00163 SmallVectorImpl<MCInst> &Instructions); 00164 00165 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc, 00166 SmallVectorImpl<MCInst> &Instructions); 00167 00168 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 00169 SmallVectorImpl<MCInst> &Instructions, bool isLoad, 00170 bool isImmOpnd); 00171 bool reportParseError(Twine ErrorMsg); 00172 bool reportParseError(SMLoc Loc, Twine ErrorMsg); 00173 00174 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 00175 bool parseRelocOperand(const MCExpr *&Res); 00176 00177 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 00178 00179 bool isEvaluated(const MCExpr *Expr); 00180 bool parseSetMips0Directive(); 00181 bool parseSetArchDirective(); 00182 bool parseSetFeature(uint64_t Feature); 00183 bool parseDirectiveCPLoad(SMLoc Loc); 00184 bool parseDirectiveCPSetup(); 00185 bool parseDirectiveNaN(); 00186 bool parseDirectiveSet(); 00187 bool parseDirectiveOption(); 00188 00189 bool parseSetAtDirective(); 00190 bool parseSetNoAtDirective(); 00191 bool parseSetMacroDirective(); 00192 bool parseSetNoMacroDirective(); 00193 bool parseSetMsaDirective(); 00194 bool parseSetNoMsaDirective(); 00195 bool parseSetNoDspDirective(); 00196 bool parseSetReorderDirective(); 00197 bool parseSetNoReorderDirective(); 00198 bool parseSetNoMips16Directive(); 00199 bool parseSetFpDirective(); 00200 bool parseSetPopDirective(); 00201 bool parseSetPushDirective(); 00202 00203 bool parseSetAssignment(); 00204 00205 bool parseDataDirective(unsigned Size, SMLoc L); 00206 bool parseDirectiveGpWord(); 00207 bool parseDirectiveGpDWord(); 00208 bool parseDirectiveModule(); 00209 bool parseDirectiveModuleFP(); 00210 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 00211 StringRef Directive); 00212 00213 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 00214 00215 bool eatComma(StringRef ErrorStr); 00216 00217 int matchCPURegisterName(StringRef Symbol); 00218 00219 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 00220 00221 int matchFPURegisterName(StringRef Name); 00222 00223 int matchFCCRegisterName(StringRef Name); 00224 00225 int matchACRegisterName(StringRef Name); 00226 00227 int matchMSA128RegisterName(StringRef Name); 00228 00229 int matchMSA128CtrlRegisterName(StringRef Name); 00230 00231 unsigned getReg(int RC, int RegNo); 00232 00233 unsigned getGPR(int RegNo); 00234 00235 int getATReg(SMLoc Loc); 00236 00237 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 00238 SmallVectorImpl<MCInst> &Instructions); 00239 00240 // Helper function that checks if the value of a vector index is within the 00241 // boundaries of accepted values for each RegisterKind 00242 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 00243 bool validateMSAIndex(int Val, int RegKind); 00244 00245 // Selects a new architecture by updating the FeatureBits with the necessary 00246 // info including implied dependencies. 00247 // Internally, it clears all the feature bits related to *any* architecture 00248 // and selects the new one using the ToggleFeature functionality of the 00249 // MCSubtargetInfo object that handles implied dependencies. The reason we 00250 // clear all the arch related bits manually is because ToggleFeature only 00251 // clears the features that imply the feature being cleared and not the 00252 // features implied by the feature being cleared. This is easier to see 00253 // with an example: 00254 // -------------------------------------------------- 00255 // | Feature | Implies | 00256 // | -------------------------------------------------| 00257 // | FeatureMips1 | None | 00258 // | FeatureMips2 | FeatureMips1 | 00259 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 | 00260 // | FeatureMips4 | FeatureMips3 | 00261 // | ... | | 00262 // -------------------------------------------------- 00263 // 00264 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 | 00265 // FeatureMipsGP64 | FeatureMips1) 00266 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4). 00267 void selectArch(StringRef ArchFeature) { 00268 uint64_t FeatureBits = STI.getFeatureBits(); 00269 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask; 00270 STI.setFeatureBits(FeatureBits); 00271 setAvailableFeatures( 00272 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature))); 00273 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 00274 } 00275 00276 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 00277 if (!(STI.getFeatureBits() & Feature)) { 00278 setAvailableFeatures( 00279 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 00280 } 00281 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 00282 } 00283 00284 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 00285 if (STI.getFeatureBits() & Feature) { 00286 setAvailableFeatures( 00287 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 00288 } 00289 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 00290 } 00291 00292 public: 00293 enum MipsMatchResultTy { 00294 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY 00295 #define GET_OPERAND_DIAGNOSTIC_TYPES 00296 #include "MipsGenAsmMatcher.inc" 00297 #undef GET_OPERAND_DIAGNOSTIC_TYPES 00298 00299 }; 00300 00301 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 00302 const MCInstrInfo &MII, const MCTargetOptions &Options) 00303 : MCTargetAsmParser(), STI(sti), Parser(parser) { 00304 // Initialize the set of available features. 00305 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 00306 00307 // Remember the initial assembler options. The user can not modify these. 00308 AssemblerOptions.push_back( 00309 make_unique<MipsAssemblerOptions>(getAvailableFeatures())); 00310 00311 // Create an assembler options environment for the user to modify. 00312 AssemblerOptions.push_back( 00313 make_unique<MipsAssemblerOptions>(getAvailableFeatures())); 00314 00315 getTargetStreamer().updateABIInfo(*this); 00316 00317 // Assert exactly one ABI was chosen. 00318 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + 00319 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + 00320 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + 00321 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); 00322 00323 if (!isABI_O32() && !useOddSPReg() != 0) 00324 report_fatal_error("-mno-odd-spreg requires the O32 ABI"); 00325 00326 CurrentFn = nullptr; 00327 } 00328 00329 MCAsmParser &getParser() const { return Parser; } 00330 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 00331 00332 /// True if all of $fcc0 - $fcc7 exist for the current ISA. 00333 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); } 00334 00335 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } 00336 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; } 00337 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; } 00338 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 00339 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; } 00340 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; } 00341 00342 bool useOddSPReg() const { 00343 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg); 00344 } 00345 00346 bool inMicroMipsMode() const { 00347 return STI.getFeatureBits() & Mips::FeatureMicroMips; 00348 } 00349 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; } 00350 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; } 00351 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } 00352 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; } 00353 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; } 00354 bool hasMips32() const { 00355 return (STI.getFeatureBits() & Mips::FeatureMips32); 00356 } 00357 bool hasMips64() const { 00358 return (STI.getFeatureBits() & Mips::FeatureMips64); 00359 } 00360 bool hasMips32r2() const { 00361 return (STI.getFeatureBits() & Mips::FeatureMips32r2); 00362 } 00363 bool hasMips64r2() const { 00364 return (STI.getFeatureBits() & Mips::FeatureMips64r2); 00365 } 00366 bool hasMips32r6() const { 00367 return (STI.getFeatureBits() & Mips::FeatureMips32r6); 00368 } 00369 bool hasMips64r6() const { 00370 return (STI.getFeatureBits() & Mips::FeatureMips64r6); 00371 } 00372 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); } 00373 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); } 00374 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); } 00375 00376 bool inMips16Mode() const { 00377 return STI.getFeatureBits() & Mips::FeatureMips16; 00378 } 00379 // TODO: see how can we get this info. 00380 bool abiUsesSoftFloat() const { return false; } 00381 00382 /// Warn if RegNo is the current assembler temporary. 00383 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc); 00384 }; 00385 } 00386 00387 namespace { 00388 00389 /// MipsOperand - Instances of this class represent a parsed Mips machine 00390 /// instruction. 00391 class MipsOperand : public MCParsedAsmOperand { 00392 public: 00393 /// Broad categories of register classes 00394 /// The exact class is finalized by the render method. 00395 enum RegKind { 00396 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit()) 00397 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 00398 /// isFP64bit()) 00399 RegKind_FCC = 4, /// FCC 00400 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 00401 RegKind_MSACtrl = 16, /// MSA control registers 00402 RegKind_COP2 = 32, /// COP2 00403 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 00404 /// context). 00405 RegKind_CCR = 128, /// CCR 00406 RegKind_HWRegs = 256, /// HWRegs 00407 RegKind_COP3 = 512, /// COP3 00408 00409 /// Potentially any (e.g. $1) 00410 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 00411 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 00412 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 00413 }; 00414 00415 private: 00416 enum KindTy { 00417 k_Immediate, /// An immediate (possibly involving symbol references) 00418 k_Memory, /// Base + Offset Memory Address 00419 k_PhysRegister, /// A physical register from the Mips namespace 00420 k_RegisterIndex, /// A register index in one or more RegKind. 00421 k_Token /// A simple token 00422 } Kind; 00423 00424 public: 00425 MipsOperand(KindTy K, MipsAsmParser &Parser) 00426 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 00427 00428 private: 00429 /// For diagnostics, and checking the assembler temporary 00430 MipsAsmParser &AsmParser; 00431 00432 struct Token { 00433 const char *Data; 00434 unsigned Length; 00435 }; 00436 00437 struct PhysRegOp { 00438 unsigned Num; /// Register Number 00439 }; 00440 00441 struct RegIdxOp { 00442 unsigned Index; /// Index into the register class 00443 RegKind Kind; /// Bitfield of the kinds it could possibly be 00444 const MCRegisterInfo *RegInfo; 00445 }; 00446 00447 struct ImmOp { 00448 const MCExpr *Val; 00449 }; 00450 00451 struct MemOp { 00452 MipsOperand *Base; 00453 const MCExpr *Off; 00454 }; 00455 00456 union { 00457 struct Token Tok; 00458 struct PhysRegOp PhysReg; 00459 struct RegIdxOp RegIdx; 00460 struct ImmOp Imm; 00461 struct MemOp Mem; 00462 }; 00463 00464 SMLoc StartLoc, EndLoc; 00465 00466 /// Internal constructor for register kinds 00467 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind, 00468 const MCRegisterInfo *RegInfo, 00469 SMLoc S, SMLoc E, 00470 MipsAsmParser &Parser) { 00471 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser); 00472 Op->RegIdx.Index = Index; 00473 Op->RegIdx.RegInfo = RegInfo; 00474 Op->RegIdx.Kind = RegKind; 00475 Op->StartLoc = S; 00476 Op->EndLoc = E; 00477 return Op; 00478 } 00479 00480 public: 00481 /// Coerce the register to GPR32 and return the real register for the current 00482 /// target. 00483 unsigned getGPR32Reg() const { 00484 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 00485 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc); 00486 unsigned ClassID = Mips::GPR32RegClassID; 00487 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00488 } 00489 00490 /// Coerce the register to GPR64 and return the real register for the current 00491 /// target. 00492 unsigned getGPR64Reg() const { 00493 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 00494 unsigned ClassID = Mips::GPR64RegClassID; 00495 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00496 } 00497 00498 private: 00499 /// Coerce the register to AFGR64 and return the real register for the current 00500 /// target. 00501 unsigned getAFGR64Reg() const { 00502 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 00503 if (RegIdx.Index % 2 != 0) 00504 AsmParser.Warning(StartLoc, "Float register should be even."); 00505 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 00506 .getRegister(RegIdx.Index / 2); 00507 } 00508 00509 /// Coerce the register to FGR64 and return the real register for the current 00510 /// target. 00511 unsigned getFGR64Reg() const { 00512 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 00513 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 00514 .getRegister(RegIdx.Index); 00515 } 00516 00517 /// Coerce the register to FGR32 and return the real register for the current 00518 /// target. 00519 unsigned getFGR32Reg() const { 00520 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 00521 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 00522 .getRegister(RegIdx.Index); 00523 } 00524 00525 /// Coerce the register to FGRH32 and return the real register for the current 00526 /// target. 00527 unsigned getFGRH32Reg() const { 00528 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 00529 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 00530 .getRegister(RegIdx.Index); 00531 } 00532 00533 /// Coerce the register to FCC and return the real register for the current 00534 /// target. 00535 unsigned getFCCReg() const { 00536 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 00537 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 00538 .getRegister(RegIdx.Index); 00539 } 00540 00541 /// Coerce the register to MSA128 and return the real register for the current 00542 /// target. 00543 unsigned getMSA128Reg() const { 00544 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 00545 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 00546 // identical 00547 unsigned ClassID = Mips::MSA128BRegClassID; 00548 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00549 } 00550 00551 /// Coerce the register to MSACtrl and return the real register for the 00552 /// current target. 00553 unsigned getMSACtrlReg() const { 00554 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 00555 unsigned ClassID = Mips::MSACtrlRegClassID; 00556 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00557 } 00558 00559 /// Coerce the register to COP2 and return the real register for the 00560 /// current target. 00561 unsigned getCOP2Reg() const { 00562 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 00563 unsigned ClassID = Mips::COP2RegClassID; 00564 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00565 } 00566 00567 /// Coerce the register to COP3 and return the real register for the 00568 /// current target. 00569 unsigned getCOP3Reg() const { 00570 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); 00571 unsigned ClassID = Mips::COP3RegClassID; 00572 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00573 } 00574 00575 /// Coerce the register to ACC64DSP and return the real register for the 00576 /// current target. 00577 unsigned getACC64DSPReg() const { 00578 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 00579 unsigned ClassID = Mips::ACC64DSPRegClassID; 00580 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00581 } 00582 00583 /// Coerce the register to HI32DSP and return the real register for the 00584 /// current target. 00585 unsigned getHI32DSPReg() const { 00586 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 00587 unsigned ClassID = Mips::HI32DSPRegClassID; 00588 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00589 } 00590 00591 /// Coerce the register to LO32DSP and return the real register for the 00592 /// current target. 00593 unsigned getLO32DSPReg() const { 00594 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 00595 unsigned ClassID = Mips::LO32DSPRegClassID; 00596 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00597 } 00598 00599 /// Coerce the register to CCR and return the real register for the 00600 /// current target. 00601 unsigned getCCRReg() const { 00602 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 00603 unsigned ClassID = Mips::CCRRegClassID; 00604 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00605 } 00606 00607 /// Coerce the register to HWRegs and return the real register for the 00608 /// current target. 00609 unsigned getHWRegsReg() const { 00610 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 00611 unsigned ClassID = Mips::HWRegsRegClassID; 00612 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 00613 } 00614 00615 public: 00616 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 00617 // Add as immediate when possible. Null MCExpr = 0. 00618 if (!Expr) 00619 Inst.addOperand(MCOperand::CreateImm(0)); 00620 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 00621 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 00622 else 00623 Inst.addOperand(MCOperand::CreateExpr(Expr)); 00624 } 00625 00626 void addRegOperands(MCInst &Inst, unsigned N) const { 00627 llvm_unreachable("Use a custom parser instead"); 00628 } 00629 00630 /// Render the operand to an MCInst as a GPR32 00631 /// Asserts if the wrong number of operands are requested, or the operand 00632 /// is not a k_RegisterIndex compatible with RegKind_GPR 00633 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 00634 assert(N == 1 && "Invalid number of operands!"); 00635 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); 00636 } 00637 00638 /// Render the operand to an MCInst as a GPR64 00639 /// Asserts if the wrong number of operands are requested, or the operand 00640 /// is not a k_RegisterIndex compatible with RegKind_GPR 00641 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 00642 assert(N == 1 && "Invalid number of operands!"); 00643 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); 00644 } 00645 00646 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 00647 assert(N == 1 && "Invalid number of operands!"); 00648 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); 00649 } 00650 00651 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 00652 assert(N == 1 && "Invalid number of operands!"); 00653 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); 00654 } 00655 00656 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 00657 assert(N == 1 && "Invalid number of operands!"); 00658 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); 00659 // FIXME: We ought to do this for -integrated-as without -via-file-asm too. 00660 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1) 00661 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU " 00662 "registers"); 00663 } 00664 00665 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 00666 assert(N == 1 && "Invalid number of operands!"); 00667 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); 00668 } 00669 00670 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 00671 assert(N == 1 && "Invalid number of operands!"); 00672 Inst.addOperand(MCOperand::CreateReg(getFCCReg())); 00673 } 00674 00675 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 00676 assert(N == 1 && "Invalid number of operands!"); 00677 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); 00678 } 00679 00680 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 00681 assert(N == 1 && "Invalid number of operands!"); 00682 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); 00683 } 00684 00685 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 00686 assert(N == 1 && "Invalid number of operands!"); 00687 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); 00688 } 00689 00690 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { 00691 assert(N == 1 && "Invalid number of operands!"); 00692 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg())); 00693 } 00694 00695 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 00696 assert(N == 1 && "Invalid number of operands!"); 00697 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); 00698 } 00699 00700 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 00701 assert(N == 1 && "Invalid number of operands!"); 00702 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); 00703 } 00704 00705 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 00706 assert(N == 1 && "Invalid number of operands!"); 00707 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); 00708 } 00709 00710 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 00711 assert(N == 1 && "Invalid number of operands!"); 00712 Inst.addOperand(MCOperand::CreateReg(getCCRReg())); 00713 } 00714 00715 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 00716 assert(N == 1 && "Invalid number of operands!"); 00717 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); 00718 } 00719 00720 void addImmOperands(MCInst &Inst, unsigned N) const { 00721 assert(N == 1 && "Invalid number of operands!"); 00722 const MCExpr *Expr = getImm(); 00723 addExpr(Inst, Expr); 00724 } 00725 00726 void addMemOperands(MCInst &Inst, unsigned N) const { 00727 assert(N == 2 && "Invalid number of operands!"); 00728 00729 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); 00730 00731 const MCExpr *Expr = getMemOff(); 00732 addExpr(Inst, Expr); 00733 } 00734 00735 bool isReg() const override { 00736 // As a special case until we sort out the definition of div/divu, pretend 00737 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 00738 if (isGPRAsmReg() && RegIdx.Index == 0) 00739 return true; 00740 00741 return Kind == k_PhysRegister; 00742 } 00743 bool isRegIdx() const { return Kind == k_RegisterIndex; } 00744 bool isImm() const override { return Kind == k_Immediate; } 00745 bool isConstantImm() const { 00746 return isImm() && dyn_cast<MCConstantExpr>(getImm()); 00747 } 00748 bool isToken() const override { 00749 // Note: It's not possible to pretend that other operand kinds are tokens. 00750 // The matcher emitter checks tokens first. 00751 return Kind == k_Token; 00752 } 00753 bool isMem() const override { return Kind == k_Memory; } 00754 bool isConstantMemOff() const { 00755 return isMem() && dyn_cast<MCConstantExpr>(getMemOff()); 00756 } 00757 template <unsigned Bits> bool isMemWithSimmOffset() const { 00758 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()); 00759 } 00760 bool isInvNum() const { return Kind == k_Immediate; } 00761 bool isLSAImm() const { 00762 if (!isConstantImm()) 00763 return false; 00764 int64_t Val = getConstantImm(); 00765 return 1 <= Val && Val <= 4; 00766 } 00767 00768 StringRef getToken() const { 00769 assert(Kind == k_Token && "Invalid access!"); 00770 return StringRef(Tok.Data, Tok.Length); 00771 } 00772 00773 unsigned getReg() const override { 00774 // As a special case until we sort out the definition of div/divu, pretend 00775 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 00776 if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 00777 RegIdx.Kind & RegKind_GPR) 00778 return getGPR32Reg(); // FIXME: GPR64 too 00779 00780 assert(Kind == k_PhysRegister && "Invalid access!"); 00781 return PhysReg.Num; 00782 } 00783 00784 const MCExpr *getImm() const { 00785 assert((Kind == k_Immediate) && "Invalid access!"); 00786 return Imm.Val; 00787 } 00788 00789 int64_t getConstantImm() const { 00790 const MCExpr *Val = getImm(); 00791 return static_cast<const MCConstantExpr *>(Val)->getValue(); 00792 } 00793 00794 MipsOperand *getMemBase() const { 00795 assert((Kind == k_Memory) && "Invalid access!"); 00796 return Mem.Base; 00797 } 00798 00799 const MCExpr *getMemOff() const { 00800 assert((Kind == k_Memory) && "Invalid access!"); 00801 return Mem.Off; 00802 } 00803 00804 int64_t getConstantMemOff() const { 00805 return static_cast<const MCConstantExpr *>(getMemOff())->getValue(); 00806 } 00807 00808 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, 00809 MipsAsmParser &Parser) { 00810 auto Op = make_unique<MipsOperand>(k_Token, Parser); 00811 Op->Tok.Data = Str.data(); 00812 Op->Tok.Length = Str.size(); 00813 Op->StartLoc = S; 00814 Op->EndLoc = S; 00815 return Op; 00816 } 00817 00818 /// Create a numeric register (e.g. $1). The exact register remains 00819 /// unresolved until an instruction successfully matches 00820 static std::unique_ptr<MipsOperand> 00821 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 00822 SMLoc E, MipsAsmParser &Parser) { 00823 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n"); 00824 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 00825 } 00826 00827 /// Create a register that is definitely a GPR. 00828 /// This is typically only used for named registers such as $gp. 00829 static std::unique_ptr<MipsOperand> 00830 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 00831 MipsAsmParser &Parser) { 00832 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 00833 } 00834 00835 /// Create a register that is definitely a FGR. 00836 /// This is typically only used for named registers such as $f0. 00837 static std::unique_ptr<MipsOperand> 00838 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 00839 MipsAsmParser &Parser) { 00840 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 00841 } 00842 00843 /// Create a register that is definitely an FCC. 00844 /// This is typically only used for named registers such as $fcc0. 00845 static std::unique_ptr<MipsOperand> 00846 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 00847 MipsAsmParser &Parser) { 00848 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 00849 } 00850 00851 /// Create a register that is definitely an ACC. 00852 /// This is typically only used for named registers such as $ac0. 00853 static std::unique_ptr<MipsOperand> 00854 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 00855 MipsAsmParser &Parser) { 00856 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 00857 } 00858 00859 /// Create a register that is definitely an MSA128. 00860 /// This is typically only used for named registers such as $w0. 00861 static std::unique_ptr<MipsOperand> 00862 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 00863 SMLoc E, MipsAsmParser &Parser) { 00864 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 00865 } 00866 00867 /// Create a register that is definitely an MSACtrl. 00868 /// This is typically only used for named registers such as $msaaccess. 00869 static std::unique_ptr<MipsOperand> 00870 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 00871 SMLoc E, MipsAsmParser &Parser) { 00872 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 00873 } 00874 00875 static std::unique_ptr<MipsOperand> 00876 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { 00877 auto Op = make_unique<MipsOperand>(k_Immediate, Parser); 00878 Op->Imm.Val = Val; 00879 Op->StartLoc = S; 00880 Op->EndLoc = E; 00881 return Op; 00882 } 00883 00884 static std::unique_ptr<MipsOperand> 00885 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S, 00886 SMLoc E, MipsAsmParser &Parser) { 00887 auto Op = make_unique<MipsOperand>(k_Memory, Parser); 00888 Op->Mem.Base = Base.release(); 00889 Op->Mem.Off = Off; 00890 Op->StartLoc = S; 00891 Op->EndLoc = E; 00892 return Op; 00893 } 00894 00895 bool isGPRAsmReg() const { 00896 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 00897 } 00898 bool isFGRAsmReg() const { 00899 // AFGR64 is $0-$15 but we handle this in getAFGR64() 00900 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 00901 } 00902 bool isHWRegsAsmReg() const { 00903 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 00904 } 00905 bool isCCRAsmReg() const { 00906 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 00907 } 00908 bool isFCCAsmReg() const { 00909 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) 00910 return false; 00911 if (!AsmParser.hasEightFccRegisters()) 00912 return RegIdx.Index == 0; 00913 return RegIdx.Index <= 7; 00914 } 00915 bool isACCAsmReg() const { 00916 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 00917 } 00918 bool isCOP2AsmReg() const { 00919 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 00920 } 00921 bool isCOP3AsmReg() const { 00922 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; 00923 } 00924 bool isMSA128AsmReg() const { 00925 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 00926 } 00927 bool isMSACtrlAsmReg() const { 00928 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 00929 } 00930 00931 /// getStartLoc - Get the location of the first token of this operand. 00932 SMLoc getStartLoc() const override { return StartLoc; } 00933 /// getEndLoc - Get the location of the last token of this operand. 00934 SMLoc getEndLoc() const override { return EndLoc; } 00935 00936 virtual ~MipsOperand() { 00937 switch (Kind) { 00938 case k_Immediate: 00939 break; 00940 case k_Memory: 00941 delete Mem.Base; 00942 break; 00943 case k_PhysRegister: 00944 case k_RegisterIndex: 00945 case k_Token: 00946 break; 00947 } 00948 } 00949 00950 void print(raw_ostream &OS) const override { 00951 switch (Kind) { 00952 case k_Immediate: 00953 OS << "Imm<"; 00954 Imm.Val->print(OS); 00955 OS << ">"; 00956 break; 00957 case k_Memory: 00958 OS << "Mem<"; 00959 Mem.Base->print(OS); 00960 OS << ", "; 00961 Mem.Off->print(OS); 00962 OS << ">"; 00963 break; 00964 case k_PhysRegister: 00965 OS << "PhysReg<" << PhysReg.Num << ">"; 00966 break; 00967 case k_RegisterIndex: 00968 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 00969 break; 00970 case k_Token: 00971 OS << Tok.Data; 00972 break; 00973 } 00974 } 00975 }; // class MipsOperand 00976 } // namespace 00977 00978 namespace llvm { 00979 extern const MCInstrDesc MipsInsts[]; 00980 } 00981 static const MCInstrDesc &getInstDesc(unsigned Opcode) { 00982 return MipsInsts[Opcode]; 00983 } 00984 00985 static bool hasShortDelaySlot(unsigned Opcode) { 00986 switch (Opcode) { 00987 case Mips::JALS_MM: 00988 case Mips::JALRS_MM: 00989 case Mips::BGEZALS_MM: 00990 case Mips::BLTZALS_MM: 00991 return true; 00992 default: 00993 return false; 00994 } 00995 } 00996 00997 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 00998 SmallVectorImpl<MCInst> &Instructions) { 00999 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 01000 01001 Inst.setLoc(IDLoc); 01002 01003 if (MCID.isBranch() || MCID.isCall()) { 01004 const unsigned Opcode = Inst.getOpcode(); 01005 MCOperand Offset; 01006 01007 switch (Opcode) { 01008 default: 01009 break; 01010 case Mips::BEQ: 01011 case Mips::BNE: 01012 case Mips::BEQ_MM: 01013 case Mips::BNE_MM: 01014 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 01015 Offset = Inst.getOperand(2); 01016 if (!Offset.isImm()) 01017 break; // We'll deal with this situation later on when applying fixups. 01018 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 01019 return Error(IDLoc, "branch target out of range"); 01020 if (OffsetToAlignment(Offset.getImm(), 01021 1LL << (inMicroMipsMode() ? 1 : 2))) 01022 return Error(IDLoc, "branch to misaligned address"); 01023 break; 01024 case Mips::BGEZ: 01025 case Mips::BGTZ: 01026 case Mips::BLEZ: 01027 case Mips::BLTZ: 01028 case Mips::BGEZAL: 01029 case Mips::BLTZAL: 01030 case Mips::BC1F: 01031 case Mips::BC1T: 01032 case Mips::BGEZ_MM: 01033 case Mips::BGTZ_MM: 01034 case Mips::BLEZ_MM: 01035 case Mips::BLTZ_MM: 01036 case Mips::BGEZAL_MM: 01037 case Mips::BLTZAL_MM: 01038 case Mips::BC1F_MM: 01039 case Mips::BC1T_MM: 01040 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 01041 Offset = Inst.getOperand(1); 01042 if (!Offset.isImm()) 01043 break; // We'll deal with this situation later on when applying fixups. 01044 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 01045 return Error(IDLoc, "branch target out of range"); 01046 if (OffsetToAlignment(Offset.getImm(), 01047 1LL << (inMicroMipsMode() ? 1 : 2))) 01048 return Error(IDLoc, "branch to misaligned address"); 01049 break; 01050 } 01051 } 01052 01053 // SSNOP is deprecated on MIPS32r6/MIPS64r6 01054 // We still accept it but it is a normal nop. 01055 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) { 01056 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6"; 01057 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a " 01058 "nop instruction"); 01059 } 01060 01061 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) { 01062 // If this instruction has a delay slot and .set reorder is active, 01063 // emit a NOP after it. 01064 Instructions.push_back(Inst); 01065 MCInst NopInst; 01066 if (hasShortDelaySlot(Inst.getOpcode())) { 01067 NopInst.setOpcode(Mips::MOVE16_MM); 01068 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 01069 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 01070 } else { 01071 NopInst.setOpcode(Mips::SLL); 01072 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 01073 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 01074 NopInst.addOperand(MCOperand::CreateImm(0)); 01075 } 01076 Instructions.push_back(NopInst); 01077 return false; 01078 } 01079 01080 if (MCID.mayLoad() || MCID.mayStore()) { 01081 // Check the offset of memory operand, if it is a symbol 01082 // reference or immediate we may have to expand instructions. 01083 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 01084 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 01085 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 01086 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 01087 MCOperand &Op = Inst.getOperand(i); 01088 if (Op.isImm()) { 01089 int MemOffset = Op.getImm(); 01090 if (MemOffset < -32768 || MemOffset > 32767) { 01091 // Offset can't exceed 16bit value. 01092 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 01093 return false; 01094 } 01095 } else if (Op.isExpr()) { 01096 const MCExpr *Expr = Op.getExpr(); 01097 if (Expr->getKind() == MCExpr::SymbolRef) { 01098 const MCSymbolRefExpr *SR = 01099 static_cast<const MCSymbolRefExpr *>(Expr); 01100 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 01101 // Expand symbol. 01102 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 01103 return false; 01104 } 01105 } else if (!isEvaluated(Expr)) { 01106 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 01107 return false; 01108 } 01109 } 01110 } 01111 } // for 01112 } // if load/store 01113 01114 if (needsExpansion(Inst)) 01115 return expandInstruction(Inst, IDLoc, Instructions); 01116 else 01117 Instructions.push_back(Inst); 01118 01119 return false; 01120 } 01121 01122 bool MipsAsmParser::needsExpansion(MCInst &Inst) { 01123 01124 switch (Inst.getOpcode()) { 01125 case Mips::LoadImm32Reg: 01126 case Mips::LoadAddr32Imm: 01127 case Mips::LoadAddr32Reg: 01128 case Mips::LoadImm64Reg: 01129 return true; 01130 default: 01131 return false; 01132 } 01133 } 01134 01135 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 01136 SmallVectorImpl<MCInst> &Instructions) { 01137 switch (Inst.getOpcode()) { 01138 default: 01139 assert(0 && "unimplemented expansion"); 01140 return true; 01141 case Mips::LoadImm32Reg: 01142 return expandLoadImm(Inst, IDLoc, Instructions); 01143 case Mips::LoadImm64Reg: 01144 if (!isGP64bit()) { 01145 Error(IDLoc, "instruction requires a 64-bit architecture"); 01146 return true; 01147 } 01148 return expandLoadImm(Inst, IDLoc, Instructions); 01149 case Mips::LoadAddr32Imm: 01150 return expandLoadAddressImm(Inst, IDLoc, Instructions); 01151 case Mips::LoadAddr32Reg: 01152 return expandLoadAddressReg(Inst, IDLoc, Instructions); 01153 } 01154 } 01155 01156 namespace { 01157 template <bool PerformShift> 01158 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc, 01159 SmallVectorImpl<MCInst> &Instructions) { 01160 MCInst tmpInst; 01161 if (PerformShift) { 01162 tmpInst.setOpcode(Mips::DSLL); 01163 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 01164 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 01165 tmpInst.addOperand(MCOperand::CreateImm(16)); 01166 tmpInst.setLoc(IDLoc); 01167 Instructions.push_back(tmpInst); 01168 tmpInst.clear(); 01169 } 01170 tmpInst.setOpcode(Mips::ORi); 01171 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 01172 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 01173 tmpInst.addOperand(Operand); 01174 tmpInst.setLoc(IDLoc); 01175 Instructions.push_back(tmpInst); 01176 } 01177 01178 template <int Shift, bool PerformShift> 01179 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc, 01180 SmallVectorImpl<MCInst> &Instructions) { 01181 createShiftOr<PerformShift>( 01182 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo, 01183 IDLoc, Instructions); 01184 } 01185 } 01186 01187 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 01188 SmallVectorImpl<MCInst> &Instructions) { 01189 MCInst tmpInst; 01190 const MCOperand &ImmOp = Inst.getOperand(1); 01191 assert(ImmOp.isImm() && "expected immediate operand kind"); 01192 const MCOperand &RegOp = Inst.getOperand(0); 01193 assert(RegOp.isReg() && "expected register operand kind"); 01194 01195 int64_t ImmValue = ImmOp.getImm(); 01196 tmpInst.setLoc(IDLoc); 01197 // FIXME: gas has a special case for values that are 000...1111, which 01198 // becomes a li -1 and then a dsrl 01199 if (0 <= ImmValue && ImmValue <= 65535) { 01200 // For 0 <= j <= 65535. 01201 // li d,j => ori d,$zero,j 01202 tmpInst.setOpcode(Mips::ORi); 01203 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01204 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 01205 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 01206 Instructions.push_back(tmpInst); 01207 } else if (ImmValue < 0 && ImmValue >= -32768) { 01208 // For -32768 <= j < 0. 01209 // li d,j => addiu d,$zero,j 01210 tmpInst.setOpcode(Mips::ADDiu); 01211 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01212 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 01213 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 01214 Instructions.push_back(tmpInst); 01215 } else if ((ImmValue & 0xffffffff) == ImmValue) { 01216 // For any value of j that is representable as a 32-bit integer, create 01217 // a sequence of: 01218 // li d,j => lui d,hi16(j) 01219 // ori d,d,lo16(j) 01220 tmpInst.setOpcode(Mips::LUi); 01221 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01222 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 01223 Instructions.push_back(tmpInst); 01224 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 01225 } else if ((ImmValue & (0xffffLL << 48)) == 0) { 01226 if (!isGP64bit()) { 01227 Error(IDLoc, "instruction requires a 64-bit architecture"); 01228 return true; 01229 } 01230 01231 // <------- lo32 ------> 01232 // <------- hi32 ------> 01233 // <- hi16 -> <- lo16 -> 01234 // _________________________________ 01235 // | | | | 01236 // | 16-bytes | 16-bytes | 16-bytes | 01237 // |__________|__________|__________| 01238 // 01239 // For any value of j that is representable as a 48-bit integer, create 01240 // a sequence of: 01241 // li d,j => lui d,hi16(j) 01242 // ori d,d,hi16(lo32(j)) 01243 // dsll d,d,16 01244 // ori d,d,lo16(lo32(j)) 01245 tmpInst.setOpcode(Mips::LUi); 01246 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01247 tmpInst.addOperand( 01248 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32)); 01249 Instructions.push_back(tmpInst); 01250 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 01251 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 01252 } else { 01253 if (!isGP64bit()) { 01254 Error(IDLoc, "instruction requires a 64-bit architecture"); 01255 return true; 01256 } 01257 01258 // <------- hi32 ------> <------- lo32 ------> 01259 // <- hi16 -> <- lo16 -> 01260 // ___________________________________________ 01261 // | | | | | 01262 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes | 01263 // |__________|__________|__________|__________| 01264 // 01265 // For any value of j that isn't representable as a 48-bit integer. 01266 // li d,j => lui d,hi16(j) 01267 // ori d,d,lo16(hi32(j)) 01268 // dsll d,d,16 01269 // ori d,d,hi16(lo32(j)) 01270 // dsll d,d,16 01271 // ori d,d,lo16(lo32(j)) 01272 tmpInst.setOpcode(Mips::LUi); 01273 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01274 tmpInst.addOperand( 01275 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48)); 01276 Instructions.push_back(tmpInst); 01277 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 01278 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 01279 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 01280 } 01281 return false; 01282 } 01283 01284 bool 01285 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 01286 SmallVectorImpl<MCInst> &Instructions) { 01287 MCInst tmpInst; 01288 const MCOperand &ImmOp = Inst.getOperand(2); 01289 assert((ImmOp.isImm() || ImmOp.isExpr()) && 01290 "expected immediate operand kind"); 01291 if (!ImmOp.isImm()) { 01292 expandLoadAddressSym(Inst, IDLoc, Instructions); 01293 return false; 01294 } 01295 const MCOperand &SrcRegOp = Inst.getOperand(1); 01296 assert(SrcRegOp.isReg() && "expected register operand kind"); 01297 const MCOperand &DstRegOp = Inst.getOperand(0); 01298 assert(DstRegOp.isReg() && "expected register operand kind"); 01299 int ImmValue = ImmOp.getImm(); 01300 if (-32768 <= ImmValue && ImmValue <= 65535) { 01301 // For -32768 <= j <= 65535. 01302 // la d,j(s) => addiu d,s,j 01303 tmpInst.setOpcode(Mips::ADDiu); 01304 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 01305 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 01306 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 01307 Instructions.push_back(tmpInst); 01308 } else { 01309 // For any other value of j that is representable as a 32-bit integer. 01310 // la d,j(s) => lui d,hi16(j) 01311 // ori d,d,lo16(j) 01312 // addu d,d,s 01313 tmpInst.setOpcode(Mips::LUi); 01314 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 01315 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 01316 Instructions.push_back(tmpInst); 01317 tmpInst.clear(); 01318 tmpInst.setOpcode(Mips::ORi); 01319 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 01320 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 01321 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 01322 Instructions.push_back(tmpInst); 01323 tmpInst.clear(); 01324 tmpInst.setOpcode(Mips::ADDu); 01325 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 01326 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 01327 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 01328 Instructions.push_back(tmpInst); 01329 } 01330 return false; 01331 } 01332 01333 bool 01334 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 01335 SmallVectorImpl<MCInst> &Instructions) { 01336 MCInst tmpInst; 01337 const MCOperand &ImmOp = Inst.getOperand(1); 01338 assert((ImmOp.isImm() || ImmOp.isExpr()) && 01339 "expected immediate operand kind"); 01340 if (!ImmOp.isImm()) { 01341 expandLoadAddressSym(Inst, IDLoc, Instructions); 01342 return false; 01343 } 01344 const MCOperand &RegOp = Inst.getOperand(0); 01345 assert(RegOp.isReg() && "expected register operand kind"); 01346 int ImmValue = ImmOp.getImm(); 01347 if (-32768 <= ImmValue && ImmValue <= 65535) { 01348 // For -32768 <= j <= 65535. 01349 // la d,j => addiu d,$zero,j 01350 tmpInst.setOpcode(Mips::ADDiu); 01351 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01352 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 01353 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 01354 Instructions.push_back(tmpInst); 01355 } else { 01356 // For any other value of j that is representable as a 32-bit integer. 01357 // la d,j => lui d,hi16(j) 01358 // ori d,d,lo16(j) 01359 tmpInst.setOpcode(Mips::LUi); 01360 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01361 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 01362 Instructions.push_back(tmpInst); 01363 tmpInst.clear(); 01364 tmpInst.setOpcode(Mips::ORi); 01365 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01366 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 01367 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 01368 Instructions.push_back(tmpInst); 01369 } 01370 return false; 01371 } 01372 01373 void 01374 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc, 01375 SmallVectorImpl<MCInst> &Instructions) { 01376 // FIXME: If we do have a valid at register to use, we should generate a 01377 // slightly shorter sequence here. 01378 MCInst tmpInst; 01379 int ExprOperandNo = 1; 01380 // Sometimes the assembly parser will get the immediate expression as 01381 // a $zero + an immediate. 01382 if (Inst.getNumOperands() == 3) { 01383 assert(Inst.getOperand(1).getReg() == 01384 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO)); 01385 ExprOperandNo = 2; 01386 } 01387 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo); 01388 assert(SymOp.isExpr() && "expected symbol operand kind"); 01389 const MCOperand &RegOp = Inst.getOperand(0); 01390 unsigned RegNo = RegOp.getReg(); 01391 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr()); 01392 const MCSymbolRefExpr *HiExpr = 01393 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 01394 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext()); 01395 const MCSymbolRefExpr *LoExpr = 01396 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 01397 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext()); 01398 if (isGP64bit()) { 01399 // If it's a 64-bit architecture, expand to: 01400 // la d,sym => lui d,highest(sym) 01401 // ori d,d,higher(sym) 01402 // dsll d,d,16 01403 // ori d,d,hi16(sym) 01404 // dsll d,d,16 01405 // ori d,d,lo16(sym) 01406 const MCSymbolRefExpr *HighestExpr = 01407 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 01408 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext()); 01409 const MCSymbolRefExpr *HigherExpr = 01410 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 01411 MCSymbolRefExpr::VK_Mips_HIGHER, getContext()); 01412 01413 tmpInst.setOpcode(Mips::LUi); 01414 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 01415 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr)); 01416 Instructions.push_back(tmpInst); 01417 01418 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(), 01419 Instructions); 01420 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(), 01421 Instructions); 01422 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(), 01423 Instructions); 01424 } else { 01425 // Otherwise, expand to: 01426 // la d,sym => lui d,hi16(sym) 01427 // ori d,d,lo16(sym) 01428 tmpInst.setOpcode(Mips::LUi); 01429 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 01430 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr)); 01431 Instructions.push_back(tmpInst); 01432 01433 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(), 01434 Instructions); 01435 } 01436 } 01437 01438 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 01439 SmallVectorImpl<MCInst> &Instructions, 01440 bool isLoad, bool isImmOpnd) { 01441 const MCSymbolRefExpr *SR; 01442 MCInst TempInst; 01443 unsigned ImmOffset, HiOffset, LoOffset; 01444 const MCExpr *ExprOffset; 01445 unsigned TmpRegNum; 01446 // 1st operand is either the source or destination register. 01447 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 01448 unsigned RegOpNum = Inst.getOperand(0).getReg(); 01449 // 2nd operand is the base register. 01450 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 01451 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 01452 // 3rd operand is either an immediate or expression. 01453 if (isImmOpnd) { 01454 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 01455 ImmOffset = Inst.getOperand(2).getImm(); 01456 LoOffset = ImmOffset & 0x0000ffff; 01457 HiOffset = (ImmOffset & 0xffff0000) >> 16; 01458 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 01459 if (LoOffset & 0x8000) 01460 HiOffset++; 01461 } else 01462 ExprOffset = Inst.getOperand(2).getExpr(); 01463 // All instructions will have the same location. 01464 TempInst.setLoc(IDLoc); 01465 // These are some of the types of expansions we perform here: 01466 // 1) lw $8, sym => lui $8, %hi(sym) 01467 // lw $8, %lo(sym)($8) 01468 // 2) lw $8, offset($9) => lui $8, %hi(offset) 01469 // add $8, $8, $9 01470 // lw $8, %lo(offset)($9) 01471 // 3) lw $8, offset($8) => lui $at, %hi(offset) 01472 // add $at, $at, $8 01473 // lw $8, %lo(offset)($at) 01474 // 4) sw $8, sym => lui $at, %hi(sym) 01475 // sw $8, %lo(sym)($at) 01476 // 5) sw $8, offset($8) => lui $at, %hi(offset) 01477 // add $at, $at, $8 01478 // sw $8, %lo(offset)($at) 01479 // 6) ldc1 $f0, sym => lui $at, %hi(sym) 01480 // ldc1 $f0, %lo(sym)($at) 01481 // 01482 // For load instructions we can use the destination register as a temporary 01483 // if base and dst are different (examples 1 and 2) and if the base register 01484 // is general purpose otherwise we must use $at (example 6) and error if it's 01485 // not available. For stores we must use $at (examples 4 and 5) because we 01486 // must not clobber the source register setting up the offset. 01487 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode()); 01488 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass; 01489 unsigned RegClassIDOp0 = 01490 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID(); 01491 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) || 01492 (RegClassIDOp0 == Mips::GPR64RegClassID); 01493 if (isLoad && IsGPR && (BaseRegNum != RegOpNum)) 01494 TmpRegNum = RegOpNum; 01495 else { 01496 int AT = getATReg(IDLoc); 01497 // At this point we need AT to perform the expansions and we exit if it is 01498 // not available. 01499 if (!AT) 01500 return; 01501 TmpRegNum = getReg( 01502 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT); 01503 } 01504 01505 TempInst.setOpcode(Mips::LUi); 01506 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 01507 if (isImmOpnd) 01508 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 01509 else { 01510 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 01511 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 01512 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 01513 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 01514 getContext()); 01515 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 01516 } else { 01517 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 01518 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 01519 } 01520 } 01521 // Add the instruction to the list. 01522 Instructions.push_back(TempInst); 01523 // Prepare TempInst for next instruction. 01524 TempInst.clear(); 01525 // Add temp register to base. 01526 TempInst.setOpcode(Mips::ADDu); 01527 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 01528 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 01529 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 01530 Instructions.push_back(TempInst); 01531 TempInst.clear(); 01532 // And finally, create original instruction with low part 01533 // of offset and new base. 01534 TempInst.setOpcode(Inst.getOpcode()); 01535 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 01536 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 01537 if (isImmOpnd) 01538 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 01539 else { 01540 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 01541 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 01542 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 01543 getContext()); 01544 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 01545 } else { 01546 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 01547 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 01548 } 01549 } 01550 Instructions.push_back(TempInst); 01551 TempInst.clear(); 01552 } 01553 01554 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 01555 // As described by the Mips32r2 spec, the registers Rd and Rs for 01556 // jalr.hb must be different. 01557 unsigned Opcode = Inst.getOpcode(); 01558 01559 if (Opcode == Mips::JALR_HB && 01560 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())) 01561 return Match_RequiresDifferentSrcAndDst; 01562 01563 return Match_Success; 01564 } 01565 01566 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 01567 OperandVector &Operands, 01568 MCStreamer &Out, 01569 uint64_t &ErrorInfo, 01570 bool MatchingInlineAsm) { 01571 01572 MCInst Inst; 01573 SmallVector<MCInst, 8> Instructions; 01574 unsigned MatchResult = 01575 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 01576 01577 switch (MatchResult) { 01578 default: 01579 break; 01580 case Match_Success: { 01581 if (processInstruction(Inst, IDLoc, Instructions)) 01582 return true; 01583 for (unsigned i = 0; i < Instructions.size(); i++) 01584 Out.EmitInstruction(Instructions[i], STI); 01585 return false; 01586 } 01587 case Match_MissingFeature: 01588 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 01589 return true; 01590 case Match_InvalidOperand: { 01591 SMLoc ErrorLoc = IDLoc; 01592 if (ErrorInfo != ~0ULL) { 01593 if (ErrorInfo >= Operands.size()) 01594 return Error(IDLoc, "too few operands for instruction"); 01595 01596 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc(); 01597 if (ErrorLoc == SMLoc()) 01598 ErrorLoc = IDLoc; 01599 } 01600 01601 return Error(ErrorLoc, "invalid operand for instruction"); 01602 } 01603 case Match_MnemonicFail: 01604 return Error(IDLoc, "invalid instruction"); 01605 case Match_RequiresDifferentSrcAndDst: 01606 return Error(IDLoc, "source and destination must be different"); 01607 } 01608 return true; 01609 } 01610 01611 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { 01612 if ((RegIndex != 0) && 01613 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) { 01614 if (RegIndex == 1) 01615 Warning(Loc, "used $at without \".set noat\""); 01616 else 01617 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" + 01618 Twine(RegIndex) + "\""); 01619 } 01620 } 01621 01622 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 01623 int CC; 01624 01625 CC = StringSwitch<unsigned>(Name) 01626 .Case("zero", 0) 01627 .Case("at", 1) 01628 .Case("a0", 4) 01629 .Case("a1", 5) 01630 .Case("a2", 6) 01631 .Case("a3", 7) 01632 .Case("v0", 2) 01633 .Case("v1", 3) 01634 .Case("s0", 16) 01635 .Case("s1", 17) 01636 .Case("s2", 18) 01637 .Case("s3", 19) 01638 .Case("s4", 20) 01639 .Case("s5", 21) 01640 .Case("s6", 22) 01641 .Case("s7", 23) 01642 .Case("k0", 26) 01643 .Case("k1", 27) 01644 .Case("gp", 28) 01645 .Case("sp", 29) 01646 .Case("fp", 30) 01647 .Case("s8", 30) 01648 .Case("ra", 31) 01649 .Case("t0", 8) 01650 .Case("t1", 9) 01651 .Case("t2", 10) 01652 .Case("t3", 11) 01653 .Case("t4", 12) 01654 .Case("t5", 13) 01655 .Case("t6", 14) 01656 .Case("t7", 15) 01657 .Case("t8", 24) 01658 .Case("t9", 25) 01659 .Default(-1); 01660 01661 if (!(isABI_N32() || isABI_N64())) 01662 return CC; 01663 01664 // Although SGI documentation just cuts out t0-t3 for n32/n64, 01665 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 01666 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 01667 if (8 <= CC && CC <= 11) 01668 CC += 4; 01669 01670 if (CC == -1) 01671 CC = StringSwitch<unsigned>(Name) 01672 .Case("a4", 8) 01673 .Case("a5", 9) 01674 .Case("a6", 10) 01675 .Case("a7", 11) 01676 .Case("kt0", 26) 01677 .Case("kt1", 27) 01678 .Default(-1); 01679 01680 return CC; 01681 } 01682 01683 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 01684 01685 if (Name[0] == 'f') { 01686 StringRef NumString = Name.substr(1); 01687 unsigned IntVal; 01688 if (NumString.getAsInteger(10, IntVal)) 01689 return -1; // This is not an integer. 01690 if (IntVal > 31) // Maximum index for fpu register. 01691 return -1; 01692 return IntVal; 01693 } 01694 return -1; 01695 } 01696 01697 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 01698 01699 if (Name.startswith("fcc")) { 01700 StringRef NumString = Name.substr(3); 01701 unsigned IntVal; 01702 if (NumString.getAsInteger(10, IntVal)) 01703 return -1; // This is not an integer. 01704 if (IntVal > 7) // There are only 8 fcc registers. 01705 return -1; 01706 return IntVal; 01707 } 01708 return -1; 01709 } 01710 01711 int MipsAsmParser::matchACRegisterName(StringRef Name) { 01712 01713 if (Name.startswith("ac")) { 01714 StringRef NumString = Name.substr(2); 01715 unsigned IntVal; 01716 if (NumString.getAsInteger(10, IntVal)) 01717 return -1; // This is not an integer. 01718 if (IntVal > 3) // There are only 3 acc registers. 01719 return -1; 01720 return IntVal; 01721 } 01722 return -1; 01723 } 01724 01725 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 01726 unsigned IntVal; 01727 01728 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 01729 return -1; 01730 01731 if (IntVal > 31) 01732 return -1; 01733 01734 return IntVal; 01735 } 01736 01737 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 01738 int CC; 01739 01740 CC = StringSwitch<unsigned>(Name) 01741 .Case("msair", 0) 01742 .Case("msacsr", 1) 01743 .Case("msaaccess", 2) 01744 .Case("msasave", 3) 01745 .Case("msamodify", 4) 01746 .Case("msarequest", 5) 01747 .Case("msamap", 6) 01748 .Case("msaunmap", 7) 01749 .Default(-1); 01750 01751 return CC; 01752 } 01753 01754 bool MipsAssemblerOptions::setATReg(unsigned Reg) { 01755 if (Reg > 31) 01756 return false; 01757 01758 ATReg = Reg; 01759 return true; 01760 } 01761 01762 int MipsAsmParser::getATReg(SMLoc Loc) { 01763 int AT = AssemblerOptions.back()->getATRegNum(); 01764 if (AT == 0) 01765 reportParseError(Loc, 01766 "pseudo-instruction requires $at, which is not available"); 01767 return AT; 01768 } 01769 01770 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 01771 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 01772 } 01773 01774 unsigned MipsAsmParser::getGPR(int RegNo) { 01775 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 01776 RegNo); 01777 } 01778 01779 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 01780 if (RegNum > 01781 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 01782 return -1; 01783 01784 return getReg(RegClass, RegNum); 01785 } 01786 01787 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 01788 DEBUG(dbgs() << "parseOperand\n"); 01789 01790 // Check if the current operand has a custom associated parser, if so, try to 01791 // custom parse the operand, or fallback to the general approach. 01792 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 01793 if (ResTy == MatchOperand_Success) 01794 return false; 01795 // If there wasn't a custom match, try the generic matcher below. Otherwise, 01796 // there was a match, but an error occurred, in which case, just return that 01797 // the operand parsing failed. 01798 if (ResTy == MatchOperand_ParseFail) 01799 return true; 01800 01801 DEBUG(dbgs() << ".. Generic Parser\n"); 01802 01803 switch (getLexer().getKind()) { 01804 default: 01805 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 01806 return true; 01807 case AsmToken::Dollar: { 01808 // Parse the register. 01809 SMLoc S = Parser.getTok().getLoc(); 01810 01811 // Almost all registers have been parsed by custom parsers. There is only 01812 // one exception to this. $zero (and it's alias $0) will reach this point 01813 // for div, divu, and similar instructions because it is not an operand 01814 // to the instruction definition but an explicit register. Special case 01815 // this situation for now. 01816 if (parseAnyRegister(Operands) != MatchOperand_NoMatch) 01817 return false; 01818 01819 // Maybe it is a symbol reference. 01820 StringRef Identifier; 01821 if (Parser.parseIdentifier(Identifier)) 01822 return true; 01823 01824 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 01825 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 01826 // Otherwise create a symbol reference. 01827 const MCExpr *Res = 01828 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 01829 01830 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 01831 return false; 01832 } 01833 // Else drop to expression parsing. 01834 case AsmToken::LParen: 01835 case AsmToken::Minus: 01836 case AsmToken::Plus: 01837 case AsmToken::Integer: 01838 case AsmToken::Tilde: 01839 case AsmToken::String: { 01840 DEBUG(dbgs() << ".. generic integer\n"); 01841 OperandMatchResultTy ResTy = parseImm(Operands); 01842 return ResTy != MatchOperand_Success; 01843 } 01844 case AsmToken::Percent: { 01845 // It is a symbol reference or constant expression. 01846 const MCExpr *IdVal; 01847 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 01848 if (parseRelocOperand(IdVal)) 01849 return true; 01850 01851 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 01852 01853 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 01854 return false; 01855 } // case AsmToken::Percent 01856 } // switch(getLexer().getKind()) 01857 return true; 01858 } 01859 01860 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 01861 StringRef RelocStr) { 01862 const MCExpr *Res; 01863 // Check the type of the expression. 01864 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 01865 // It's a constant, evaluate reloc value. 01866 int16_t Val; 01867 switch (getVariantKind(RelocStr)) { 01868 case MCSymbolRefExpr::VK_Mips_ABS_LO: 01869 // Get the 1st 16-bits. 01870 Val = MCE->getValue() & 0xffff; 01871 break; 01872 case MCSymbolRefExpr::VK_Mips_ABS_HI: 01873 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low 01874 // 16 bits being negative. 01875 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff; 01876 break; 01877 case MCSymbolRefExpr::VK_Mips_HIGHER: 01878 // Get the 3rd 16-bits. 01879 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff; 01880 break; 01881 case MCSymbolRefExpr::VK_Mips_HIGHEST: 01882 // Get the 4th 16-bits. 01883 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff; 01884 break; 01885 default: 01886 report_fatal_error("unsupported reloc value"); 01887 } 01888 return MCConstantExpr::Create(Val, getContext()); 01889 } 01890 01891 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 01892 // It's a symbol, create a symbolic expression from the symbol. 01893 StringRef Symbol = MSRE->getSymbol().getName(); 01894 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 01895 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 01896 return Res; 01897 } 01898 01899 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 01900 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 01901 01902 // Try to create target expression. 01903 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE)) 01904 return MipsMCExpr::Create(VK, Expr, getContext()); 01905 01906 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 01907 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 01908 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 01909 return Res; 01910 } 01911 01912 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 01913 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 01914 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 01915 return Res; 01916 } 01917 // Just return the original expression. 01918 return Expr; 01919 } 01920 01921 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 01922 01923 switch (Expr->getKind()) { 01924 case MCExpr::Constant: 01925 return true; 01926 case MCExpr::SymbolRef: 01927 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 01928 case MCExpr::Binary: 01929 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 01930 if (!isEvaluated(BE->getLHS())) 01931 return false; 01932 return isEvaluated(BE->getRHS()); 01933 } 01934 case MCExpr::Unary: 01935 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 01936 case MCExpr::Target: 01937 return true; 01938 } 01939 return false; 01940 } 01941 01942 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 01943 Parser.Lex(); // Eat the % token. 01944 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 01945 if (Tok.isNot(AsmToken::Identifier)) 01946 return true; 01947 01948 std::string Str = Tok.getIdentifier().str(); 01949 01950 Parser.Lex(); // Eat the identifier. 01951 // Now make an expression from the rest of the operand. 01952 const MCExpr *IdVal; 01953 SMLoc EndLoc; 01954 01955 if (getLexer().getKind() == AsmToken::LParen) { 01956 while (1) { 01957 Parser.Lex(); // Eat the '(' token. 01958 if (getLexer().getKind() == AsmToken::Percent) { 01959 Parser.Lex(); // Eat the % token. 01960 const AsmToken &nextTok = Parser.getTok(); 01961 if (nextTok.isNot(AsmToken::Identifier)) 01962 return true; 01963 Str += "(%"; 01964 Str += nextTok.getIdentifier(); 01965 Parser.Lex(); // Eat the identifier. 01966 if (getLexer().getKind() != AsmToken::LParen) 01967 return true; 01968 } else 01969 break; 01970 } 01971 if (getParser().parseParenExpression(IdVal, EndLoc)) 01972 return true; 01973 01974 while (getLexer().getKind() == AsmToken::RParen) 01975 Parser.Lex(); // Eat the ')' token. 01976 01977 } else 01978 return true; // Parenthesis must follow the relocation operand. 01979 01980 Res = evaluateRelocExpr(IdVal, Str); 01981 return false; 01982 } 01983 01984 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 01985 SMLoc &EndLoc) { 01986 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 01987 OperandMatchResultTy ResTy = parseAnyRegister(Operands); 01988 if (ResTy == MatchOperand_Success) { 01989 assert(Operands.size() == 1); 01990 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 01991 StartLoc = Operand.getStartLoc(); 01992 EndLoc = Operand.getEndLoc(); 01993 01994 // AFAIK, we only support numeric registers and named GPR's in CFI 01995 // directives. 01996 // Don't worry about eating tokens before failing. Using an unrecognised 01997 // register is a parse error. 01998 if (Operand.isGPRAsmReg()) { 01999 // Resolve to GPR32 or GPR64 appropriately. 02000 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 02001 } 02002 02003 return (RegNo == (unsigned)-1); 02004 } 02005 02006 assert(Operands.size() == 0); 02007 return (RegNo == (unsigned)-1); 02008 } 02009 02010 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 02011 SMLoc S; 02012 bool Result = true; 02013 02014 while (getLexer().getKind() == AsmToken::LParen) 02015 Parser.Lex(); 02016 02017 switch (getLexer().getKind()) { 02018 default: 02019 return true; 02020 case AsmToken::Identifier: 02021 case AsmToken::LParen: 02022 case AsmToken::Integer: 02023 case AsmToken::Minus: 02024 case AsmToken::Plus: 02025 if (isParenExpr) 02026 Result = getParser().parseParenExpression(Res, S); 02027 else 02028 Result = (getParser().parseExpression(Res)); 02029 while (getLexer().getKind() == AsmToken::RParen) 02030 Parser.Lex(); 02031 break; 02032 case AsmToken::Percent: 02033 Result = parseRelocOperand(Res); 02034 } 02035 return Result; 02036 } 02037 02038 MipsAsmParser::OperandMatchResultTy 02039 MipsAsmParser::parseMemOperand(OperandVector &Operands) { 02040 DEBUG(dbgs() << "parseMemOperand\n"); 02041 const MCExpr *IdVal = nullptr; 02042 SMLoc S; 02043 bool isParenExpr = false; 02044 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 02045 // First operand is the offset. 02046 S = Parser.getTok().getLoc(); 02047 02048 if (getLexer().getKind() == AsmToken::LParen) { 02049 Parser.Lex(); 02050 isParenExpr = true; 02051 } 02052 02053 if (getLexer().getKind() != AsmToken::Dollar) { 02054 if (parseMemOffset(IdVal, isParenExpr)) 02055 return MatchOperand_ParseFail; 02056 02057 const AsmToken &Tok = Parser.getTok(); // Get the next token. 02058 if (Tok.isNot(AsmToken::LParen)) { 02059 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 02060 if (Mnemonic.getToken() == "la") { 02061 SMLoc E = 02062 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 02063 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 02064 return MatchOperand_Success; 02065 } 02066 if (Tok.is(AsmToken::EndOfStatement)) { 02067 SMLoc E = 02068 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 02069 02070 // Zero register assumed, add a memory operand with ZERO as its base. 02071 // "Base" will be managed by k_Memory. 02072 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(), 02073 S, E, *this); 02074 Operands.push_back( 02075 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 02076 return MatchOperand_Success; 02077 } 02078 Error(Parser.getTok().getLoc(), "'(' expected"); 02079 return MatchOperand_ParseFail; 02080 } 02081 02082 Parser.Lex(); // Eat the '(' token. 02083 } 02084 02085 Res = parseAnyRegister(Operands); 02086 if (Res != MatchOperand_Success) 02087 return Res; 02088 02089 if (Parser.getTok().isNot(AsmToken::RParen)) { 02090 Error(Parser.getTok().getLoc(), "')' expected"); 02091 return MatchOperand_ParseFail; 02092 } 02093 02094 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 02095 02096 Parser.Lex(); // Eat the ')' token. 02097 02098 if (!IdVal) 02099 IdVal = MCConstantExpr::Create(0, getContext()); 02100 02101 // Replace the register operand with the memory operand. 02102 std::unique_ptr<MipsOperand> op( 02103 static_cast<MipsOperand *>(Operands.back().release())); 02104 // Remove the register from the operands. 02105 // "op" will be managed by k_Memory. 02106 Operands.pop_back(); 02107 // Add the memory operand. 02108 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 02109 int64_t Imm; 02110 if (IdVal->EvaluateAsAbsolute(Imm)) 02111 IdVal = MCConstantExpr::Create(Imm, getContext()); 02112 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 02113 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 02114 getContext()); 02115 } 02116 02117 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 02118 return MatchOperand_Success; 02119 } 02120 02121 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 02122 02123 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 02124 if (Sym) { 02125 SMLoc S = Parser.getTok().getLoc(); 02126 const MCExpr *Expr; 02127 if (Sym->isVariable()) 02128 Expr = Sym->getVariableValue(); 02129 else 02130 return false; 02131 if (Expr->getKind() == MCExpr::SymbolRef) { 02132 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 02133 StringRef DefSymbol = Ref->getSymbol().getName(); 02134 if (DefSymbol.startswith("$")) { 02135 OperandMatchResultTy ResTy = 02136 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 02137 if (ResTy == MatchOperand_Success) { 02138 Parser.Lex(); 02139 return true; 02140 } else if (ResTy == MatchOperand_ParseFail) 02141 llvm_unreachable("Should never ParseFail"); 02142 return false; 02143 } 02144 } else if (Expr->getKind() == MCExpr::Constant) { 02145 Parser.Lex(); 02146 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 02147 Operands.push_back( 02148 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this)); 02149 return true; 02150 } 02151 } 02152 return false; 02153 } 02154 02155 MipsAsmParser::OperandMatchResultTy 02156 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 02157 StringRef Identifier, 02158 SMLoc S) { 02159 int Index = matchCPURegisterName(Identifier); 02160 if (Index != -1) { 02161 Operands.push_back(MipsOperand::createGPRReg( 02162 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 02163 return MatchOperand_Success; 02164 } 02165 02166 Index = matchFPURegisterName(Identifier); 02167 if (Index != -1) { 02168 Operands.push_back(MipsOperand::createFGRReg( 02169 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 02170 return MatchOperand_Success; 02171 } 02172 02173 Index = matchFCCRegisterName(Identifier); 02174 if (Index != -1) { 02175 Operands.push_back(MipsOperand::createFCCReg( 02176 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 02177 return MatchOperand_Success; 02178 } 02179 02180 Index = matchACRegisterName(Identifier); 02181 if (Index != -1) { 02182 Operands.push_back(MipsOperand::createACCReg( 02183 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 02184 return MatchOperand_Success; 02185 } 02186 02187 Index = matchMSA128RegisterName(Identifier); 02188 if (Index != -1) { 02189 Operands.push_back(MipsOperand::createMSA128Reg( 02190 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 02191 return MatchOperand_Success; 02192 } 02193 02194 Index = matchMSA128CtrlRegisterName(Identifier); 02195 if (Index != -1) { 02196 Operands.push_back(MipsOperand::createMSACtrlReg( 02197 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 02198 return MatchOperand_Success; 02199 } 02200 02201 return MatchOperand_NoMatch; 02202 } 02203 02204 MipsAsmParser::OperandMatchResultTy 02205 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 02206 auto Token = Parser.getLexer().peekTok(false); 02207 02208 if (Token.is(AsmToken::Identifier)) { 02209 DEBUG(dbgs() << ".. identifier\n"); 02210 StringRef Identifier = Token.getIdentifier(); 02211 OperandMatchResultTy ResTy = 02212 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 02213 return ResTy; 02214 } else if (Token.is(AsmToken::Integer)) { 02215 DEBUG(dbgs() << ".. integer\n"); 02216 Operands.push_back(MipsOperand::createNumericReg( 02217 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 02218 *this)); 02219 return MatchOperand_Success; 02220 } 02221 02222 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 02223 02224 return MatchOperand_NoMatch; 02225 } 02226 02227 MipsAsmParser::OperandMatchResultTy 02228 MipsAsmParser::parseAnyRegister(OperandVector &Operands) { 02229 DEBUG(dbgs() << "parseAnyRegister\n"); 02230 02231 auto Token = Parser.getTok(); 02232 02233 SMLoc S = Token.getLoc(); 02234 02235 if (Token.isNot(AsmToken::Dollar)) { 02236 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 02237 if (Token.is(AsmToken::Identifier)) { 02238 if (searchSymbolAlias(Operands)) 02239 return MatchOperand_Success; 02240 } 02241 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 02242 return MatchOperand_NoMatch; 02243 } 02244 DEBUG(dbgs() << ".. $\n"); 02245 02246 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S); 02247 if (ResTy == MatchOperand_Success) { 02248 Parser.Lex(); // $ 02249 Parser.Lex(); // identifier 02250 } 02251 return ResTy; 02252 } 02253 02254 MipsAsmParser::OperandMatchResultTy 02255 MipsAsmParser::parseImm(OperandVector &Operands) { 02256 switch (getLexer().getKind()) { 02257 default: 02258 return MatchOperand_NoMatch; 02259 case AsmToken::LParen: 02260 case AsmToken::Minus: 02261 case AsmToken::Plus: 02262 case AsmToken::Integer: 02263 case AsmToken::Tilde: 02264 case AsmToken::String: 02265 break; 02266 } 02267 02268 const MCExpr *IdVal; 02269 SMLoc S = Parser.getTok().getLoc(); 02270 if (getParser().parseExpression(IdVal)) 02271 return MatchOperand_ParseFail; 02272 02273 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 02274 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 02275 return MatchOperand_Success; 02276 } 02277 02278 MipsAsmParser::OperandMatchResultTy 02279 MipsAsmParser::parseJumpTarget(OperandVector &Operands) { 02280 DEBUG(dbgs() << "parseJumpTarget\n"); 02281 02282 SMLoc S = getLexer().getLoc(); 02283 02284 // Integers and expressions are acceptable 02285 OperandMatchResultTy ResTy = parseImm(Operands); 02286 if (ResTy != MatchOperand_NoMatch) 02287 return ResTy; 02288 02289 // Registers are a valid target and have priority over symbols. 02290 ResTy = parseAnyRegister(Operands); 02291 if (ResTy != MatchOperand_NoMatch) 02292 return ResTy; 02293 02294 const MCExpr *Expr = nullptr; 02295 if (Parser.parseExpression(Expr)) { 02296 // We have no way of knowing if a symbol was consumed so we must ParseFail 02297 return MatchOperand_ParseFail; 02298 } 02299 Operands.push_back( 02300 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 02301 return MatchOperand_Success; 02302 } 02303 02304 MipsAsmParser::OperandMatchResultTy 02305 MipsAsmParser::parseInvNum(OperandVector &Operands) { 02306 const MCExpr *IdVal; 02307 // If the first token is '$' we may have register operand. 02308 if (Parser.getTok().is(AsmToken::Dollar)) 02309 return MatchOperand_NoMatch; 02310 SMLoc S = Parser.getTok().getLoc(); 02311 if (getParser().parseExpression(IdVal)) 02312 return MatchOperand_ParseFail; 02313 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 02314 assert(MCE && "Unexpected MCExpr type."); 02315 int64_t Val = MCE->getValue(); 02316 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 02317 Operands.push_back(MipsOperand::CreateImm( 02318 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); 02319 return MatchOperand_Success; 02320 } 02321 02322 MipsAsmParser::OperandMatchResultTy 02323 MipsAsmParser::parseLSAImm(OperandVector &Operands) { 02324 switch (getLexer().getKind()) { 02325 default: 02326 return MatchOperand_NoMatch; 02327 case AsmToken::LParen: 02328 case AsmToken::Plus: 02329 case AsmToken::Minus: 02330 case AsmToken::Integer: 02331 break; 02332 } 02333 02334 const MCExpr *Expr; 02335 SMLoc S = Parser.getTok().getLoc(); 02336 02337 if (getParser().parseExpression(Expr)) 02338 return MatchOperand_ParseFail; 02339 02340 int64_t Val; 02341 if (!Expr->EvaluateAsAbsolute(Val)) { 02342 Error(S, "expected immediate value"); 02343 return MatchOperand_ParseFail; 02344 } 02345 02346 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 02347 // and because the CPU always adds one to the immediate field, the allowed 02348 // range becomes 1..4. We'll only check the range here and will deal 02349 // with the addition/subtraction when actually decoding/encoding 02350 // the instruction. 02351 if (Val < 1 || Val > 4) { 02352 Error(S, "immediate not in range (1..4)"); 02353 return MatchOperand_ParseFail; 02354 } 02355 02356 Operands.push_back( 02357 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 02358 return MatchOperand_Success; 02359 } 02360 02361 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 02362 02363 MCSymbolRefExpr::VariantKind VK = 02364 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 02365 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 02366 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 02367 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 02368 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 02369 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 02370 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 02371 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 02372 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 02373 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 02374 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 02375 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 02376 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 02377 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 02378 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 02379 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 02380 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 02381 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 02382 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16) 02383 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16) 02384 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16) 02385 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16) 02386 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER) 02387 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST) 02388 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16) 02389 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16) 02390 .Default(MCSymbolRefExpr::VK_None); 02391 02392 assert(VK != MCSymbolRefExpr::VK_None); 02393 02394 return VK; 02395 } 02396 02397 /// Sometimes (i.e. load/stores) the operand may be followed immediately by 02398 /// either this. 02399 /// ::= '(', register, ')' 02400 /// handle it before we iterate so we don't get tripped up by the lack of 02401 /// a comma. 02402 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) { 02403 if (getLexer().is(AsmToken::LParen)) { 02404 Operands.push_back( 02405 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 02406 Parser.Lex(); 02407 if (parseOperand(Operands, Name)) { 02408 SMLoc Loc = getLexer().getLoc(); 02409 Parser.eatToEndOfStatement(); 02410 return Error(Loc, "unexpected token in argument list"); 02411 } 02412 if (Parser.getTok().isNot(AsmToken::RParen)) { 02413 SMLoc Loc = getLexer().getLoc(); 02414 Parser.eatToEndOfStatement(); 02415 return Error(Loc, "unexpected token, expected ')'"); 02416 } 02417 Operands.push_back( 02418 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 02419 Parser.Lex(); 02420 } 02421 return false; 02422 } 02423 02424 /// Sometimes (i.e. in MSA) the operand may be followed immediately by 02425 /// either one of these. 02426 /// ::= '[', register, ']' 02427 /// ::= '[', integer, ']' 02428 /// handle it before we iterate so we don't get tripped up by the lack of 02429 /// a comma. 02430 bool MipsAsmParser::parseBracketSuffix(StringRef Name, 02431 OperandVector &Operands) { 02432 if (getLexer().is(AsmToken::LBrac)) { 02433 Operands.push_back( 02434 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 02435 Parser.Lex(); 02436 if (parseOperand(Operands, Name)) { 02437 SMLoc Loc = getLexer().getLoc(); 02438 Parser.eatToEndOfStatement(); 02439 return Error(Loc, "unexpected token in argument list"); 02440 } 02441 if (Parser.getTok().isNot(AsmToken::RBrac)) { 02442 SMLoc Loc = getLexer().getLoc(); 02443 Parser.eatToEndOfStatement(); 02444 return Error(Loc, "unexpected token, expected ']'"); 02445 } 02446 Operands.push_back( 02447 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 02448 Parser.Lex(); 02449 } 02450 return false; 02451 } 02452 02453 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 02454 SMLoc NameLoc, OperandVector &Operands) { 02455 DEBUG(dbgs() << "ParseInstruction\n"); 02456 02457 // We have reached first instruction, module directive are now forbidden. 02458 getTargetStreamer().forbidModuleDirective(); 02459 02460 // Check if we have valid mnemonic 02461 if (!mnemonicIsValid(Name, 0)) { 02462 Parser.eatToEndOfStatement(); 02463 return Error(NameLoc, "unknown instruction"); 02464 } 02465 // First operand in MCInst is instruction mnemonic. 02466 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 02467 02468 // Read the remaining operands. 02469 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02470 // Read the first operand. 02471 if (parseOperand(Operands, Name)) { 02472 SMLoc Loc = getLexer().getLoc(); 02473 Parser.eatToEndOfStatement(); 02474 return Error(Loc, "unexpected token in argument list"); 02475 } 02476 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands)) 02477 return true; 02478 // AFAIK, parenthesis suffixes are never on the first operand 02479 02480 while (getLexer().is(AsmToken::Comma)) { 02481 Parser.Lex(); // Eat the comma. 02482 // Parse and remember the operand. 02483 if (parseOperand(Operands, Name)) { 02484 SMLoc Loc = getLexer().getLoc(); 02485 Parser.eatToEndOfStatement(); 02486 return Error(Loc, "unexpected token in argument list"); 02487 } 02488 // Parse bracket and parenthesis suffixes before we iterate 02489 if (getLexer().is(AsmToken::LBrac)) { 02490 if (parseBracketSuffix(Name, Operands)) 02491 return true; 02492 } else if (getLexer().is(AsmToken::LParen) && 02493 parseParenSuffix(Name, Operands)) 02494 return true; 02495 } 02496 } 02497 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02498 SMLoc Loc = getLexer().getLoc(); 02499 Parser.eatToEndOfStatement(); 02500 return Error(Loc, "unexpected token in argument list"); 02501 } 02502 Parser.Lex(); // Consume the EndOfStatement. 02503 return false; 02504 } 02505 02506 bool MipsAsmParser::reportParseError(Twine ErrorMsg) { 02507 SMLoc Loc = getLexer().getLoc(); 02508 Parser.eatToEndOfStatement(); 02509 return Error(Loc, ErrorMsg); 02510 } 02511 02512 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) { 02513 return Error(Loc, ErrorMsg); 02514 } 02515 02516 bool MipsAsmParser::parseSetNoAtDirective() { 02517 // Line should look like: ".set noat". 02518 // set at reg to 0. 02519 AssemblerOptions.back()->setATReg(0); 02520 // eat noat 02521 Parser.Lex(); 02522 // If this is not the end of the statement, report an error. 02523 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02524 reportParseError("unexpected token, expected end of statement"); 02525 return false; 02526 } 02527 Parser.Lex(); // Consume the EndOfStatement. 02528 return false; 02529 } 02530 02531 bool MipsAsmParser::parseSetAtDirective() { 02532 // Line can be .set at - defaults to $1 02533 // or .set at=$reg 02534 int AtRegNo; 02535 getParser().Lex(); 02536 if (getLexer().is(AsmToken::EndOfStatement)) { 02537 AssemblerOptions.back()->setATReg(1); 02538 Parser.Lex(); // Consume the EndOfStatement. 02539 return false; 02540 } else if (getLexer().is(AsmToken::Equal)) { 02541 getParser().Lex(); // Eat the '='. 02542 if (getLexer().isNot(AsmToken::Dollar)) { 02543 reportParseError("unexpected token, expected dollar sign '$'"); 02544 return false; 02545 } 02546 Parser.Lex(); // Eat the '$'. 02547 const AsmToken &Reg = Parser.getTok(); 02548 if (Reg.is(AsmToken::Identifier)) { 02549 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 02550 } else if (Reg.is(AsmToken::Integer)) { 02551 AtRegNo = Reg.getIntVal(); 02552 } else { 02553 reportParseError("unexpected token, expected identifier or integer"); 02554 return false; 02555 } 02556 02557 if (AtRegNo < 0 || AtRegNo > 31) { 02558 reportParseError("unexpected token in statement"); 02559 return false; 02560 } 02561 02562 if (!AssemblerOptions.back()->setATReg(AtRegNo)) { 02563 reportParseError("invalid register"); 02564 return false; 02565 } 02566 getParser().Lex(); // Eat the register. 02567 02568 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02569 reportParseError("unexpected token, expected end of statement"); 02570 return false; 02571 } 02572 Parser.Lex(); // Consume the EndOfStatement. 02573 return false; 02574 } else { 02575 reportParseError("unexpected token in statement"); 02576 return false; 02577 } 02578 } 02579 02580 bool MipsAsmParser::parseSetReorderDirective() { 02581 Parser.Lex(); 02582 // If this is not the end of the statement, report an error. 02583 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02584 reportParseError("unexpected token, expected end of statement"); 02585 return false; 02586 } 02587 AssemblerOptions.back()->setReorder(); 02588 getTargetStreamer().emitDirectiveSetReorder(); 02589 Parser.Lex(); // Consume the EndOfStatement. 02590 return false; 02591 } 02592 02593 bool MipsAsmParser::parseSetNoReorderDirective() { 02594 Parser.Lex(); 02595 // If this is not the end of the statement, report an error. 02596 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02597 reportParseError("unexpected token, expected end of statement"); 02598 return false; 02599 } 02600 AssemblerOptions.back()->setNoReorder(); 02601 getTargetStreamer().emitDirectiveSetNoReorder(); 02602 Parser.Lex(); // Consume the EndOfStatement. 02603 return false; 02604 } 02605 02606 bool MipsAsmParser::parseSetMacroDirective() { 02607 Parser.Lex(); 02608 // If this is not the end of the statement, report an error. 02609 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02610 reportParseError("unexpected token, expected end of statement"); 02611 return false; 02612 } 02613 AssemblerOptions.back()->setMacro(); 02614 Parser.Lex(); // Consume the EndOfStatement. 02615 return false; 02616 } 02617 02618 bool MipsAsmParser::parseSetNoMacroDirective() { 02619 Parser.Lex(); 02620 // If this is not the end of the statement, report an error. 02621 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02622 reportParseError("unexpected token, expected end of statement"); 02623 return false; 02624 } 02625 if (AssemblerOptions.back()->isReorder()) { 02626 reportParseError("`noreorder' must be set before `nomacro'"); 02627 return false; 02628 } 02629 AssemblerOptions.back()->setNoMacro(); 02630 Parser.Lex(); // Consume the EndOfStatement. 02631 return false; 02632 } 02633 02634 bool MipsAsmParser::parseSetMsaDirective() { 02635 Parser.Lex(); 02636 02637 // If this is not the end of the statement, report an error. 02638 if (getLexer().isNot(AsmToken::EndOfStatement)) 02639 return reportParseError("unexpected token, expected end of statement"); 02640 02641 setFeatureBits(Mips::FeatureMSA, "msa"); 02642 getTargetStreamer().emitDirectiveSetMsa(); 02643 return false; 02644 } 02645 02646 bool MipsAsmParser::parseSetNoMsaDirective() { 02647 Parser.Lex(); 02648 02649 // If this is not the end of the statement, report an error. 02650 if (getLexer().isNot(AsmToken::EndOfStatement)) 02651 return reportParseError("unexpected token, expected end of statement"); 02652 02653 clearFeatureBits(Mips::FeatureMSA, "msa"); 02654 getTargetStreamer().emitDirectiveSetNoMsa(); 02655 return false; 02656 } 02657 02658 bool MipsAsmParser::parseSetNoDspDirective() { 02659 Parser.Lex(); // Eat "nodsp". 02660 02661 // If this is not the end of the statement, report an error. 02662 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02663 reportParseError("unexpected token, expected end of statement"); 02664 return false; 02665 } 02666 02667 clearFeatureBits(Mips::FeatureDSP, "dsp"); 02668 getTargetStreamer().emitDirectiveSetNoDsp(); 02669 return false; 02670 } 02671 02672 bool MipsAsmParser::parseSetNoMips16Directive() { 02673 Parser.Lex(); 02674 // If this is not the end of the statement, report an error. 02675 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02676 reportParseError("unexpected token, expected end of statement"); 02677 return false; 02678 } 02679 // For now do nothing. 02680 Parser.Lex(); // Consume the EndOfStatement. 02681 return false; 02682 } 02683 02684 bool MipsAsmParser::parseSetFpDirective() { 02685 MipsABIFlagsSection::FpABIKind FpAbiVal; 02686 // Line can be: .set fp=32 02687 // .set fp=xx 02688 // .set fp=64 02689 Parser.Lex(); // Eat fp token 02690 AsmToken Tok = Parser.getTok(); 02691 if (Tok.isNot(AsmToken::Equal)) { 02692 reportParseError("unexpected token, expected equals sign '='"); 02693 return false; 02694 } 02695 Parser.Lex(); // Eat '=' token. 02696 Tok = Parser.getTok(); 02697 02698 if (!parseFpABIValue(FpAbiVal, ".set")) 02699 return false; 02700 02701 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02702 reportParseError("unexpected token, expected end of statement"); 02703 return false; 02704 } 02705 getTargetStreamer().emitDirectiveSetFp(FpAbiVal); 02706 Parser.Lex(); // Consume the EndOfStatement. 02707 return false; 02708 } 02709 02710 bool MipsAsmParser::parseSetPopDirective() { 02711 SMLoc Loc = getLexer().getLoc(); 02712 02713 Parser.Lex(); 02714 if (getLexer().isNot(AsmToken::EndOfStatement)) 02715 return reportParseError("unexpected token, expected end of statement"); 02716 02717 // Always keep an element on the options "stack" to prevent the user 02718 // from changing the initial options. This is how we remember them. 02719 if (AssemblerOptions.size() == 2) 02720 return reportParseError(Loc, ".set pop with no .set push"); 02721 02722 AssemblerOptions.pop_back(); 02723 setAvailableFeatures(AssemblerOptions.back()->getFeatures()); 02724 02725 getTargetStreamer().emitDirectiveSetPop(); 02726 return false; 02727 } 02728 02729 bool MipsAsmParser::parseSetPushDirective() { 02730 Parser.Lex(); 02731 if (getLexer().isNot(AsmToken::EndOfStatement)) 02732 return reportParseError("unexpected token, expected end of statement"); 02733 02734 // Create a copy of the current assembler options environment and push it. 02735 AssemblerOptions.push_back( 02736 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get())); 02737 02738 getTargetStreamer().emitDirectiveSetPush(); 02739 return false; 02740 } 02741 02742 bool MipsAsmParser::parseSetAssignment() { 02743 StringRef Name; 02744 const MCExpr *Value; 02745 02746 if (Parser.parseIdentifier(Name)) 02747 reportParseError("expected identifier after .set"); 02748 02749 if (getLexer().isNot(AsmToken::Comma)) 02750 return reportParseError("unexpected token, expected comma"); 02751 Lex(); // Eat comma 02752 02753 if (Parser.parseExpression(Value)) 02754 return reportParseError("expected valid expression after comma"); 02755 02756 // Check if the Name already exists as a symbol. 02757 MCSymbol *Sym = getContext().LookupSymbol(Name); 02758 if (Sym) 02759 return reportParseError("symbol already defined"); 02760 Sym = getContext().GetOrCreateSymbol(Name); 02761 Sym->setVariableValue(Value); 02762 02763 return false; 02764 } 02765 02766 bool MipsAsmParser::parseSetMips0Directive() { 02767 Parser.Lex(); 02768 if (getLexer().isNot(AsmToken::EndOfStatement)) 02769 return reportParseError("unexpected token, expected end of statement"); 02770 02771 // Reset assembler options to their initial values. 02772 setAvailableFeatures(AssemblerOptions.front()->getFeatures()); 02773 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures()); 02774 02775 getTargetStreamer().emitDirectiveSetMips0(); 02776 return false; 02777 } 02778 02779 bool MipsAsmParser::parseSetArchDirective() { 02780 Parser.Lex(); 02781 if (getLexer().isNot(AsmToken::Equal)) 02782 return reportParseError("unexpected token, expected equals sign"); 02783 02784 Parser.Lex(); 02785 StringRef Arch; 02786 if (Parser.parseIdentifier(Arch)) 02787 return reportParseError("expected arch identifier"); 02788 02789 StringRef ArchFeatureName = 02790 StringSwitch<StringRef>(Arch) 02791 .Case("mips1", "mips1") 02792 .Case("mips2", "mips2") 02793 .Case("mips3", "mips3") 02794 .Case("mips4", "mips4") 02795 .Case("mips5", "mips5") 02796 .Case("mips32", "mips32") 02797 .Case("mips32r2", "mips32r2") 02798 .Case("mips32r6", "mips32r6") 02799 .Case("mips64", "mips64") 02800 .Case("mips64r2", "mips64r2") 02801 .Case("mips64r6", "mips64r6") 02802 .Case("cnmips", "cnmips") 02803 .Case("r4000", "mips3") // This is an implementation of Mips3. 02804 .Default(""); 02805 02806 if (ArchFeatureName.empty()) 02807 return reportParseError("unsupported architecture"); 02808 02809 selectArch(ArchFeatureName); 02810 getTargetStreamer().emitDirectiveSetArch(Arch); 02811 return false; 02812 } 02813 02814 bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 02815 Parser.Lex(); 02816 if (getLexer().isNot(AsmToken::EndOfStatement)) 02817 return reportParseError("unexpected token, expected end of statement"); 02818 02819 switch (Feature) { 02820 default: 02821 llvm_unreachable("Unimplemented feature"); 02822 case Mips::FeatureDSP: 02823 setFeatureBits(Mips::FeatureDSP, "dsp"); 02824 getTargetStreamer().emitDirectiveSetDsp(); 02825 break; 02826 case Mips::FeatureMicroMips: 02827 getTargetStreamer().emitDirectiveSetMicroMips(); 02828 break; 02829 case Mips::FeatureMips16: 02830 getTargetStreamer().emitDirectiveSetMips16(); 02831 break; 02832 case Mips::FeatureMips1: 02833 selectArch("mips1"); 02834 getTargetStreamer().emitDirectiveSetMips1(); 02835 break; 02836 case Mips::FeatureMips2: 02837 selectArch("mips2"); 02838 getTargetStreamer().emitDirectiveSetMips2(); 02839 break; 02840 case Mips::FeatureMips3: 02841 selectArch("mips3"); 02842 getTargetStreamer().emitDirectiveSetMips3(); 02843 break; 02844 case Mips::FeatureMips4: 02845 selectArch("mips4"); 02846 getTargetStreamer().emitDirectiveSetMips4(); 02847 break; 02848 case Mips::FeatureMips5: 02849 selectArch("mips5"); 02850 getTargetStreamer().emitDirectiveSetMips5(); 02851 break; 02852 case Mips::FeatureMips32: 02853 selectArch("mips32"); 02854 getTargetStreamer().emitDirectiveSetMips32(); 02855 break; 02856 case Mips::FeatureMips32r2: 02857 selectArch("mips32r2"); 02858 getTargetStreamer().emitDirectiveSetMips32R2(); 02859 break; 02860 case Mips::FeatureMips32r6: 02861 selectArch("mips32r6"); 02862 getTargetStreamer().emitDirectiveSetMips32R6(); 02863 break; 02864 case Mips::FeatureMips64: 02865 selectArch("mips64"); 02866 getTargetStreamer().emitDirectiveSetMips64(); 02867 break; 02868 case Mips::FeatureMips64r2: 02869 selectArch("mips64r2"); 02870 getTargetStreamer().emitDirectiveSetMips64R2(); 02871 break; 02872 case Mips::FeatureMips64r6: 02873 selectArch("mips64r6"); 02874 getTargetStreamer().emitDirectiveSetMips64R6(); 02875 break; 02876 } 02877 return false; 02878 } 02879 02880 bool MipsAsmParser::eatComma(StringRef ErrorStr) { 02881 if (getLexer().isNot(AsmToken::Comma)) { 02882 SMLoc Loc = getLexer().getLoc(); 02883 Parser.eatToEndOfStatement(); 02884 return Error(Loc, ErrorStr); 02885 } 02886 02887 Parser.Lex(); // Eat the comma. 02888 return true; 02889 } 02890 02891 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) { 02892 if (AssemblerOptions.back()->isReorder()) 02893 Warning(Loc, ".cpload in reorder section"); 02894 02895 // FIXME: Warn if cpload is used in Mips16 mode. 02896 02897 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 02898 OperandMatchResultTy ResTy = parseAnyRegister(Reg); 02899 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 02900 reportParseError("expected register containing function address"); 02901 return false; 02902 } 02903 02904 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 02905 if (!RegOpnd.isGPRAsmReg()) { 02906 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 02907 return false; 02908 } 02909 02910 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg()); 02911 return false; 02912 } 02913 02914 bool MipsAsmParser::parseDirectiveCPSetup() { 02915 unsigned FuncReg; 02916 unsigned Save; 02917 bool SaveIsReg = true; 02918 02919 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 02920 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 02921 if (ResTy == MatchOperand_NoMatch) { 02922 reportParseError("expected register containing function address"); 02923 Parser.eatToEndOfStatement(); 02924 return false; 02925 } 02926 02927 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 02928 if (!FuncRegOpnd.isGPRAsmReg()) { 02929 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 02930 Parser.eatToEndOfStatement(); 02931 return false; 02932 } 02933 02934 FuncReg = FuncRegOpnd.getGPR32Reg(); 02935 TmpReg.clear(); 02936 02937 if (!eatComma("unexpected token, expected comma")) 02938 return true; 02939 02940 ResTy = parseAnyRegister(TmpReg); 02941 if (ResTy == MatchOperand_NoMatch) { 02942 const AsmToken &Tok = Parser.getTok(); 02943 if (Tok.is(AsmToken::Integer)) { 02944 Save = Tok.getIntVal(); 02945 SaveIsReg = false; 02946 Parser.Lex(); 02947 } else { 02948 reportParseError("expected save register or stack offset"); 02949 Parser.eatToEndOfStatement(); 02950 return false; 02951 } 02952 } else { 02953 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 02954 if (!SaveOpnd.isGPRAsmReg()) { 02955 reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 02956 Parser.eatToEndOfStatement(); 02957 return false; 02958 } 02959 Save = SaveOpnd.getGPR32Reg(); 02960 } 02961 02962 if (!eatComma("unexpected token, expected comma")) 02963 return true; 02964 02965 StringRef Name; 02966 if (Parser.parseIdentifier(Name)) 02967 reportParseError("expected identifier"); 02968 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 02969 02970 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg); 02971 return false; 02972 } 02973 02974 bool MipsAsmParser::parseDirectiveNaN() { 02975 if (getLexer().isNot(AsmToken::EndOfStatement)) { 02976 const AsmToken &Tok = Parser.getTok(); 02977 02978 if (Tok.getString() == "2008") { 02979 Parser.Lex(); 02980 getTargetStreamer().emitDirectiveNaN2008(); 02981 return false; 02982 } else if (Tok.getString() == "legacy") { 02983 Parser.Lex(); 02984 getTargetStreamer().emitDirectiveNaNLegacy(); 02985 return false; 02986 } 02987 } 02988 // If we don't recognize the option passed to the .nan 02989 // directive (e.g. no option or unknown option), emit an error. 02990 reportParseError("invalid option in .nan directive"); 02991 return false; 02992 } 02993 02994 bool MipsAsmParser::parseDirectiveSet() { 02995 02996 // Get the next token. 02997 const AsmToken &Tok = Parser.getTok(); 02998 02999 if (Tok.getString() == "noat") { 03000 return parseSetNoAtDirective(); 03001 } else if (Tok.getString() == "at") { 03002 return parseSetAtDirective(); 03003 } else if (Tok.getString() == "arch") { 03004 return parseSetArchDirective(); 03005 } else if (Tok.getString() == "fp") { 03006 return parseSetFpDirective(); 03007 } else if (Tok.getString() == "pop") { 03008 return parseSetPopDirective(); 03009 } else if (Tok.getString() == "push") { 03010 return parseSetPushDirective(); 03011 } else if (Tok.getString() == "reorder") { 03012 return parseSetReorderDirective(); 03013 } else if (Tok.getString() == "noreorder") { 03014 return parseSetNoReorderDirective(); 03015 } else if (Tok.getString() == "macro") { 03016 return parseSetMacroDirective(); 03017 } else if (Tok.getString() == "nomacro") { 03018 return parseSetNoMacroDirective(); 03019 } else if (Tok.getString() == "mips16") { 03020 return parseSetFeature(Mips::FeatureMips16); 03021 } else if (Tok.getString() == "nomips16") { 03022 return parseSetNoMips16Directive(); 03023 } else if (Tok.getString() == "nomicromips") { 03024 getTargetStreamer().emitDirectiveSetNoMicroMips(); 03025 Parser.eatToEndOfStatement(); 03026 return false; 03027 } else if (Tok.getString() == "micromips") { 03028 return parseSetFeature(Mips::FeatureMicroMips); 03029 } else if (Tok.getString() == "mips0") { 03030 return parseSetMips0Directive(); 03031 } else if (Tok.getString() == "mips1") { 03032 return parseSetFeature(Mips::FeatureMips1); 03033 } else if (Tok.getString() == "mips2") { 03034 return parseSetFeature(Mips::FeatureMips2); 03035 } else if (Tok.getString() == "mips3") { 03036 return parseSetFeature(Mips::FeatureMips3); 03037 } else if (Tok.getString() == "mips4") { 03038 return parseSetFeature(Mips::FeatureMips4); 03039 } else if (Tok.getString() == "mips5") { 03040 return parseSetFeature(Mips::FeatureMips5); 03041 } else if (Tok.getString() == "mips32") { 03042 return parseSetFeature(Mips::FeatureMips32); 03043 } else if (Tok.getString() == "mips32r2") { 03044 return parseSetFeature(Mips::FeatureMips32r2); 03045 } else if (Tok.getString() == "mips32r6") { 03046 return parseSetFeature(Mips::FeatureMips32r6); 03047 } else if (Tok.getString() == "mips64") { 03048 return parseSetFeature(Mips::FeatureMips64); 03049 } else if (Tok.getString() == "mips64r2") { 03050 return parseSetFeature(Mips::FeatureMips64r2); 03051 } else if (Tok.getString() == "mips64r6") { 03052 return parseSetFeature(Mips::FeatureMips64r6); 03053 } else if (Tok.getString() == "dsp") { 03054 return parseSetFeature(Mips::FeatureDSP); 03055 } else if (Tok.getString() == "nodsp") { 03056 return parseSetNoDspDirective(); 03057 } else if (Tok.getString() == "msa") { 03058 return parseSetMsaDirective(); 03059 } else if (Tok.getString() == "nomsa") { 03060 return parseSetNoMsaDirective(); 03061 } else { 03062 // It is just an identifier, look for an assignment. 03063 parseSetAssignment(); 03064 return false; 03065 } 03066 03067 return true; 03068 } 03069 03070 /// parseDataDirective 03071 /// ::= .word [ expression (, expression)* ] 03072 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 03073 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03074 for (;;) { 03075 const MCExpr *Value; 03076 if (getParser().parseExpression(Value)) 03077 return true; 03078 03079 getParser().getStreamer().EmitValue(Value, Size); 03080 03081 if (getLexer().is(AsmToken::EndOfStatement)) 03082 break; 03083 03084 if (getLexer().isNot(AsmToken::Comma)) 03085 return Error(L, "unexpected token, expected comma"); 03086 Parser.Lex(); 03087 } 03088 } 03089 03090 Parser.Lex(); 03091 return false; 03092 } 03093 03094 /// parseDirectiveGpWord 03095 /// ::= .gpword local_sym 03096 bool MipsAsmParser::parseDirectiveGpWord() { 03097 const MCExpr *Value; 03098 // EmitGPRel32Value requires an expression, so we are using base class 03099 // method to evaluate the expression. 03100 if (getParser().parseExpression(Value)) 03101 return true; 03102 getParser().getStreamer().EmitGPRel32Value(Value); 03103 03104 if (getLexer().isNot(AsmToken::EndOfStatement)) 03105 return Error(getLexer().getLoc(), 03106 "unexpected token, expected end of statement"); 03107 Parser.Lex(); // Eat EndOfStatement token. 03108 return false; 03109 } 03110 03111 /// parseDirectiveGpDWord 03112 /// ::= .gpdword local_sym 03113 bool MipsAsmParser::parseDirectiveGpDWord() { 03114 const MCExpr *Value; 03115 // EmitGPRel64Value requires an expression, so we are using base class 03116 // method to evaluate the expression. 03117 if (getParser().parseExpression(Value)) 03118 return true; 03119 getParser().getStreamer().EmitGPRel64Value(Value); 03120 03121 if (getLexer().isNot(AsmToken::EndOfStatement)) 03122 return Error(getLexer().getLoc(), 03123 "unexpected token, expected end of statement"); 03124 Parser.Lex(); // Eat EndOfStatement token. 03125 return false; 03126 } 03127 03128 bool MipsAsmParser::parseDirectiveOption() { 03129 // Get the option token. 03130 AsmToken Tok = Parser.getTok(); 03131 // At the moment only identifiers are supported. 03132 if (Tok.isNot(AsmToken::Identifier)) { 03133 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier"); 03134 Parser.eatToEndOfStatement(); 03135 return false; 03136 } 03137 03138 StringRef Option = Tok.getIdentifier(); 03139 03140 if (Option == "pic0") { 03141 getTargetStreamer().emitDirectiveOptionPic0(); 03142 Parser.Lex(); 03143 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 03144 Error(Parser.getTok().getLoc(), 03145 "unexpected token, expected end of statement"); 03146 Parser.eatToEndOfStatement(); 03147 } 03148 return false; 03149 } 03150 03151 if (Option == "pic2") { 03152 getTargetStreamer().emitDirectiveOptionPic2(); 03153 Parser.Lex(); 03154 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 03155 Error(Parser.getTok().getLoc(), 03156 "unexpected token, expected end of statement"); 03157 Parser.eatToEndOfStatement(); 03158 } 03159 return false; 03160 } 03161 03162 // Unknown option. 03163 Warning(Parser.getTok().getLoc(), 03164 "unknown option, expected 'pic0' or 'pic2'"); 03165 Parser.eatToEndOfStatement(); 03166 return false; 03167 } 03168 03169 /// parseDirectiveModule 03170 /// ::= .module oddspreg 03171 /// ::= .module nooddspreg 03172 /// ::= .module fp=value 03173 bool MipsAsmParser::parseDirectiveModule() { 03174 MCAsmLexer &Lexer = getLexer(); 03175 SMLoc L = Lexer.getLoc(); 03176 03177 if (!getTargetStreamer().isModuleDirectiveAllowed()) { 03178 // TODO : get a better message. 03179 reportParseError(".module directive must appear before any code"); 03180 return false; 03181 } 03182 03183 if (Lexer.is(AsmToken::Identifier)) { 03184 StringRef Option = Parser.getTok().getString(); 03185 Parser.Lex(); 03186 03187 if (Option == "oddspreg") { 03188 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32()); 03189 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 03190 03191 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03192 reportParseError("unexpected token, expected end of statement"); 03193 return false; 03194 } 03195 03196 return false; 03197 } else if (Option == "nooddspreg") { 03198 if (!isABI_O32()) { 03199 Error(L, "'.module nooddspreg' requires the O32 ABI"); 03200 return false; 03201 } 03202 03203 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32()); 03204 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 03205 03206 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03207 reportParseError("unexpected token, expected end of statement"); 03208 return false; 03209 } 03210 03211 return false; 03212 } else if (Option == "fp") { 03213 return parseDirectiveModuleFP(); 03214 } 03215 03216 return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); 03217 } 03218 03219 return false; 03220 } 03221 03222 /// parseDirectiveModuleFP 03223 /// ::= =32 03224 /// ::= =xx 03225 /// ::= =64 03226 bool MipsAsmParser::parseDirectiveModuleFP() { 03227 MCAsmLexer &Lexer = getLexer(); 03228 03229 if (Lexer.isNot(AsmToken::Equal)) { 03230 reportParseError("unexpected token, expected equals sign '='"); 03231 return false; 03232 } 03233 Parser.Lex(); // Eat '=' token. 03234 03235 MipsABIFlagsSection::FpABIKind FpABI; 03236 if (!parseFpABIValue(FpABI, ".module")) 03237 return false; 03238 03239 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03240 reportParseError("unexpected token, expected end of statement"); 03241 return false; 03242 } 03243 03244 // Emit appropriate flags. 03245 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32()); 03246 Parser.Lex(); // Consume the EndOfStatement. 03247 return false; 03248 } 03249 03250 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 03251 StringRef Directive) { 03252 MCAsmLexer &Lexer = getLexer(); 03253 03254 if (Lexer.is(AsmToken::Identifier)) { 03255 StringRef Value = Parser.getTok().getString(); 03256 Parser.Lex(); 03257 03258 if (Value != "xx") { 03259 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 03260 return false; 03261 } 03262 03263 if (!isABI_O32()) { 03264 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI"); 03265 return false; 03266 } 03267 03268 FpABI = MipsABIFlagsSection::FpABIKind::XX; 03269 return true; 03270 } 03271 03272 if (Lexer.is(AsmToken::Integer)) { 03273 unsigned Value = Parser.getTok().getIntVal(); 03274 Parser.Lex(); 03275 03276 if (Value != 32 && Value != 64) { 03277 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 03278 return false; 03279 } 03280 03281 if (Value == 32) { 03282 if (!isABI_O32()) { 03283 reportParseError("'" + Directive + " fp=32' requires the O32 ABI"); 03284 return false; 03285 } 03286 03287 FpABI = MipsABIFlagsSection::FpABIKind::S32; 03288 } else 03289 FpABI = MipsABIFlagsSection::FpABIKind::S64; 03290 03291 return true; 03292 } 03293 03294 return false; 03295 } 03296 03297 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 03298 StringRef IDVal = DirectiveID.getString(); 03299 03300 if (IDVal == ".cpload") 03301 return parseDirectiveCPLoad(DirectiveID.getLoc()); 03302 if (IDVal == ".dword") { 03303 parseDataDirective(8, DirectiveID.getLoc()); 03304 return false; 03305 } 03306 if (IDVal == ".ent") { 03307 StringRef SymbolName; 03308 03309 if (Parser.parseIdentifier(SymbolName)) { 03310 reportParseError("expected identifier after .ent"); 03311 return false; 03312 } 03313 03314 // There's an undocumented extension that allows an integer to 03315 // follow the name of the procedure which AFAICS is ignored by GAS. 03316 // Example: .ent foo,2 03317 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03318 if (getLexer().isNot(AsmToken::Comma)) { 03319 // Even though we accept this undocumented extension for compatibility 03320 // reasons, the additional integer argument does not actually change 03321 // the behaviour of the '.ent' directive, so we would like to discourage 03322 // its use. We do this by not referring to the extended version in 03323 // error messages which are not directly related to its use. 03324 reportParseError("unexpected token, expected end of statement"); 03325 return false; 03326 } 03327 Parser.Lex(); // Eat the comma. 03328 const MCExpr *DummyNumber; 03329 int64_t DummyNumberVal; 03330 // If the user was explicitly trying to use the extended version, 03331 // we still give helpful extension-related error messages. 03332 if (Parser.parseExpression(DummyNumber)) { 03333 reportParseError("expected number after comma"); 03334 return false; 03335 } 03336 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) { 03337 reportParseError("expected an absolute expression after comma"); 03338 return false; 03339 } 03340 } 03341 03342 // If this is not the end of the statement, report an error. 03343 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03344 reportParseError("unexpected token, expected end of statement"); 03345 return false; 03346 } 03347 03348 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); 03349 03350 getTargetStreamer().emitDirectiveEnt(*Sym); 03351 CurrentFn = Sym; 03352 return false; 03353 } 03354 03355 if (IDVal == ".end") { 03356 StringRef SymbolName; 03357 03358 if (Parser.parseIdentifier(SymbolName)) { 03359 reportParseError("expected identifier after .end"); 03360 return false; 03361 } 03362 03363 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03364 reportParseError("unexpected token, expected end of statement"); 03365 return false; 03366 } 03367 03368 if (CurrentFn == nullptr) { 03369 reportParseError(".end used without .ent"); 03370 return false; 03371 } 03372 03373 if ((SymbolName != CurrentFn->getName())) { 03374 reportParseError(".end symbol does not match .ent symbol"); 03375 return false; 03376 } 03377 03378 getTargetStreamer().emitDirectiveEnd(SymbolName); 03379 CurrentFn = nullptr; 03380 return false; 03381 } 03382 03383 if (IDVal == ".frame") { 03384 // .frame $stack_reg, frame_size_in_bytes, $return_reg 03385 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 03386 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 03387 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 03388 reportParseError("expected stack register"); 03389 return false; 03390 } 03391 03392 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 03393 if (!StackRegOpnd.isGPRAsmReg()) { 03394 reportParseError(StackRegOpnd.getStartLoc(), 03395 "expected general purpose register"); 03396 return false; 03397 } 03398 unsigned StackReg = StackRegOpnd.getGPR32Reg(); 03399 03400 if (Parser.getTok().is(AsmToken::Comma)) 03401 Parser.Lex(); 03402 else { 03403 reportParseError("unexpected token, expected comma"); 03404 return false; 03405 } 03406 03407 // Parse the frame size. 03408 const MCExpr *FrameSize; 03409 int64_t FrameSizeVal; 03410 03411 if (Parser.parseExpression(FrameSize)) { 03412 reportParseError("expected frame size value"); 03413 return false; 03414 } 03415 03416 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) { 03417 reportParseError("frame size not an absolute expression"); 03418 return false; 03419 } 03420 03421 if (Parser.getTok().is(AsmToken::Comma)) 03422 Parser.Lex(); 03423 else { 03424 reportParseError("unexpected token, expected comma"); 03425 return false; 03426 } 03427 03428 // Parse the return register. 03429 TmpReg.clear(); 03430 ResTy = parseAnyRegister(TmpReg); 03431 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 03432 reportParseError("expected return register"); 03433 return false; 03434 } 03435 03436 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 03437 if (!ReturnRegOpnd.isGPRAsmReg()) { 03438 reportParseError(ReturnRegOpnd.getStartLoc(), 03439 "expected general purpose register"); 03440 return false; 03441 } 03442 03443 // If this is not the end of the statement, report an error. 03444 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03445 reportParseError("unexpected token, expected end of statement"); 03446 return false; 03447 } 03448 03449 getTargetStreamer().emitFrame(StackReg, FrameSizeVal, 03450 ReturnRegOpnd.getGPR32Reg()); 03451 return false; 03452 } 03453 03454 if (IDVal == ".set") { 03455 return parseDirectiveSet(); 03456 } 03457 03458 if (IDVal == ".mask" || IDVal == ".fmask") { 03459 // .mask bitmask, frame_offset 03460 // bitmask: One bit for each register used. 03461 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where 03462 // first register is expected to be saved. 03463 // Examples: 03464 // .mask 0x80000000, -4 03465 // .fmask 0x80000000, -4 03466 // 03467 03468 // Parse the bitmask 03469 const MCExpr *BitMask; 03470 int64_t BitMaskVal; 03471 03472 if (Parser.parseExpression(BitMask)) { 03473 reportParseError("expected bitmask value"); 03474 return false; 03475 } 03476 03477 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) { 03478 reportParseError("bitmask not an absolute expression"); 03479 return false; 03480 } 03481 03482 if (Parser.getTok().is(AsmToken::Comma)) 03483 Parser.Lex(); 03484 else { 03485 reportParseError("unexpected token, expected comma"); 03486 return false; 03487 } 03488 03489 // Parse the frame_offset 03490 const MCExpr *FrameOffset; 03491 int64_t FrameOffsetVal; 03492 03493 if (Parser.parseExpression(FrameOffset)) { 03494 reportParseError("expected frame offset value"); 03495 return false; 03496 } 03497 03498 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) { 03499 reportParseError("frame offset not an absolute expression"); 03500 return false; 03501 } 03502 03503 // If this is not the end of the statement, report an error. 03504 if (getLexer().isNot(AsmToken::EndOfStatement)) { 03505 reportParseError("unexpected token, expected end of statement"); 03506 return false; 03507 } 03508 03509 if (IDVal == ".mask") 03510 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal); 03511 else 03512 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal); 03513 return false; 03514 } 03515 03516 if (IDVal == ".nan") 03517 return parseDirectiveNaN(); 03518 03519 if (IDVal == ".gpword") { 03520 parseDirectiveGpWord(); 03521 return false; 03522 } 03523 03524 if (IDVal == ".gpdword") { 03525 parseDirectiveGpDWord(); 03526 return false; 03527 } 03528 03529 if (IDVal == ".word") { 03530 parseDataDirective(4, DirectiveID.getLoc()); 03531 return false; 03532 } 03533 03534 if (IDVal == ".option") 03535 return parseDirectiveOption(); 03536 03537 if (IDVal == ".abicalls") { 03538 getTargetStreamer().emitDirectiveAbiCalls(); 03539 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 03540 Error(Parser.getTok().getLoc(), 03541 "unexpected token, expected end of statement"); 03542 // Clear line 03543 Parser.eatToEndOfStatement(); 03544 } 03545 return false; 03546 } 03547 03548 if (IDVal == ".cpsetup") 03549 return parseDirectiveCPSetup(); 03550 03551 if (IDVal == ".module") 03552 return parseDirectiveModule(); 03553 03554 return true; 03555 } 03556 03557 extern "C" void LLVMInitializeMipsAsmParser() { 03558 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 03559 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 03560 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 03561 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 03562 } 03563 03564 #define GET_REGISTER_MATCHER 03565 #define GET_MATCHER_IMPLEMENTATION 03566 #include "MipsGenAsmMatcher.inc"