1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIFlagsSection.h"
11 #include "MCTargetDesc/MipsABIInfo.h"
12 #include "MCTargetDesc/MipsBaseInfo.h"
13 #include "MCTargetDesc/MipsMCExpr.h"
14 #include "MCTargetDesc/MipsMCTargetDesc.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCAsmParser.h"
31 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/SubtargetFeature.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/Compiler.h"
43 #include "llvm/Support/Debug.h"
44 #include "llvm/Support/ErrorHandling.h"
45 #include "llvm/Support/MathExtras.h"
46 #include "llvm/Support/SMLoc.h"
47 #include "llvm/Support/SourceMgr.h"
48 #include "llvm/Support/TargetRegistry.h"
49 #include "llvm/Support/raw_ostream.h"
59 #define DEBUG_TYPE "mips-asm-parser"
65 } // end namespace llvm
69 class MipsAssemblerOptions {
71 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
73 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
74 ATReg = Opts->getATRegIndex();
75 Reorder = Opts->isReorder();
76 Macro = Opts->isMacro();
77 Features = Opts->getFeatures();
80 unsigned getATRegIndex() const { return ATReg; }
81 bool setATRegIndex(unsigned Reg) {
89 bool isReorder() const { return Reorder; }
90 void setReorder() { Reorder = true; }
91 void setNoReorder() { Reorder = false; }
93 bool isMacro() const { return Macro; }
94 void setMacro() { Macro = true; }
95 void setNoMacro() { Macro = false; }
97 const FeatureBitset &getFeatures() const { return Features; }
98 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
100 // Set of features that are either architecture features or referenced
101 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
102 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
103 // The reason we need this mask is explained in the selectArch function.
104 // FIXME: Ideally we would like TableGen to generate this information.
105 static const FeatureBitset AllArchRelatedMask;
111 FeatureBitset Features;
114 } // end anonymous namespace
116 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
117 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
118 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
119 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
120 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
121 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
122 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
123 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
124 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
129 class MipsAsmParser : public MCTargetAsmParser {
130 MipsTargetStreamer &getTargetStreamer() {
131 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
132 return static_cast<MipsTargetStreamer &>(TS);
136 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
137 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
138 // nullptr, which indicates that no function is currently
139 // selected. This usually happens after an '.end func'
145 unsigned CpSaveLocation;
146 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
147 bool CpSaveLocationIsRegister;
149 // Print a warning along with its fix-it message at the given range.
150 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
151 SMRange Range, bool ShowColors = true);
153 #define GET_ASSEMBLER_HEADER
154 #include "MipsGenAsmMatcher.inc"
157 checkEarlyTargetMatchPredicate(MCInst &Inst,
158 const OperandVector &Operands) override;
159 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
161 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
162 OperandVector &Operands, MCStreamer &Out,
164 bool MatchingInlineAsm) override;
166 /// Parse a register as used in CFI directives
167 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
169 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
171 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
173 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
175 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
176 SMLoc NameLoc, OperandVector &Operands) override;
178 bool ParseDirective(AsmToken DirectiveID) override;
180 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
182 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
183 StringRef Identifier, SMLoc S);
184 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
186 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
187 OperandMatchResultTy parseImm(OperandVector &Operands);
188 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
189 OperandMatchResultTy parseInvNum(OperandVector &Operands);
190 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
191 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
192 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
194 bool searchSymbolAlias(OperandVector &Operands);
196 bool parseOperand(OperandVector &, StringRef Mnemonic);
198 enum MacroExpanderResultTy {
204 // Expands assembly pseudo instructions.
205 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
207 const MCSubtargetInfo *STI);
209 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
210 const MCSubtargetInfo *STI);
212 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
213 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
214 MCStreamer &Out, const MCSubtargetInfo *STI);
216 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
217 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
218 MCStreamer &Out, const MCSubtargetInfo *STI);
220 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
222 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
223 MCStreamer &Out, const MCSubtargetInfo *STI);
225 bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
226 SMLoc IDLoc, MCStreamer &Out,
227 const MCSubtargetInfo *STI);
229 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
230 const MCOperand &Offset, bool Is32BitAddress,
231 SMLoc IDLoc, MCStreamer &Out,
232 const MCSubtargetInfo *STI);
234 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
235 const MCSubtargetInfo *STI);
237 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
238 const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
240 void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI, bool IsImmOpnd);
243 void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI, bool IsImmOpnd);
246 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI);
249 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
250 const MCSubtargetInfo *STI);
252 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
255 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
258 bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI, const bool IsMips64,
262 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
263 MCStreamer &Out, const MCSubtargetInfo *STI);
265 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
268 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
271 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
274 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
275 MCStreamer &Out, const MCSubtargetInfo *STI);
276 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI);
278 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
279 const MCSubtargetInfo *STI);
280 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
281 const MCSubtargetInfo *STI);
283 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
284 const MCSubtargetInfo *STI);
286 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
287 const MCSubtargetInfo *STI);
289 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
290 const MCSubtargetInfo *STI);
292 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
295 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
298 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI, bool IsLoad);
301 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI);
304 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI);
307 bool reportParseError(Twine ErrorMsg);
308 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
310 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
312 bool isEvaluated(const MCExpr *Expr);
313 bool parseSetMips0Directive();
314 bool parseSetArchDirective();
315 bool parseSetFeature(uint64_t Feature);
316 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
317 bool parseDirectiveCpLoad(SMLoc Loc);
318 bool parseDirectiveCpRestore(SMLoc Loc);
319 bool parseDirectiveCPSetup();
320 bool parseDirectiveCPReturn();
321 bool parseDirectiveNaN();
322 bool parseDirectiveSet();
323 bool parseDirectiveOption();
324 bool parseInsnDirective();
325 bool parseRSectionDirective(StringRef Section);
326 bool parseSSectionDirective(StringRef Section, unsigned Type);
328 bool parseSetAtDirective();
329 bool parseSetNoAtDirective();
330 bool parseSetMacroDirective();
331 bool parseSetNoMacroDirective();
332 bool parseSetMsaDirective();
333 bool parseSetNoMsaDirective();
334 bool parseSetNoDspDirective();
335 bool parseSetReorderDirective();
336 bool parseSetNoReorderDirective();
337 bool parseSetMips16Directive();
338 bool parseSetNoMips16Directive();
339 bool parseSetFpDirective();
340 bool parseSetOddSPRegDirective();
341 bool parseSetNoOddSPRegDirective();
342 bool parseSetPopDirective();
343 bool parseSetPushDirective();
344 bool parseSetSoftFloatDirective();
345 bool parseSetHardFloatDirective();
347 bool parseSetAssignment();
349 bool parseDataDirective(unsigned Size, SMLoc L);
350 bool parseDirectiveGpWord();
351 bool parseDirectiveGpDWord();
352 bool parseDirectiveDtpRelWord();
353 bool parseDirectiveDtpRelDWord();
354 bool parseDirectiveTpRelWord();
355 bool parseDirectiveTpRelDWord();
356 bool parseDirectiveModule();
357 bool parseDirectiveModuleFP();
358 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
359 StringRef Directive);
361 bool parseInternalDirectiveReallowModule();
363 bool eatComma(StringRef ErrorStr);
365 int matchCPURegisterName(StringRef Symbol);
367 int matchHWRegsRegisterName(StringRef Symbol);
369 int matchFPURegisterName(StringRef Name);
371 int matchFCCRegisterName(StringRef Name);
373 int matchACRegisterName(StringRef Name);
375 int matchMSA128RegisterName(StringRef Name);
377 int matchMSA128CtrlRegisterName(StringRef Name);
379 unsigned getReg(int RC, int RegNo);
381 /// Returns the internal register number for the current AT. Also checks if
382 /// the current AT is unavailable (set to $0) and gives an error if it is.
383 /// This should be used in pseudo-instruction expansions which need AT.
384 unsigned getATReg(SMLoc Loc);
388 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
389 const MCSubtargetInfo *STI);
391 // Helper function that checks if the value of a vector index is within the
392 // boundaries of accepted values for each RegisterKind
393 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
394 bool validateMSAIndex(int Val, int RegKind);
396 // Selects a new architecture by updating the FeatureBits with the necessary
397 // info including implied dependencies.
398 // Internally, it clears all the feature bits related to *any* architecture
399 // and selects the new one using the ToggleFeature functionality of the
400 // MCSubtargetInfo object that handles implied dependencies. The reason we
401 // clear all the arch related bits manually is because ToggleFeature only
402 // clears the features that imply the feature being cleared and not the
403 // features implied by the feature being cleared. This is easier to see
405 // --------------------------------------------------
406 // | Feature | Implies |
407 // | -------------------------------------------------|
408 // | FeatureMips1 | None |
409 // | FeatureMips2 | FeatureMips1 |
410 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
411 // | FeatureMips4 | FeatureMips3 |
413 // --------------------------------------------------
415 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
416 // FeatureMipsGP64 | FeatureMips1)
417 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
418 void selectArch(StringRef ArchFeature) {
419 MCSubtargetInfo &STI = copySTI();
420 FeatureBitset FeatureBits = STI.getFeatureBits();
421 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
422 STI.setFeatureBits(FeatureBits);
423 setAvailableFeatures(
424 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
425 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
428 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
429 if (!(getSTI().getFeatureBits()[Feature])) {
430 MCSubtargetInfo &STI = copySTI();
431 setAvailableFeatures(
432 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
433 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
437 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
438 if (getSTI().getFeatureBits()[Feature]) {
439 MCSubtargetInfo &STI = copySTI();
440 setAvailableFeatures(
441 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
442 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
446 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
447 setFeatureBits(Feature, FeatureString);
448 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
451 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
452 clearFeatureBits(Feature, FeatureString);
453 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
457 enum MipsMatchResultTy {
458 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
459 Match_RequiresDifferentOperands,
460 Match_RequiresNoZeroRegister,
461 Match_RequiresSameSrcAndDst,
462 Match_NoFCCRegisterForCurrentISA,
463 Match_NonZeroOperandForSync,
464 #define GET_OPERAND_DIAGNOSTIC_TYPES
465 #include "MipsGenAsmMatcher.inc"
466 #undef GET_OPERAND_DIAGNOSTIC_TYPES
469 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
470 const MCInstrInfo &MII, const MCTargetOptions &Options)
471 : MCTargetAsmParser(Options, sti),
472 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
473 sti.getCPU(), Options)) {
474 MCAsmParserExtension::Initialize(parser);
476 parser.addAliasForDirective(".asciiz", ".asciz");
478 // Initialize the set of available features.
479 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
481 // Remember the initial assembler options. The user can not modify these.
482 AssemblerOptions.push_back(
483 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
485 // Create an assembler options environment for the user to modify.
486 AssemblerOptions.push_back(
487 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
489 getTargetStreamer().updateABIInfo(*this);
491 if (!isABI_O32() && !useOddSPReg() != 0)
492 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
496 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
498 IsCpRestoreSet = false;
499 CpRestoreOffset = -1;
501 const Triple &TheTriple = sti.getTargetTriple();
502 if ((TheTriple.getArch() == Triple::mips) ||
503 (TheTriple.getArch() == Triple::mips64))
504 IsLittleEndian = false;
506 IsLittleEndian = true;
509 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
510 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
512 bool isGP64bit() const {
513 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
516 bool isFP64bit() const {
517 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
520 const MipsABIInfo &getABI() const { return ABI; }
521 bool isABI_N32() const { return ABI.IsN32(); }
522 bool isABI_N64() const { return ABI.IsN64(); }
523 bool isABI_O32() const { return ABI.IsO32(); }
524 bool isABI_FPXX() const {
525 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
528 bool useOddSPReg() const {
529 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
532 bool inMicroMipsMode() const {
533 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
536 bool hasMips1() const {
537 return getSTI().getFeatureBits()[Mips::FeatureMips1];
540 bool hasMips2() const {
541 return getSTI().getFeatureBits()[Mips::FeatureMips2];
544 bool hasMips3() const {
545 return getSTI().getFeatureBits()[Mips::FeatureMips3];
548 bool hasMips4() const {
549 return getSTI().getFeatureBits()[Mips::FeatureMips4];
552 bool hasMips5() const {
553 return getSTI().getFeatureBits()[Mips::FeatureMips5];
556 bool hasMips32() const {
557 return getSTI().getFeatureBits()[Mips::FeatureMips32];
560 bool hasMips64() const {
561 return getSTI().getFeatureBits()[Mips::FeatureMips64];
564 bool hasMips32r2() const {
565 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
568 bool hasMips64r2() const {
569 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
572 bool hasMips32r3() const {
573 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
576 bool hasMips64r3() const {
577 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
580 bool hasMips32r5() const {
581 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
584 bool hasMips64r5() const {
585 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
588 bool hasMips32r6() const {
589 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
592 bool hasMips64r6() const {
593 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
596 bool hasDSP() const {
597 return getSTI().getFeatureBits()[Mips::FeatureDSP];
600 bool hasDSPR2() const {
601 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
604 bool hasDSPR3() const {
605 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
608 bool hasMSA() const {
609 return getSTI().getFeatureBits()[Mips::FeatureMSA];
612 bool hasCnMips() const {
613 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
620 bool inMips16Mode() const {
621 return getSTI().getFeatureBits()[Mips::FeatureMips16];
624 bool useTraps() const {
625 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
628 bool useSoftFloat() const {
629 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
632 /// Warn if RegIndex is the same as the current AT.
633 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
635 void warnIfNoMacro(SMLoc Loc);
637 bool isLittle() const { return IsLittleEndian; }
639 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
640 AsmToken::TokenKind OperatorToken,
641 MCContext &Ctx) override {
642 switch(OperatorToken) {
644 llvm_unreachable("Unknown token");
646 case AsmToken::PercentCall16:
647 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
648 case AsmToken::PercentCall_Hi:
649 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
650 case AsmToken::PercentCall_Lo:
651 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
652 case AsmToken::PercentDtprel_Hi:
653 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
654 case AsmToken::PercentDtprel_Lo:
655 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
656 case AsmToken::PercentGot:
657 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
658 case AsmToken::PercentGot_Disp:
659 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
660 case AsmToken::PercentGot_Hi:
661 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
662 case AsmToken::PercentGot_Lo:
663 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
664 case AsmToken::PercentGot_Ofst:
665 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
666 case AsmToken::PercentGot_Page:
667 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
668 case AsmToken::PercentGottprel:
669 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
670 case AsmToken::PercentGp_Rel:
671 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
672 case AsmToken::PercentHi:
673 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
674 case AsmToken::PercentHigher:
675 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
676 case AsmToken::PercentHighest:
677 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
678 case AsmToken::PercentLo:
679 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
680 case AsmToken::PercentNeg:
681 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
682 case AsmToken::PercentPcrel_Hi:
683 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
684 case AsmToken::PercentPcrel_Lo:
685 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
686 case AsmToken::PercentTlsgd:
687 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
688 case AsmToken::PercentTlsldm:
689 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
690 case AsmToken::PercentTprel_Hi:
691 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
692 case AsmToken::PercentTprel_Lo:
693 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
698 /// MipsOperand - Instances of this class represent a parsed Mips machine
700 class MipsOperand : public MCParsedAsmOperand {
702 /// Broad categories of register classes
703 /// The exact class is finalized by the render method.
705 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
706 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
708 RegKind_FCC = 4, /// FCC
709 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
710 RegKind_MSACtrl = 16, /// MSA control registers
711 RegKind_COP2 = 32, /// COP2
712 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
714 RegKind_CCR = 128, /// CCR
715 RegKind_HWRegs = 256, /// HWRegs
716 RegKind_COP3 = 512, /// COP3
717 RegKind_COP0 = 1024, /// COP0
718 /// Potentially any (e.g. $1)
719 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
720 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
721 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
726 k_Immediate, /// An immediate (possibly involving symbol references)
727 k_Memory, /// Base + Offset Memory Address
728 k_RegisterIndex, /// A register index in one or more RegKind.
729 k_Token, /// A simple token
730 k_RegList, /// A physical register list
731 k_RegPair /// A pair of physical register
735 MipsOperand(KindTy K, MipsAsmParser &Parser)
736 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
738 ~MipsOperand() override {
747 case k_RegisterIndex:
755 /// For diagnostics, and checking the assembler temporary
756 MipsAsmParser &AsmParser;
764 unsigned Index; /// Index into the register class
765 RegKind Kind; /// Bitfield of the kinds it could possibly be
766 struct Token Tok; /// The input token this operand originated from.
767 const MCRegisterInfo *RegInfo;
780 SmallVector<unsigned, 10> *List;
785 struct RegIdxOp RegIdx;
788 struct RegListOp RegList;
791 SMLoc StartLoc, EndLoc;
793 /// Internal constructor for register kinds
794 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
796 const MCRegisterInfo *RegInfo,
798 MipsAsmParser &Parser) {
799 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
800 Op->RegIdx.Index = Index;
801 Op->RegIdx.RegInfo = RegInfo;
802 Op->RegIdx.Kind = RegKind;
803 Op->RegIdx.Tok.Data = Str.data();
804 Op->RegIdx.Tok.Length = Str.size();
811 /// Coerce the register to GPR32 and return the real register for the current
813 unsigned getGPR32Reg() const {
814 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
815 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
816 unsigned ClassID = Mips::GPR32RegClassID;
817 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
820 /// Coerce the register to GPR32 and return the real register for the current
822 unsigned getGPRMM16Reg() const {
823 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
824 unsigned ClassID = Mips::GPR32RegClassID;
825 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
828 /// Coerce the register to GPR64 and return the real register for the current
830 unsigned getGPR64Reg() const {
831 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
832 unsigned ClassID = Mips::GPR64RegClassID;
833 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
837 /// Coerce the register to AFGR64 and return the real register for the current
839 unsigned getAFGR64Reg() const {
840 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
841 if (RegIdx.Index % 2 != 0)
842 AsmParser.Warning(StartLoc, "Float register should be even.");
843 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
844 .getRegister(RegIdx.Index / 2);
847 /// Coerce the register to FGR64 and return the real register for the current
849 unsigned getFGR64Reg() const {
850 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
851 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
852 .getRegister(RegIdx.Index);
855 /// Coerce the register to FGR32 and return the real register for the current
857 unsigned getFGR32Reg() const {
858 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
859 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
860 .getRegister(RegIdx.Index);
863 /// Coerce the register to FGRH32 and return the real register for the current
865 unsigned getFGRH32Reg() const {
866 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
867 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
868 .getRegister(RegIdx.Index);
871 /// Coerce the register to FCC and return the real register for the current
873 unsigned getFCCReg() const {
874 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
875 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
876 .getRegister(RegIdx.Index);
879 /// Coerce the register to MSA128 and return the real register for the current
881 unsigned getMSA128Reg() const {
882 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
883 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
885 unsigned ClassID = Mips::MSA128BRegClassID;
886 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
889 /// Coerce the register to MSACtrl and return the real register for the
891 unsigned getMSACtrlReg() const {
892 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
893 unsigned ClassID = Mips::MSACtrlRegClassID;
894 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
897 /// Coerce the register to COP0 and return the real register for the
899 unsigned getCOP0Reg() const {
900 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
901 unsigned ClassID = Mips::COP0RegClassID;
902 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
905 /// Coerce the register to COP2 and return the real register for the
907 unsigned getCOP2Reg() const {
908 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
909 unsigned ClassID = Mips::COP2RegClassID;
910 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
913 /// Coerce the register to COP3 and return the real register for the
915 unsigned getCOP3Reg() const {
916 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
917 unsigned ClassID = Mips::COP3RegClassID;
918 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
921 /// Coerce the register to ACC64DSP and return the real register for the
923 unsigned getACC64DSPReg() const {
924 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
925 unsigned ClassID = Mips::ACC64DSPRegClassID;
926 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
929 /// Coerce the register to HI32DSP and return the real register for the
931 unsigned getHI32DSPReg() const {
932 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
933 unsigned ClassID = Mips::HI32DSPRegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 /// Coerce the register to LO32DSP and return the real register for the
939 unsigned getLO32DSPReg() const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
941 unsigned ClassID = Mips::LO32DSPRegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 /// Coerce the register to CCR and return the real register for the
947 unsigned getCCRReg() const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
949 unsigned ClassID = Mips::CCRRegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
953 /// Coerce the register to HWRegs and return the real register for the
955 unsigned getHWRegsReg() const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
957 unsigned ClassID = Mips::HWRegsRegClassID;
958 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
962 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
963 // Add as immediate when possible. Null MCExpr = 0.
965 Inst.addOperand(MCOperand::createImm(0));
966 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
967 Inst.addOperand(MCOperand::createImm(CE->getValue()));
969 Inst.addOperand(MCOperand::createExpr(Expr));
972 void addRegOperands(MCInst &Inst, unsigned N) const {
973 llvm_unreachable("Use a custom parser instead");
976 /// Render the operand to an MCInst as a GPR32
977 /// Asserts if the wrong number of operands are requested, or the operand
978 /// is not a k_RegisterIndex compatible with RegKind_GPR
979 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
980 assert(N == 1 && "Invalid number of operands!");
981 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
984 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
985 assert(N == 1 && "Invalid number of operands!");
986 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
989 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
990 assert(N == 1 && "Invalid number of operands!");
991 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
994 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
995 assert(N == 1 && "Invalid number of operands!");
996 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
999 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1000 assert(N == 1 && "Invalid number of operands!");
1001 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1004 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1005 assert(N == 1 && "Invalid number of operands!");
1006 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1009 /// Render the operand to an MCInst as a GPR64
1010 /// Asserts if the wrong number of operands are requested, or the operand
1011 /// is not a k_RegisterIndex compatible with RegKind_GPR
1012 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1013 assert(N == 1 && "Invalid number of operands!");
1014 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1017 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1018 assert(N == 1 && "Invalid number of operands!");
1019 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1022 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1023 assert(N == 1 && "Invalid number of operands!");
1024 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1027 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1028 assert(N == 1 && "Invalid number of operands!");
1029 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1032 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1033 assert(N == 1 && "Invalid number of operands!");
1034 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1037 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1038 assert(N == 1 && "Invalid number of operands!");
1039 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1040 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1041 // FIXME: This should propagate failure up to parseStatement.
1042 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1043 AsmParser.getParser().printError(
1044 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1048 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1049 assert(N == 1 && "Invalid number of operands!");
1050 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1051 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1052 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1053 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1057 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1058 assert(N == 1 && "Invalid number of operands!");
1059 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1062 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1063 assert(N == 1 && "Invalid number of operands!");
1064 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1067 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1068 assert(N == 1 && "Invalid number of operands!");
1069 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1072 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1073 assert(N == 1 && "Invalid number of operands!");
1074 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1077 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1078 assert(N == 1 && "Invalid number of operands!");
1079 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1082 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1083 assert(N == 1 && "Invalid number of operands!");
1084 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1087 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1088 assert(N == 1 && "Invalid number of operands!");
1089 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1092 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1093 assert(N == 1 && "Invalid number of operands!");
1094 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1097 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1098 assert(N == 1 && "Invalid number of operands!");
1099 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1102 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1103 assert(N == 1 && "Invalid number of operands!");
1104 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1107 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1108 assert(N == 1 && "Invalid number of operands!");
1109 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1112 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1113 assert(N == 1 && "Invalid number of operands!");
1114 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1117 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1118 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1119 assert(N == 1 && "Invalid number of operands!");
1120 uint64_t Imm = getConstantImm() - Offset;
1121 Imm &= (1ULL << Bits) - 1;
1123 Imm += AdjustOffset;
1124 Inst.addOperand(MCOperand::createImm(Imm));
1127 template <unsigned Bits>
1128 void addSImmOperands(MCInst &Inst, unsigned N) const {
1129 if (isImm() && !isConstantImm()) {
1130 addExpr(Inst, getImm());
1133 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1136 template <unsigned Bits>
1137 void addUImmOperands(MCInst &Inst, unsigned N) const {
1138 if (isImm() && !isConstantImm()) {
1139 addExpr(Inst, getImm());
1142 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1145 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1146 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1147 assert(N == 1 && "Invalid number of operands!");
1148 int64_t Imm = getConstantImm() - Offset;
1149 Imm = SignExtend64<Bits>(Imm);
1151 Imm += AdjustOffset;
1152 Inst.addOperand(MCOperand::createImm(Imm));
1155 void addImmOperands(MCInst &Inst, unsigned N) const {
1156 assert(N == 1 && "Invalid number of operands!");
1157 const MCExpr *Expr = getImm();
1158 addExpr(Inst, Expr);
1161 void addMemOperands(MCInst &Inst, unsigned N) const {
1162 assert(N == 2 && "Invalid number of operands!");
1164 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1165 ? getMemBase()->getGPR64Reg()
1166 : getMemBase()->getGPR32Reg()));
1168 const MCExpr *Expr = getMemOff();
1169 addExpr(Inst, Expr);
1172 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1173 assert(N == 2 && "Invalid number of operands!");
1175 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1177 const MCExpr *Expr = getMemOff();
1178 addExpr(Inst, Expr);
1181 void addRegListOperands(MCInst &Inst, unsigned N) const {
1182 assert(N == 1 && "Invalid number of operands!");
1184 for (auto RegNo : getRegList())
1185 Inst.addOperand(MCOperand::createReg(RegNo));
1188 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1189 assert(N == 2 && "Invalid number of operands!");
1190 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1191 unsigned RegNo = getRegPair();
1192 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1193 Inst.addOperand(MCOperand::createReg(
1194 RegIdx.RegInfo->getRegClass(
1195 AsmParser.getABI().AreGprs64bit()
1196 ? Mips::GPR64RegClassID
1197 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1198 Inst.addOperand(MCOperand::createReg(
1199 RegIdx.RegInfo->getRegClass(
1200 AsmParser.getABI().AreGprs64bit()
1201 ? Mips::GPR64RegClassID
1202 : Mips::GPR32RegClassID).getRegister(RegNo)));
1205 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1206 assert(N == 2 && "Invalid number of operands!");
1207 for (auto RegNo : getRegList())
1208 Inst.addOperand(MCOperand::createReg(RegNo));
1211 bool isReg() const override {
1212 // As a special case until we sort out the definition of div/divu, accept
1213 // $0/$zero here so that MCK_ZERO works correctly.
1214 return isGPRAsmReg() && RegIdx.Index == 0;
1217 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1218 bool isImm() const override { return Kind == k_Immediate; }
1220 bool isConstantImm() const {
1222 return isImm() && getImm()->evaluateAsAbsolute(Res);
1225 bool isConstantImmz() const {
1226 return isConstantImm() && getConstantImm() == 0;
1229 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1230 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1233 template <unsigned Bits> bool isSImm() const {
1234 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1237 template <unsigned Bits> bool isUImm() const {
1238 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1241 template <unsigned Bits> bool isAnyImm() const {
1242 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1243 isUInt<Bits>(getConstantImm()))
1247 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1248 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1251 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1252 return isConstantImm() && getConstantImm() >= Bottom &&
1253 getConstantImm() <= Top;
1256 bool isToken() const override {
1257 // Note: It's not possible to pretend that other operand kinds are tokens.
1258 // The matcher emitter checks tokens first.
1259 return Kind == k_Token;
1262 bool isMem() const override { return Kind == k_Memory; }
1264 bool isConstantMemOff() const {
1265 return isMem() && isa<MCConstantExpr>(getMemOff());
1268 // Allow relocation operators.
1269 // FIXME: This predicate and others need to look through binary expressions
1270 // and determine whether a Value is a constant or not.
1271 template <unsigned Bits, unsigned ShiftAmount = 0>
1272 bool isMemWithSimmOffset() const {
1275 if (!getMemBase()->isGPRAsmReg())
1277 if (isa<MCTargetExpr>(getMemOff()) ||
1278 (isConstantMemOff() &&
1279 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1282 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1283 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1286 bool isMemWithGRPMM16Base() const {
1287 return isMem() && getMemBase()->isMM16AsmReg();
1290 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1291 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1292 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1295 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1296 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1297 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1298 && (getMemBase()->getGPR32Reg() == Mips::SP);
1301 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1302 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1303 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1304 && (getMemBase()->getGPR32Reg() == Mips::GP);
1307 template <unsigned Bits, unsigned ShiftLeftAmount>
1308 bool isScaledUImm() const {
1309 return isConstantImm() &&
1310 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1313 template <unsigned Bits, unsigned ShiftLeftAmount>
1314 bool isScaledSImm() const {
1315 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1317 // Operand can also be a symbol or symbol plus offset in case of relocations.
1318 if (Kind != k_Immediate)
1321 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1322 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1325 bool isRegList16() const {
1329 int Size = RegList.List->size();
1330 if (Size < 2 || Size > 5)
1333 unsigned R0 = RegList.List->front();
1334 unsigned R1 = RegList.List->back();
1335 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1336 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1339 int PrevReg = *RegList.List->begin();
1340 for (int i = 1; i < Size - 1; i++) {
1341 int Reg = (*(RegList.List))[i];
1342 if ( Reg != PrevReg + 1)
1350 bool isInvNum() const { return Kind == k_Immediate; }
1352 bool isLSAImm() const {
1353 if (!isConstantImm())
1355 int64_t Val = getConstantImm();
1356 return 1 <= Val && Val <= 4;
1359 bool isRegList() const { return Kind == k_RegList; }
1361 bool isMovePRegPair() const {
1362 if (Kind != k_RegList || RegList.List->size() != 2)
1365 unsigned R0 = RegList.List->front();
1366 unsigned R1 = RegList.List->back();
1368 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1369 (R0 == Mips::A1 && R1 == Mips::A3) ||
1370 (R0 == Mips::A2 && R1 == Mips::A3) ||
1371 (R0 == Mips::A0 && R1 == Mips::S5) ||
1372 (R0 == Mips::A0 && R1 == Mips::S6) ||
1373 (R0 == Mips::A0 && R1 == Mips::A1) ||
1374 (R0 == Mips::A0 && R1 == Mips::A2) ||
1375 (R0 == Mips::A0 && R1 == Mips::A3) ||
1376 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1377 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1378 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1379 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1380 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1381 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1382 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1383 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1389 StringRef getToken() const {
1390 assert(Kind == k_Token && "Invalid access!");
1391 return StringRef(Tok.Data, Tok.Length);
1394 bool isRegPair() const {
1395 return Kind == k_RegPair && RegIdx.Index <= 30;
1398 unsigned getReg() const override {
1399 // As a special case until we sort out the definition of div/divu, accept
1400 // $0/$zero here so that MCK_ZERO works correctly.
1401 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1402 RegIdx.Kind & RegKind_GPR)
1403 return getGPR32Reg(); // FIXME: GPR64 too
1405 llvm_unreachable("Invalid access!");
1409 const MCExpr *getImm() const {
1410 assert((Kind == k_Immediate) && "Invalid access!");
1414 int64_t getConstantImm() const {
1415 const MCExpr *Val = getImm();
1417 (void)Val->evaluateAsAbsolute(Value);
1421 MipsOperand *getMemBase() const {
1422 assert((Kind == k_Memory) && "Invalid access!");
1426 const MCExpr *getMemOff() const {
1427 assert((Kind == k_Memory) && "Invalid access!");
1431 int64_t getConstantMemOff() const {
1432 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1435 const SmallVectorImpl<unsigned> &getRegList() const {
1436 assert((Kind == k_RegList) && "Invalid access!");
1437 return *(RegList.List);
1440 unsigned getRegPair() const {
1441 assert((Kind == k_RegPair) && "Invalid access!");
1442 return RegIdx.Index;
1445 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1446 MipsAsmParser &Parser) {
1447 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1448 Op->Tok.Data = Str.data();
1449 Op->Tok.Length = Str.size();
1455 /// Create a numeric register (e.g. $1). The exact register remains
1456 /// unresolved until an instruction successfully matches
1457 static std::unique_ptr<MipsOperand>
1458 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1459 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1460 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1461 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1464 /// Create a register that is definitely a GPR.
1465 /// This is typically only used for named registers such as $gp.
1466 static std::unique_ptr<MipsOperand>
1467 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1468 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1469 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1472 /// Create a register that is definitely a FGR.
1473 /// This is typically only used for named registers such as $f0.
1474 static std::unique_ptr<MipsOperand>
1475 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1476 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1477 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1480 /// Create a register that is definitely a HWReg.
1481 /// This is typically only used for named registers such as $hwr_cpunum.
1482 static std::unique_ptr<MipsOperand>
1483 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1484 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1485 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1488 /// Create a register that is definitely an FCC.
1489 /// This is typically only used for named registers such as $fcc0.
1490 static std::unique_ptr<MipsOperand>
1491 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1492 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1493 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1496 /// Create a register that is definitely an ACC.
1497 /// This is typically only used for named registers such as $ac0.
1498 static std::unique_ptr<MipsOperand>
1499 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1500 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1501 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1504 /// Create a register that is definitely an MSA128.
1505 /// This is typically only used for named registers such as $w0.
1506 static std::unique_ptr<MipsOperand>
1507 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1508 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1509 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1512 /// Create a register that is definitely an MSACtrl.
1513 /// This is typically only used for named registers such as $msaaccess.
1514 static std::unique_ptr<MipsOperand>
1515 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1516 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1517 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1520 static std::unique_ptr<MipsOperand>
1521 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1522 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1529 static std::unique_ptr<MipsOperand>
1530 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1531 SMLoc E, MipsAsmParser &Parser) {
1532 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1533 Op->Mem.Base = Base.release();
1540 static std::unique_ptr<MipsOperand>
1541 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1542 MipsAsmParser &Parser) {
1543 assert(Regs.size() > 0 && "Empty list not allowed");
1545 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1546 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1547 Op->StartLoc = StartLoc;
1548 Op->EndLoc = EndLoc;
1552 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1554 MipsAsmParser &Parser) {
1555 auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
1556 Op->RegIdx.Index = MOP.RegIdx.Index;
1557 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1558 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1564 bool isGPRZeroAsmReg() const {
1565 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1568 bool isGPRNonZeroAsmReg() const {
1569 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1573 bool isGPRAsmReg() const {
1574 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1577 bool isMM16AsmReg() const {
1578 if (!(isRegIdx() && RegIdx.Kind))
1580 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1581 || RegIdx.Index == 16 || RegIdx.Index == 17);
1584 bool isMM16AsmRegZero() const {
1585 if (!(isRegIdx() && RegIdx.Kind))
1587 return (RegIdx.Index == 0 ||
1588 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1589 RegIdx.Index == 17);
1592 bool isMM16AsmRegMoveP() const {
1593 if (!(isRegIdx() && RegIdx.Kind))
1595 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1596 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1599 bool isFGRAsmReg() const {
1600 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1601 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1604 bool isStrictlyFGRAsmReg() const {
1605 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1606 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1609 bool isHWRegsAsmReg() const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1613 bool isCCRAsmReg() const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1617 bool isFCCAsmReg() const {
1618 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1620 return RegIdx.Index <= 7;
1623 bool isACCAsmReg() const {
1624 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1627 bool isCOP0AsmReg() const {
1628 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1631 bool isCOP2AsmReg() const {
1632 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1635 bool isCOP3AsmReg() const {
1636 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1639 bool isMSA128AsmReg() const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1643 bool isMSACtrlAsmReg() const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1647 /// getStartLoc - Get the location of the first token of this operand.
1648 SMLoc getStartLoc() const override { return StartLoc; }
1649 /// getEndLoc - Get the location of the last token of this operand.
1650 SMLoc getEndLoc() const override { return EndLoc; }
1652 void print(raw_ostream &OS) const override {
1661 Mem.Base->print(OS);
1666 case k_RegisterIndex:
1667 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1668 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1675 for (auto Reg : (*RegList.List))
1680 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1685 bool isValidForTie(const MipsOperand &Other) const {
1686 if (Kind != Other.Kind)
1691 llvm_unreachable("Unexpected kind");
1693 case k_RegisterIndex: {
1694 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1695 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1696 return Token == OtherToken;
1700 }; // class MipsOperand
1702 } // end anonymous namespace
1706 extern const MCInstrDesc MipsInsts[];
1708 } // end namespace llvm
1710 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1711 return MipsInsts[Opcode];
1714 static bool hasShortDelaySlot(unsigned Opcode) {
1717 case Mips::JALRS_MM:
1718 case Mips::JALRS16_MM:
1719 case Mips::BGEZALS_MM:
1720 case Mips::BLTZALS_MM:
1727 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1728 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1729 return &SRExpr->getSymbol();
1732 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1733 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1734 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1745 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1746 return getSingleMCSymbol(UExpr->getSubExpr());
1751 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1752 if (isa<MCSymbolRefExpr>(Expr))
1755 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1756 return countMCSymbolRefExpr(BExpr->getLHS()) +
1757 countMCSymbolRefExpr(BExpr->getRHS());
1759 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1760 return countMCSymbolRefExpr(UExpr->getSubExpr());
1765 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1767 const MCSubtargetInfo *STI) {
1768 MipsTargetStreamer &TOut = getTargetStreamer();
1769 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1770 bool ExpandedJalSym = false;
1774 if (MCID.isBranch() || MCID.isCall()) {
1775 const unsigned Opcode = Inst.getOpcode();
1785 assert(hasCnMips() && "instruction only valid for octeon cpus");
1792 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1793 Offset = Inst.getOperand(2);
1794 if (!Offset.isImm())
1795 break; // We'll deal with this situation later on when applying fixups.
1796 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1797 return Error(IDLoc, "branch target out of range");
1798 if (OffsetToAlignment(Offset.getImm(),
1799 1LL << (inMicroMipsMode() ? 1 : 2)))
1800 return Error(IDLoc, "branch to misaligned address");
1814 case Mips::BGEZAL_MM:
1815 case Mips::BLTZAL_MM:
1818 case Mips::BC1EQZC_MMR6:
1819 case Mips::BC1NEZC_MMR6:
1820 case Mips::BC2EQZC_MMR6:
1821 case Mips::BC2NEZC_MMR6:
1822 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1823 Offset = Inst.getOperand(1);
1824 if (!Offset.isImm())
1825 break; // We'll deal with this situation later on when applying fixups.
1826 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1827 return Error(IDLoc, "branch target out of range");
1828 if (OffsetToAlignment(Offset.getImm(),
1829 1LL << (inMicroMipsMode() ? 1 : 2)))
1830 return Error(IDLoc, "branch to misaligned address");
1832 case Mips::BGEC: case Mips::BGEC_MMR6:
1833 case Mips::BLTC: case Mips::BLTC_MMR6:
1834 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1835 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1836 case Mips::BEQC: case Mips::BEQC_MMR6:
1837 case Mips::BNEC: case Mips::BNEC_MMR6:
1838 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1839 Offset = Inst.getOperand(2);
1840 if (!Offset.isImm())
1841 break; // We'll deal with this situation later on when applying fixups.
1842 if (!isIntN(18, Offset.getImm()))
1843 return Error(IDLoc, "branch target out of range");
1844 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1845 return Error(IDLoc, "branch to misaligned address");
1847 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1848 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1849 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1850 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1851 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1852 Offset = Inst.getOperand(1);
1853 if (!Offset.isImm())
1854 break; // We'll deal with this situation later on when applying fixups.
1855 if (!isIntN(18, Offset.getImm()))
1856 return Error(IDLoc, "branch target out of range");
1857 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1858 return Error(IDLoc, "branch to misaligned address");
1860 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1861 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1862 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1863 Offset = Inst.getOperand(1);
1864 if (!Offset.isImm())
1865 break; // We'll deal with this situation later on when applying fixups.
1866 if (!isIntN(23, Offset.getImm()))
1867 return Error(IDLoc, "branch target out of range");
1868 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1869 return Error(IDLoc, "branch to misaligned address");
1871 case Mips::BEQZ16_MM:
1872 case Mips::BEQZC16_MMR6:
1873 case Mips::BNEZ16_MM:
1874 case Mips::BNEZC16_MMR6:
1875 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1876 Offset = Inst.getOperand(1);
1877 if (!Offset.isImm())
1878 break; // We'll deal with this situation later on when applying fixups.
1879 if (!isInt<8>(Offset.getImm()))
1880 return Error(IDLoc, "branch target out of range");
1881 if (OffsetToAlignment(Offset.getImm(), 2LL))
1882 return Error(IDLoc, "branch to misaligned address");
1887 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1888 // We still accept it but it is a normal nop.
1889 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1890 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1891 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1896 const unsigned Opcode = Inst.getOpcode();
1908 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1909 // The offset is handled above
1910 Opnd = Inst.getOperand(1);
1912 return Error(IDLoc, "expected immediate operand kind");
1913 Imm = Opnd.getImm();
1914 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1915 Opcode == Mips::BBIT1 ? 63 : 31))
1916 return Error(IDLoc, "immediate operand value out of range");
1918 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1920 Inst.getOperand(1).setImm(Imm - 32);
1926 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1927 Opnd = Inst.getOperand(2);
1929 return Error(IDLoc, "expected immediate operand kind");
1930 Imm = Opnd.getImm();
1931 if (!isInt<10>(Imm))
1932 return Error(IDLoc, "immediate operand value out of range");
1937 // Warn on division by zero. We're checking here as all instructions get
1938 // processed here, not just the macros that need expansion.
1940 // The MIPS backend models most of the divison instructions and macros as
1941 // three operand instructions. The pre-R6 divide instructions however have
1942 // two operands and explicitly define HI/LO as part of the instruction,
1943 // not in the operands.
1944 unsigned FirstOp = 1;
1945 unsigned SecondOp = 2;
1946 switch (Inst.getOpcode()) {
1949 case Mips::SDivIMacro:
1950 case Mips::UDivIMacro:
1951 case Mips::DSDivIMacro:
1952 case Mips::DUDivIMacro:
1953 if (Inst.getOperand(2).getImm() == 0) {
1954 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1955 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1956 Warning(IDLoc, "dividing zero by zero");
1958 Warning(IDLoc, "division by zero");
1969 case Mips::SDivMacro:
1970 case Mips::DSDivMacro:
1971 case Mips::UDivMacro:
1972 case Mips::DUDivMacro:
1977 case Mips::DIVU_MMR6:
1978 case Mips::DDIVU_MM64R6:
1979 case Mips::DIV_MMR6:
1980 case Mips::DDIV_MM64R6:
1981 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1982 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1983 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1984 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1985 Warning(IDLoc, "dividing zero by zero");
1987 Warning(IDLoc, "division by zero");
1992 // For PIC code convert unconditional jump to unconditional branch.
1993 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1996 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1997 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1998 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1999 BInst.addOperand(Inst.getOperand(0));
2003 // This expansion is not in a function called by tryExpandInstruction()
2004 // because the pseudo-instruction doesn't have a distinct opcode.
2005 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2007 warnIfNoMacro(IDLoc);
2009 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2011 // We can do this expansion if there's only 1 symbol in the argument
2013 if (countMCSymbolRefExpr(JalExpr) > 1)
2014 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2016 // FIXME: This is checking the expression can be handled by the later stages
2017 // of the assembler. We ought to leave it to those later stages.
2018 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2020 // FIXME: Add support for label+offset operands (currently causes an error).
2021 // FIXME: Add support for forward-declared local symbols.
2022 // FIXME: Add expansion for when the LargeGOT option is enabled.
2023 if (JalSym->isInSection() || JalSym->isTemporary() ||
2024 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2026 // If it's a local symbol and the O32 ABI is being used, we expand to:
2028 // R_(MICRO)MIPS_GOT16 label
2029 // addiu $25, $25, 0
2030 // R_(MICRO)MIPS_LO16 label
2032 const MCExpr *Got16RelocExpr =
2033 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2034 const MCExpr *Lo16RelocExpr =
2035 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2037 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2038 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2039 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2040 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2041 } else if (isABI_N32() || isABI_N64()) {
2042 // If it's a local symbol and the N32/N64 ABIs are being used,
2044 // lw/ld $25, 0($gp)
2045 // R_(MICRO)MIPS_GOT_DISP label
2047 const MCExpr *GotDispRelocExpr =
2048 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2050 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2051 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2055 // If it's an external/weak symbol, we expand to:
2056 // lw/ld $25, 0($gp)
2057 // R_(MICRO)MIPS_CALL16 label
2059 const MCExpr *Call16RelocExpr =
2060 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2062 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2063 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2067 if (IsCpRestoreSet && inMicroMipsMode())
2068 JalrInst.setOpcode(Mips::JALRS_MM);
2070 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2071 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2072 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2074 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
2075 // This relocation is supposed to be an optimization hint for the linker
2076 // and is not necessary for correctness.
2079 ExpandedJalSym = true;
2082 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2083 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2084 // Check the offset of memory operand, if it is a symbol
2085 // reference or immediate we may have to expand instructions.
2086 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2087 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2088 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2089 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2090 MCOperand &Op = Inst.getOperand(i);
2092 int MemOffset = Op.getImm();
2093 if (MemOffset < -32768 || MemOffset > 32767) {
2094 // Offset can't exceed 16bit value.
2095 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
2096 return getParser().hasPendingError();
2098 } else if (Op.isExpr()) {
2099 const MCExpr *Expr = Op.getExpr();
2100 if (Expr->getKind() == MCExpr::SymbolRef) {
2101 const MCSymbolRefExpr *SR =
2102 static_cast<const MCSymbolRefExpr *>(Expr);
2103 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2105 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2106 return getParser().hasPendingError();
2108 } else if (!isEvaluated(Expr)) {
2109 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2110 return getParser().hasPendingError();
2117 if (inMicroMipsMode()) {
2118 if (MCID.mayLoad()) {
2119 // Try to create 16-bit GP relative load instruction.
2120 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2121 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2122 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2123 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2124 MCOperand &Op = Inst.getOperand(i);
2126 int MemOffset = Op.getImm();
2127 MCOperand &DstReg = Inst.getOperand(0);
2128 MCOperand &BaseReg = Inst.getOperand(1);
2129 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2130 getContext().getRegisterInfo()->getRegClass(
2131 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2132 (BaseReg.getReg() == Mips::GP ||
2133 BaseReg.getReg() == Mips::GP_64)) {
2135 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2144 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2149 switch (Inst.getOpcode()) {
2152 case Mips::ADDIUSP_MM:
2153 Opnd = Inst.getOperand(0);
2155 return Error(IDLoc, "expected immediate operand kind");
2156 Imm = Opnd.getImm();
2157 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2159 return Error(IDLoc, "immediate operand value out of range");
2161 case Mips::SLL16_MM:
2162 case Mips::SRL16_MM:
2163 Opnd = Inst.getOperand(2);
2165 return Error(IDLoc, "expected immediate operand kind");
2166 Imm = Opnd.getImm();
2167 if (Imm < 1 || Imm > 8)
2168 return Error(IDLoc, "immediate operand value out of range");
2171 Opnd = Inst.getOperand(1);
2173 return Error(IDLoc, "expected immediate operand kind");
2174 Imm = Opnd.getImm();
2175 if (Imm < -1 || Imm > 126)
2176 return Error(IDLoc, "immediate operand value out of range");
2178 case Mips::ADDIUR2_MM:
2179 Opnd = Inst.getOperand(2);
2181 return Error(IDLoc, "expected immediate operand kind");
2182 Imm = Opnd.getImm();
2183 if (!(Imm == 1 || Imm == -1 ||
2184 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2185 return Error(IDLoc, "immediate operand value out of range");
2187 case Mips::ANDI16_MM:
2188 Opnd = Inst.getOperand(2);
2190 return Error(IDLoc, "expected immediate operand kind");
2191 Imm = Opnd.getImm();
2192 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2193 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2194 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2195 return Error(IDLoc, "immediate operand value out of range");
2197 case Mips::LBU16_MM:
2198 Opnd = Inst.getOperand(2);
2200 return Error(IDLoc, "expected immediate operand kind");
2201 Imm = Opnd.getImm();
2202 if (Imm < -1 || Imm > 14)
2203 return Error(IDLoc, "immediate operand value out of range");
2206 case Mips::SB16_MMR6:
2207 Opnd = Inst.getOperand(2);
2209 return Error(IDLoc, "expected immediate operand kind");
2210 Imm = Opnd.getImm();
2211 if (Imm < 0 || Imm > 15)
2212 return Error(IDLoc, "immediate operand value out of range");
2214 case Mips::LHU16_MM:
2216 case Mips::SH16_MMR6:
2217 Opnd = Inst.getOperand(2);
2219 return Error(IDLoc, "expected immediate operand kind");
2220 Imm = Opnd.getImm();
2221 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2222 return Error(IDLoc, "immediate operand value out of range");
2226 case Mips::SW16_MMR6:
2227 Opnd = Inst.getOperand(2);
2229 return Error(IDLoc, "expected immediate operand kind");
2230 Imm = Opnd.getImm();
2231 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2232 return Error(IDLoc, "immediate operand value out of range");
2234 case Mips::ADDIUPC_MM:
2235 MCOperand Opnd = Inst.getOperand(1);
2237 return Error(IDLoc, "expected immediate operand kind");
2238 int Imm = Opnd.getImm();
2239 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2240 return Error(IDLoc, "immediate operand value out of range");
2245 bool FillDelaySlot =
2246 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2248 TOut.emitDirectiveSetNoReorder();
2250 MacroExpanderResultTy ExpandResult =
2251 tryExpandInstruction(Inst, IDLoc, Out, STI);
2252 switch (ExpandResult) {
2254 Out.EmitInstruction(Inst, *STI);
2262 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2263 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2264 if (inMicroMipsMode())
2265 TOut.setUsesMicroMips();
2267 // If this instruction has a delay slot and .set reorder is active,
2268 // emit a NOP after it.
2269 if (FillDelaySlot) {
2270 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2271 TOut.emitDirectiveSetReorder();
2274 if ((Inst.getOpcode() == Mips::JalOneReg ||
2275 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2276 isPicAndNotNxxAbi()) {
2277 if (IsCpRestoreSet) {
2278 // We need a NOP between the JALR and the LW:
2279 // If .set reorder has been used, we've already emitted a NOP.
2280 // If .set noreorder has been used, we need to emit a NOP at this point.
2281 if (!AssemblerOptions.back()->isReorder())
2282 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2285 // Load the $gp from the stack.
2286 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2288 Warning(IDLoc, "no .cprestore used in PIC mode");
2294 MipsAsmParser::MacroExpanderResultTy
2295 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2296 const MCSubtargetInfo *STI) {
2297 switch (Inst.getOpcode()) {
2299 return MER_NotAMacro;
2300 case Mips::LoadImm32:
2301 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2302 case Mips::LoadImm64:
2303 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2304 case Mips::LoadAddrImm32:
2305 case Mips::LoadAddrImm64:
2306 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2307 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2308 "expected immediate operand kind");
2310 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2312 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2316 case Mips::LoadAddrReg32:
2317 case Mips::LoadAddrReg64:
2318 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2319 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2320 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2321 "expected immediate operand kind");
2323 return expandLoadAddress(Inst.getOperand(0).getReg(),
2324 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2325 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2329 case Mips::B_MM_Pseudo:
2330 case Mips::B_MMR6_Pseudo:
2331 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2335 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2337 case Mips::JalOneReg:
2338 case Mips::JalTwoReg:
2339 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2342 case Mips::BEQLImmMacro:
2343 case Mips::BNELImmMacro:
2344 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2361 case Mips::BLTImmMacro:
2362 case Mips::BLEImmMacro:
2363 case Mips::BGEImmMacro:
2364 case Mips::BGTImmMacro:
2365 case Mips::BLTUImmMacro:
2366 case Mips::BLEUImmMacro:
2367 case Mips::BGEUImmMacro:
2368 case Mips::BGTUImmMacro:
2369 case Mips::BLTLImmMacro:
2370 case Mips::BLELImmMacro:
2371 case Mips::BGELImmMacro:
2372 case Mips::BGTLImmMacro:
2373 case Mips::BLTULImmMacro:
2374 case Mips::BLEULImmMacro:
2375 case Mips::BGEULImmMacro:
2376 case Mips::BGTULImmMacro:
2377 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2378 case Mips::SDivMacro:
2379 case Mips::SDivIMacro:
2380 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2382 case Mips::DSDivMacro:
2383 case Mips::DSDivIMacro:
2384 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2386 case Mips::UDivMacro:
2387 case Mips::UDivIMacro:
2388 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2390 case Mips::DUDivMacro:
2391 case Mips::DUDivIMacro:
2392 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2394 case Mips::PseudoTRUNC_W_S:
2395 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2397 case Mips::PseudoTRUNC_W_D32:
2398 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2400 case Mips::PseudoTRUNC_W_D:
2401 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2404 case Mips::LoadImmSingleGPR:
2405 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2408 case Mips::LoadImmSingleFGR:
2409 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2412 case Mips::LoadImmDoubleGPR:
2413 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2416 case Mips::LoadImmDoubleFGR:
2417 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2420 case Mips::LoadImmDoubleFGR_32:
2421 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2425 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2427 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2429 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2432 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2434 case Mips::NORImm64:
2435 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2436 case Mips::SLTImm64:
2437 if (isInt<16>(Inst.getOperand(2).getImm())) {
2438 Inst.setOpcode(Mips::SLTi64);
2439 return MER_NotAMacro;
2441 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2442 case Mips::SLTUImm64:
2443 if (isInt<16>(Inst.getOperand(2).getImm())) {
2444 Inst.setOpcode(Mips::SLTiu64);
2445 return MER_NotAMacro;
2447 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::ADDi: case Mips::ADDi_MM:
2449 case Mips::ADDiu: case Mips::ADDiu_MM:
2450 case Mips::SLTi: case Mips::SLTi_MM:
2451 case Mips::SLTiu: case Mips::SLTiu_MM:
2452 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2453 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2454 int64_t ImmValue = Inst.getOperand(2).getImm();
2455 if (isInt<16>(ImmValue))
2456 return MER_NotAMacro;
2457 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2460 return MER_NotAMacro;
2461 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2462 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2463 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2464 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2465 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2466 int64_t ImmValue = Inst.getOperand(2).getImm();
2467 if (isUInt<16>(ImmValue))
2468 return MER_NotAMacro;
2469 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2472 return MER_NotAMacro;
2475 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2478 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2481 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2485 case Mips::ABSMacro:
2486 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2487 case Mips::MULImmMacro:
2488 case Mips::DMULImmMacro:
2489 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 case Mips::MULOMacro:
2491 case Mips::DMULOMacro:
2492 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 case Mips::MULOUMacro:
2494 case Mips::DMULOUMacro:
2495 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2496 case Mips::DMULMacro:
2497 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2500 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2501 Inst.getOpcode() == Mips::LDMacro)
2504 case Mips::SEQMacro:
2505 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2506 case Mips::SEQIMacro:
2507 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2511 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2513 const MCSubtargetInfo *STI) {
2514 MipsTargetStreamer &TOut = getTargetStreamer();
2516 // Create a JALR instruction which is going to replace the pseudo-JAL.
2518 JalrInst.setLoc(IDLoc);
2519 const MCOperand FirstRegOp = Inst.getOperand(0);
2520 const unsigned Opcode = Inst.getOpcode();
2522 if (Opcode == Mips::JalOneReg) {
2523 // jal $rs => jalr $rs
2524 if (IsCpRestoreSet && inMicroMipsMode()) {
2525 JalrInst.setOpcode(Mips::JALRS16_MM);
2526 JalrInst.addOperand(FirstRegOp);
2527 } else if (inMicroMipsMode()) {
2528 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2529 JalrInst.addOperand(FirstRegOp);
2531 JalrInst.setOpcode(Mips::JALR);
2532 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2533 JalrInst.addOperand(FirstRegOp);
2535 } else if (Opcode == Mips::JalTwoReg) {
2536 // jal $rd, $rs => jalr $rd, $rs
2537 if (IsCpRestoreSet && inMicroMipsMode())
2538 JalrInst.setOpcode(Mips::JALRS_MM);
2540 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2541 JalrInst.addOperand(FirstRegOp);
2542 const MCOperand SecondRegOp = Inst.getOperand(1);
2543 JalrInst.addOperand(SecondRegOp);
2545 Out.EmitInstruction(JalrInst, *STI);
2547 // If .set reorder is active and branch instruction has a delay slot,
2548 // emit a NOP after it.
2549 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2550 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2551 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2557 /// Can the value be represented by a unsigned N-bit value and a shift left?
2558 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2559 unsigned BitNum = findFirstSet(x);
2561 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2564 /// Load (or add) an immediate into a register.
2566 /// @param ImmValue The immediate to load.
2567 /// @param DstReg The register that will hold the immediate.
2568 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2569 /// for a simple initialization.
2570 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2571 /// @param IsAddress True if the immediate represents an address. False if it
2573 /// @param IDLoc Location of the immediate in the source file.
2574 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2575 unsigned SrcReg, bool Is32BitImm,
2576 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2577 const MCSubtargetInfo *STI) {
2578 MipsTargetStreamer &TOut = getTargetStreamer();
2580 if (!Is32BitImm && !isGP64bit()) {
2581 Error(IDLoc, "instruction requires a 64-bit architecture");
2586 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2587 // Sign extend up to 64-bit so that the predicates match the hardware
2588 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2590 ImmValue = SignExtend64<32>(ImmValue);
2592 Error(IDLoc, "instruction requires a 32-bit immediate");
2597 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2598 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2600 bool UseSrcReg = false;
2601 if (SrcReg != Mips::NoRegister)
2604 unsigned TmpReg = DstReg;
2606 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2607 // At this point we need AT to perform the expansions and we exit if it is
2609 unsigned ATReg = getATReg(IDLoc);
2615 if (isInt<16>(ImmValue)) {
2619 // This doesn't quite follow the usual ABI expectations for N32 but matches
2620 // traditional assembler behaviour. N32 would normally use addiu for both
2621 // integers and addresses.
2622 if (IsAddress && !Is32BitImm) {
2623 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2627 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2631 if (isUInt<16>(ImmValue)) {
2632 unsigned TmpReg = DstReg;
2633 if (SrcReg == DstReg) {
2634 TmpReg = getATReg(IDLoc);
2639 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2641 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2645 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2646 warnIfNoMacro(IDLoc);
2648 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2649 uint16_t Bits15To0 = ImmValue & 0xffff;
2650 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2651 // Traditional behaviour seems to special case this particular value. It's
2652 // not clear why other masks are handled differently.
2653 if (ImmValue == 0xffffffff) {
2654 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2655 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2657 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2661 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2663 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2664 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2666 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2668 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2672 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2674 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2676 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2680 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2682 Error(IDLoc, "instruction requires a 32-bit immediate");
2686 // Traditionally, these immediates are shifted as little as possible and as
2687 // such we align the most significant bit to bit 15 of our temporary.
2688 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2689 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2690 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2691 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2692 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2693 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2696 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2701 warnIfNoMacro(IDLoc);
2703 // The remaining case is packed with a sequence of dsll and ori with zeros
2704 // being omitted and any neighbouring dsll's being coalesced.
2705 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2707 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2708 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2712 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2713 // skip it and defer the shift to the next chunk.
2714 unsigned ShiftCarriedForwards = 16;
2715 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2716 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2718 if (ImmChunk != 0) {
2719 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2720 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2721 ShiftCarriedForwards = 0;
2724 ShiftCarriedForwards += 16;
2726 ShiftCarriedForwards -= 16;
2728 // Finish any remaining shifts left by trailing zeros.
2729 if (ShiftCarriedForwards)
2730 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2733 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2738 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2739 MCStreamer &Out, const MCSubtargetInfo *STI) {
2740 const MCOperand &ImmOp = Inst.getOperand(1);
2741 assert(ImmOp.isImm() && "expected immediate operand kind");
2742 const MCOperand &DstRegOp = Inst.getOperand(0);
2743 assert(DstRegOp.isReg() && "expected register operand kind");
2745 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2746 Is32BitImm, false, IDLoc, Out, STI))
2752 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2753 const MCOperand &Offset,
2754 bool Is32BitAddress, SMLoc IDLoc,
2756 const MCSubtargetInfo *STI) {
2757 // la can't produce a usable address when addresses are 64-bit.
2758 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2759 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2760 // We currently can't do this because we depend on the equality
2761 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2762 Error(IDLoc, "la used to load 64-bit address");
2763 // Continue as if we had 'dla' instead.
2764 Is32BitAddress = false;
2768 // dla requires 64-bit addresses.
2769 if (!Is32BitAddress && !hasMips3()) {
2770 Error(IDLoc, "instruction requires a 64-bit architecture");
2774 if (!Offset.isImm())
2775 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2776 Is32BitAddress, IDLoc, Out, STI);
2778 if (!ABI.ArePtrs64bit()) {
2779 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2780 Is32BitAddress = true;
2783 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2787 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2788 unsigned DstReg, unsigned SrcReg,
2789 bool Is32BitSym, SMLoc IDLoc,
2791 const MCSubtargetInfo *STI) {
2792 // FIXME: These expansions do not respect -mxgot.
2793 MipsTargetStreamer &TOut = getTargetStreamer();
2794 bool UseSrcReg = SrcReg != Mips::NoRegister;
2795 warnIfNoMacro(IDLoc);
2797 if (inPicMode() && ABI.IsO32()) {
2799 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2800 Error(IDLoc, "expected relocatable expression");
2803 if (Res.getSymB() != nullptr) {
2804 Error(IDLoc, "expected relocatable expression with only one symbol");
2808 // The case where the result register is $25 is somewhat special. If the
2809 // symbol in the final relocation is external and not modified with a
2810 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2811 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2812 Res.getConstant() == 0 &&
2813 !(Res.getSymA()->getSymbol().isInSection() ||
2814 Res.getSymA()->getSymbol().isTemporary() ||
2815 (Res.getSymA()->getSymbol().isELF() &&
2816 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2818 const MCExpr *CallExpr =
2819 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2820 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2821 MCOperand::createExpr(CallExpr), IDLoc, STI);
2825 // The remaining cases are:
2826 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2827 // >addiu $tmp, $tmp, %lo(offset)
2828 // >addiu $rd, $tmp, $rs
2829 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2830 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2831 // >addiu $rd, $tmp, $rs
2832 // The addiu's marked with a '>' may be omitted if they are redundant. If
2833 // this happens then the last instruction must use $rd as the result
2835 const MipsMCExpr *GotExpr =
2836 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2837 const MCExpr *LoExpr = nullptr;
2838 if (Res.getSymA()->getSymbol().isInSection() ||
2839 Res.getSymA()->getSymbol().isTemporary())
2840 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2841 else if (Res.getConstant() != 0) {
2842 // External symbols fully resolve the symbol with just the %got(symbol)
2843 // but we must still account for any offset to the symbol for expressions
2845 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2848 unsigned TmpReg = DstReg;
2850 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2852 // If $rs is the same as $rd, we need to use AT.
2853 // If it is not available we exit.
2854 unsigned ATReg = getATReg(IDLoc);
2860 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2861 MCOperand::createExpr(GotExpr), IDLoc, STI);
2864 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2868 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2873 if (inPicMode() && ABI.ArePtrs64bit()) {
2875 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2876 Error(IDLoc, "expected relocatable expression");
2879 if (Res.getSymB() != nullptr) {
2880 Error(IDLoc, "expected relocatable expression with only one symbol");
2884 // The case where the result register is $25 is somewhat special. If the
2885 // symbol in the final relocation is external and not modified with a
2886 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2887 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2888 Res.getConstant() == 0 &&
2889 !(Res.getSymA()->getSymbol().isInSection() ||
2890 Res.getSymA()->getSymbol().isTemporary() ||
2891 (Res.getSymA()->getSymbol().isELF() &&
2892 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2894 const MCExpr *CallExpr =
2895 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2896 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2897 MCOperand::createExpr(CallExpr), IDLoc, STI);
2901 // The remaining cases are:
2902 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2903 // >daddiu $tmp, $tmp, offset
2904 // >daddu $rd, $tmp, $rs
2905 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2906 // this happens then the last instruction must use $rd as the result
2908 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2911 const MCExpr *LoExpr = nullptr;
2912 if (Res.getConstant() != 0) {
2913 // Symbols fully resolve with just the %got_disp(symbol) but we
2914 // must still account for any offset to the symbol for
2915 // expressions like symbol+8.
2916 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2918 // FIXME: Offsets greater than 16 bits are not yet implemented.
2919 // FIXME: The correct range is a 32-bit sign-extended number.
2920 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2921 Error(IDLoc, "macro instruction uses large offset, which is not "
2922 "currently supported");
2927 unsigned TmpReg = DstReg;
2929 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2931 // If $rs is the same as $rd, we need to use AT.
2932 // If it is not available we exit.
2933 unsigned ATReg = getATReg(IDLoc);
2939 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
2940 MCOperand::createExpr(GotExpr), IDLoc, STI);
2943 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2947 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2952 const MipsMCExpr *HiExpr =
2953 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2954 const MipsMCExpr *LoExpr =
2955 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2957 // This is the 64-bit symbol address expansion.
2958 if (ABI.ArePtrs64bit() && isGP64bit()) {
2959 // We need AT for the 64-bit expansion in the cases where the optional
2960 // source register is the destination register and for the superscalar
2963 // If it is not available we exit if the destination is the same as the
2966 const MipsMCExpr *HighestExpr =
2967 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2968 const MipsMCExpr *HigherExpr =
2969 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2972 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
2974 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
2975 unsigned ATReg = getATReg(IDLoc);
2977 // If $rs is the same as $rd:
2978 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2979 // daddiu $at, $at, %higher(sym)
2980 // dsll $at, $at, 16
2981 // daddiu $at, $at, %hi(sym)
2982 // dsll $at, $at, 16
2983 // daddiu $at, $at, %lo(sym)
2984 // daddu $rd, $at, $rd
2985 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2987 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2988 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2989 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2990 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2992 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2993 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2995 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2998 } else if (canUseATReg() && !RdRegIsRsReg) {
2999 unsigned ATReg = getATReg(IDLoc);
3001 // If the $rs is different from $rd or if $rs isn't specified and we
3002 // have $at available:
3003 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3004 // lui $at, %hi(sym)
3005 // daddiu $rd, $rd, %higher(sym)
3006 // daddiu $at, $at, %lo(sym)
3007 // dsll32 $rd, $rd, 0
3008 // daddu $rd, $rd, $at
3009 // (daddu $rd, $rd, $rs)
3011 // Which is preferred for superscalar issue.
3012 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3014 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3015 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3016 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3017 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3019 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3020 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3022 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3025 } else if (!canUseATReg() && !RdRegIsRsReg) {
3026 // Otherwise, synthesize the address in the destination register
3028 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3029 // daddiu $rd, $rd, %higher(sym)
3030 // dsll $rd, $rd, 16
3031 // daddiu $rd, $rd, %hi(sym)
3032 // dsll $rd, $rd, 16
3033 // daddiu $rd, $rd, %lo(sym)
3034 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3036 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3037 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3038 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3039 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3040 MCOperand::createExpr(HiExpr), IDLoc, STI);
3041 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3042 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3043 MCOperand::createExpr(LoExpr), IDLoc, STI);
3045 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3049 // We have a case where SrcReg == DstReg and we don't have $at
3050 // available. We can't expand this case, so error out appropriately.
3051 assert(SrcReg == DstReg && !canUseATReg() &&
3052 "Could have expanded dla but didn't?");
3053 reportParseError(IDLoc,
3054 "pseudo-instruction requires $at, which is not available");
3059 // And now, the 32-bit symbol address expansion:
3060 // If $rs is the same as $rd:
3061 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3062 // ori $at, $at, %lo(sym)
3063 // addu $rd, $at, $rd
3064 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3065 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3066 // ori $rd, $rd, %lo(sym)
3067 // (addu $rd, $rd, $rs)
3068 unsigned TmpReg = DstReg;
3070 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3071 // If $rs is the same as $rd, we need to use AT.
3072 // If it is not available we exit.
3073 unsigned ATReg = getATReg(IDLoc);
3079 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3080 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3084 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3087 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3092 // Each double-precision register DO-D15 overlaps with two of the single
3093 // precision registers F0-F31. As an example, all of the following hold true:
3094 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3095 static unsigned nextReg(unsigned Reg) {
3096 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3097 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3099 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3100 case Mips::ZERO: return Mips::AT;
3101 case Mips::AT: return Mips::V0;
3102 case Mips::V0: return Mips::V1;
3103 case Mips::V1: return Mips::A0;
3104 case Mips::A0: return Mips::A1;
3105 case Mips::A1: return Mips::A2;
3106 case Mips::A2: return Mips::A3;
3107 case Mips::A3: return Mips::T0;
3108 case Mips::T0: return Mips::T1;
3109 case Mips::T1: return Mips::T2;
3110 case Mips::T2: return Mips::T3;
3111 case Mips::T3: return Mips::T4;
3112 case Mips::T4: return Mips::T5;
3113 case Mips::T5: return Mips::T6;
3114 case Mips::T6: return Mips::T7;
3115 case Mips::T7: return Mips::S0;
3116 case Mips::S0: return Mips::S1;
3117 case Mips::S1: return Mips::S2;
3118 case Mips::S2: return Mips::S3;
3119 case Mips::S3: return Mips::S4;
3120 case Mips::S4: return Mips::S5;
3121 case Mips::S5: return Mips::S6;
3122 case Mips::S6: return Mips::S7;
3123 case Mips::S7: return Mips::T8;
3124 case Mips::T8: return Mips::T9;
3125 case Mips::T9: return Mips::K0;
3126 case Mips::K0: return Mips::K1;
3127 case Mips::K1: return Mips::GP;
3128 case Mips::GP: return Mips::SP;
3129 case Mips::SP: return Mips::FP;
3130 case Mips::FP: return Mips::RA;
3131 case Mips::RA: return Mips::ZERO;
3132 case Mips::D0: return Mips::F1;
3133 case Mips::D1: return Mips::F3;
3134 case Mips::D2: return Mips::F5;
3135 case Mips::D3: return Mips::F7;
3136 case Mips::D4: return Mips::F9;
3137 case Mips::D5: return Mips::F11;
3138 case Mips::D6: return Mips::F13;
3139 case Mips::D7: return Mips::F15;
3140 case Mips::D8: return Mips::F17;
3141 case Mips::D9: return Mips::F19;
3142 case Mips::D10: return Mips::F21;
3143 case Mips::D11: return Mips::F23;
3144 case Mips::D12: return Mips::F25;
3145 case Mips::D13: return Mips::F27;
3146 case Mips::D14: return Mips::F29;
3147 case Mips::D15: return Mips::F31;
3151 // FIXME: This method is too general. In principle we should compute the number
3152 // of instructions required to synthesize the immediate inline compared to
3153 // synthesizing the address inline and relying on non .text sections.
3154 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3155 // likely to yield a much larger benefit as we have to synthesize a 64bit
3156 // address to load a 64 bit value.
3157 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3159 unsigned ATReg = getATReg(IDLoc);
3164 const MCExpr *GotSym =
3165 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3166 const MipsMCExpr *GotExpr =
3167 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3169 if(isABI_O32() || isABI_N32()) {
3170 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3172 } else { //isABI_N64()
3173 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3176 } else { //!IsPicEnabled
3177 const MCExpr *HiSym =
3178 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3179 const MipsMCExpr *HiExpr =
3180 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3182 // FIXME: This is technically correct but gives a different result to gas,
3183 // but gas is incomplete there (it has a fixme noting it doesn't work with
3184 // 64-bit addresses).
3185 // FIXME: With -msym32 option, the address expansion for N64 should probably
3186 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3187 // symbol's value is considered sign extended.
3188 if(isABI_O32() || isABI_N32()) {
3189 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3190 } else { //isABI_N64()
3191 const MCExpr *HighestSym =
3192 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3193 const MipsMCExpr *HighestExpr =
3194 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3195 const MCExpr *HigherSym =
3196 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3197 const MipsMCExpr *HigherExpr =
3198 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3200 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3202 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3203 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3204 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3205 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3207 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3213 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3214 bool Is64FPU, SMLoc IDLoc,
3216 const MCSubtargetInfo *STI) {
3217 MipsTargetStreamer &TOut = getTargetStreamer();
3218 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3219 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3220 "Invalid instruction operand.");
3222 unsigned FirstReg = Inst.getOperand(0).getReg();
3223 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3225 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3226 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3227 // exponent field), convert it to double (e.g. 1 to 1.0)
3228 if ((HiImmOp64 & 0x7ff00000) == 0) {
3229 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3230 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3233 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3234 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3237 // Conversion of a double in an uint64_t to a float in a uint32_t,
3238 // retaining the bit pattern of a float.
3240 double doubleImm = BitsToDouble(ImmOp64);
3241 float tmp_float = static_cast<float>(doubleImm);
3242 ImmOp32 = FloatToBits(tmp_float);
3245 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3250 unsigned ATReg = getATReg(IDLoc);
3253 if (LoImmOp64 == 0) {
3254 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3257 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3261 MCSection *CS = getStreamer().getCurrentSectionOnly();
3262 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3263 // where appropriate.
3264 MCSection *ReadOnlySection = getContext().getELFSection(
3265 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3267 MCSymbol *Sym = getContext().createTempSymbol();
3268 const MCExpr *LoSym =
3269 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3270 const MipsMCExpr *LoExpr =
3271 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3273 getStreamer().SwitchSection(ReadOnlySection);
3274 getStreamer().EmitLabel(Sym, IDLoc);
3275 getStreamer().EmitIntValue(ImmOp32, 4);
3276 getStreamer().SwitchSection(CS);
3278 if(emitPartialAddress(TOut, IDLoc, Sym))
3280 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3281 MCOperand::createExpr(LoExpr), IDLoc, STI);
3287 unsigned ATReg = getATReg(IDLoc);
3292 if (LoImmOp64 == 0) {
3293 if(isABI_N32() || isABI_N64()) {
3294 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3299 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3303 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3310 MCSection *CS = getStreamer().getCurrentSectionOnly();
3311 MCSection *ReadOnlySection = getContext().getELFSection(
3312 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3314 MCSymbol *Sym = getContext().createTempSymbol();
3315 const MCExpr *LoSym =
3316 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3317 const MipsMCExpr *LoExpr =
3318 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3320 getStreamer().SwitchSection(ReadOnlySection);
3321 getStreamer().EmitLabel(Sym, IDLoc);
3322 getStreamer().EmitIntValue(HiImmOp64, 4);
3323 getStreamer().EmitIntValue(LoImmOp64, 4);
3324 getStreamer().SwitchSection(CS);
3326 if(emitPartialAddress(TOut, IDLoc, Sym))
3329 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3330 MCOperand::createExpr(LoExpr), IDLoc, STI);
3332 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3333 MCOperand::createExpr(LoExpr), IDLoc, STI);
3335 if(isABI_N32() || isABI_N64())
3336 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3338 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3339 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3342 } else { // if(!IsGPR && !IsSingle)
3343 if ((LoImmOp64 == 0) &&
3344 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3345 // FIXME: In the case where the constant is zero, we can load the
3346 // register directly from the zero register.
3347 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3350 if (isABI_N32() || isABI_N64())
3351 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3352 else if (hasMips32r2()) {
3353 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3354 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3356 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3357 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3362 MCSection *CS = getStreamer().getCurrentSectionOnly();
3363 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3364 // where appropriate.
3365 MCSection *ReadOnlySection = getContext().getELFSection(
3366 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3368 MCSymbol *Sym = getContext().createTempSymbol();
3369 const MCExpr *LoSym =
3370 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3371 const MipsMCExpr *LoExpr =
3372 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3374 getStreamer().SwitchSection(ReadOnlySection);
3375 getStreamer().EmitLabel(Sym, IDLoc);
3376 getStreamer().EmitIntValue(HiImmOp64, 4);
3377 getStreamer().EmitIntValue(LoImmOp64, 4);
3378 getStreamer().SwitchSection(CS);
3380 if(emitPartialAddress(TOut, IDLoc, Sym))
3382 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3383 MCOperand::createExpr(LoExpr), IDLoc, STI);
3388 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3390 const MCSubtargetInfo *STI) {
3391 MipsTargetStreamer &TOut = getTargetStreamer();
3393 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3394 "unexpected number of operands");
3396 MCOperand Offset = Inst.getOperand(0);
3397 if (Offset.isExpr()) {
3399 Inst.setOpcode(Mips::BEQ_MM);
3400 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3401 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3402 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3404 assert(Offset.isImm() && "expected immediate operand kind");
3405 if (isInt<11>(Offset.getImm())) {
3406 // If offset fits into 11 bits then this instruction becomes microMIPS
3407 // 16-bit unconditional branch instruction.
3408 if (inMicroMipsMode())
3409 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3411 if (!isInt<17>(Offset.getImm()))
3412 return Error(IDLoc, "branch target out of range");
3413 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3414 return Error(IDLoc, "branch to misaligned address");
3416 Inst.setOpcode(Mips::BEQ_MM);
3417 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3418 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3419 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3422 Out.EmitInstruction(Inst, *STI);
3424 // If .set reorder is active and branch instruction has a delay slot,
3425 // emit a NOP after it.
3426 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3427 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3428 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3433 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3434 const MCSubtargetInfo *STI) {
3435 MipsTargetStreamer &TOut = getTargetStreamer();
3436 const MCOperand &DstRegOp = Inst.getOperand(0);
3437 assert(DstRegOp.isReg() && "expected register operand kind");
3439 const MCOperand &ImmOp = Inst.getOperand(1);
3440 assert(ImmOp.isImm() && "expected immediate operand kind");
3442 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3443 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3444 "expected immediate or expression operand");
3446 bool IsLikely = false;
3448 unsigned OpCode = 0;
3449 switch(Inst.getOpcode()) {
3456 case Mips::BEQLImmMacro:
3457 OpCode = Mips::BEQL;
3460 case Mips::BNELImmMacro:
3461 OpCode = Mips::BNEL;
3465 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3469 int64_t ImmValue = ImmOp.getImm();
3470 if (ImmValue == 0) {
3472 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3473 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3474 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3476 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3479 warnIfNoMacro(IDLoc);
3481 unsigned ATReg = getATReg(IDLoc);
3485 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3490 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3491 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3492 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3494 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3499 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3500 const MCSubtargetInfo *STI, bool IsLoad,
3503 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3506 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3509 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3510 const MCSubtargetInfo *STI, bool IsImmOpnd) {
3511 MipsTargetStreamer &TOut = getTargetStreamer();
3513 unsigned DstReg = Inst.getOperand(0).getReg();
3514 unsigned BaseReg = Inst.getOperand(1).getReg();
3516 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3517 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3518 unsigned DstRegClassID =
3519 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3520 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3521 (DstRegClassID == Mips::GPR64RegClassID);
3524 // Try to use DstReg as the temporary.
3525 if (IsGPR && (BaseReg != DstReg)) {
3526 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3527 Inst.getOperand(2).getImm(), DstReg, IDLoc,
3532 // At this point we need AT to perform the expansions and we exit if it is
3534 unsigned ATReg = getATReg(IDLoc);
3538 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3539 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
3543 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3544 MCOperand LoOperand = MCOperand::createExpr(
3545 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3546 MCOperand HiOperand = MCOperand::createExpr(
3547 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3549 // Try to use DstReg as the temporary.
3550 if (IsGPR && (BaseReg != DstReg)) {
3551 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3552 LoOperand, DstReg, IDLoc, STI);
3556 // At this point we need AT to perform the expansions and we exit if it is
3558 unsigned ATReg = getATReg(IDLoc);
3562 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3563 LoOperand, ATReg, IDLoc, STI);
3566 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3567 const MCSubtargetInfo *STI,
3569 MipsTargetStreamer &TOut = getTargetStreamer();
3571 unsigned SrcReg = Inst.getOperand(0).getReg();
3572 unsigned BaseReg = Inst.getOperand(1).getReg();
3575 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
3576 Inst.getOperand(2).getImm(),
3577 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
3581 unsigned ATReg = getATReg(IDLoc);
3585 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3586 MCOperand LoOperand = MCOperand::createExpr(
3587 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3588 MCOperand HiOperand = MCOperand::createExpr(
3589 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3590 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
3591 LoOperand, ATReg, IDLoc, STI);
3594 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3596 const MCSubtargetInfo *STI) {
3597 unsigned OpNum = Inst.getNumOperands();
3598 unsigned Opcode = Inst.getOpcode();
3599 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3601 assert(Inst.getOperand(OpNum - 1).isImm() &&
3602 Inst.getOperand(OpNum - 2).isReg() &&
3603 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3605 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3606 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3607 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3608 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3609 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3610 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3611 // It can be implemented as SWM16 or LWM16 instruction.
3612 if (inMicroMipsMode() && hasMips32r6())
3613 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3615 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3618 Inst.setOpcode(NewOpcode);
3619 Out.EmitInstruction(Inst, *STI);
3623 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3625 const MCSubtargetInfo *STI) {
3626 MipsTargetStreamer &TOut = getTargetStreamer();
3627 bool EmittedNoMacroWarning = false;
3628 unsigned PseudoOpcode = Inst.getOpcode();
3629 unsigned SrcReg = Inst.getOperand(0).getReg();
3630 const MCOperand &TrgOp = Inst.getOperand(1);
3631 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3633 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3634 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3638 TrgReg = TrgOp.getReg();
3639 else if (TrgOp.isImm()) {
3640 warnIfNoMacro(IDLoc);
3641 EmittedNoMacroWarning = true;
3643 TrgReg = getATReg(IDLoc);
3647 switch(PseudoOpcode) {
3649 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3650 case Mips::BLTImmMacro:
3651 PseudoOpcode = Mips::BLT;
3653 case Mips::BLEImmMacro:
3654 PseudoOpcode = Mips::BLE;
3656 case Mips::BGEImmMacro:
3657 PseudoOpcode = Mips::BGE;
3659 case Mips::BGTImmMacro:
3660 PseudoOpcode = Mips::BGT;
3662 case Mips::BLTUImmMacro:
3663 PseudoOpcode = Mips::BLTU;
3665 case Mips::BLEUImmMacro:
3666 PseudoOpcode = Mips::BLEU;
3668 case Mips::BGEUImmMacro:
3669 PseudoOpcode = Mips::BGEU;
3671 case Mips::BGTUImmMacro:
3672 PseudoOpcode = Mips::BGTU;
3674 case Mips::BLTLImmMacro:
3675 PseudoOpcode = Mips::BLTL;
3677 case Mips::BLELImmMacro:
3678 PseudoOpcode = Mips::BLEL;
3680 case Mips::BGELImmMacro:
3681 PseudoOpcode = Mips::BGEL;
3683 case Mips::BGTLImmMacro:
3684 PseudoOpcode = Mips::BGTL;
3686 case Mips::BLTULImmMacro:
3687 PseudoOpcode = Mips::BLTUL;
3689 case Mips::BLEULImmMacro:
3690 PseudoOpcode = Mips::BLEUL;
3692 case Mips::BGEULImmMacro:
3693 PseudoOpcode = Mips::BGEUL;
3695 case Mips::BGTULImmMacro:
3696 PseudoOpcode = Mips::BGTUL;
3700 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3701 false, IDLoc, Out, STI))
3705 switch (PseudoOpcode) {
3710 AcceptsEquality = false;
3711 ReverseOrderSLT = false;
3712 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3713 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3714 ZeroSrcOpcode = Mips::BGTZ;
3715 ZeroTrgOpcode = Mips::BLTZ;
3721 AcceptsEquality = true;
3722 ReverseOrderSLT = true;
3723 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3724 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3725 ZeroSrcOpcode = Mips::BGEZ;
3726 ZeroTrgOpcode = Mips::BLEZ;
3732 AcceptsEquality = true;
3733 ReverseOrderSLT = false;
3734 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3735 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3736 ZeroSrcOpcode = Mips::BLEZ;
3737 ZeroTrgOpcode = Mips::BGEZ;
3743 AcceptsEquality = false;
3744 ReverseOrderSLT = true;
3745 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3746 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3747 ZeroSrcOpcode = Mips::BLTZ;
3748 ZeroTrgOpcode = Mips::BGTZ;
3751 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3754 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3755 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3756 if (IsSrcRegZero && IsTrgRegZero) {
3757 // FIXME: All of these Opcode-specific if's are needed for compatibility
3758 // with GAS' behaviour. However, they may not generate the most efficient
3759 // code in some circumstances.
3760 if (PseudoOpcode == Mips::BLT) {
3761 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3765 if (PseudoOpcode == Mips::BLE) {
3766 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3768 Warning(IDLoc, "branch is always taken");
3771 if (PseudoOpcode == Mips::BGE) {
3772 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3774 Warning(IDLoc, "branch is always taken");
3777 if (PseudoOpcode == Mips::BGT) {
3778 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3782 if (PseudoOpcode == Mips::BGTU) {
3783 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3784 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3787 if (AcceptsEquality) {
3788 // If both registers are $0 and the pseudo-branch accepts equality, it
3789 // will always be taken, so we emit an unconditional branch.
3790 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3791 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3792 Warning(IDLoc, "branch is always taken");
3795 // If both registers are $0 and the pseudo-branch does not accept
3796 // equality, it will never be taken, so we don't have to emit anything.
3799 if (IsSrcRegZero || IsTrgRegZero) {
3800 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3801 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3802 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3803 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3804 // the pseudo-branch will never be taken, so we don't emit anything.
3805 // This only applies to unsigned pseudo-branches.
3808 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3809 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3810 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3811 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3812 // the pseudo-branch will always be taken, so we emit an unconditional
3814 // This only applies to unsigned pseudo-branches.
3815 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3816 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3817 Warning(IDLoc, "branch is always taken");
3821 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3822 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3823 // the pseudo-branch will be taken only when the non-zero register is
3824 // different from 0, so we emit a BNEZ.
3826 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3827 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3828 // the pseudo-branch will be taken only when the non-zero register is
3829 // equal to 0, so we emit a BEQZ.
3831 // Because only BLEU and BGEU branch on equality, we can use the
3832 // AcceptsEquality variable to decide when to emit the BEQZ.
3833 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3834 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3835 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3838 // If we have a signed pseudo-branch and one of the registers is $0,
3839 // we can use an appropriate compare-to-zero branch. We select which one
3840 // to use in the switch statement above.
3841 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3842 IsSrcRegZero ? TrgReg : SrcReg,
3843 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3847 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3848 // expansions. If it is not available, we return.
3849 unsigned ATRegNum = getATReg(IDLoc);
3853 if (!EmittedNoMacroWarning)
3854 warnIfNoMacro(IDLoc);
3856 // SLT fits well with 2 of our 4 pseudo-branches:
3857 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3858 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3859 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3860 // This is accomplished by using a BNEZ with the result of the SLT.
3862 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3863 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3864 // Because only BGE and BLE branch on equality, we can use the
3865 // AcceptsEquality variable to decide when to emit the BEQZ.
3866 // Note that the order of the SLT arguments doesn't change between
3869 // The same applies to the unsigned variants, except that SLTu is used
3871 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3872 ReverseOrderSLT ? TrgReg : SrcReg,
3873 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3875 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3876 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3877 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3882 // Expand a integer division macro.
3884 // Notably we don't have to emit a warning when encountering $rt as the $zero
3885 // register, or 0 as an immediate. processInstruction() has already done that.
3887 // The destination register can only be $zero when expanding (S)DivIMacro or
3890 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3891 const MCSubtargetInfo *STI, const bool IsMips64,
3892 const bool Signed) {
3893 MipsTargetStreamer &TOut = getTargetStreamer();
3895 warnIfNoMacro(IDLoc);
3897 const MCOperand &RdRegOp = Inst.getOperand(0);
3898 assert(RdRegOp.isReg() && "expected register operand kind");
3899 unsigned RdReg = RdRegOp.getReg();
3901 const MCOperand &RsRegOp = Inst.getOperand(1);
3902 assert(RsRegOp.isReg() && "expected register operand kind");
3903 unsigned RsReg = RsRegOp.getReg();
3908 const MCOperand &RtOp = Inst.getOperand(2);
3909 assert((RtOp.isReg() || RtOp.isImm()) &&
3910 "expected register or immediate operand kind");
3912 RtReg = RtOp.getReg();
3914 ImmValue = RtOp.getImm();
3921 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3922 ZeroReg = Mips::ZERO_64;
3925 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3926 ZeroReg = Mips::ZERO;
3930 bool UseTraps = useTraps();
3933 unsigned ATReg = getATReg(IDLoc);
3937 if (ImmValue == 0) {
3939 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3941 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3945 if (ImmValue == 1) {
3946 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3948 } else if (Signed && ImmValue == -1) {
3949 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3952 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
3953 false, Inst.getLoc(), Out, STI))
3955 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
3956 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3962 // If the macro expansion of (d)div(u) would always trap or break, insert
3963 // the trap/break and exit. This gives a different result to GAS. GAS has
3964 // an inconsistency/missed optimization in that not all cases are handled
3965 // equivalently. As the observed behaviour is the same, we're ok.
3966 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3968 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3971 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3975 // Temporary label for first branch traget
3976 MCContext &Context = TOut.getStreamer().getContext();
3981 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3983 // Branch to the li instruction.
3984 BrTarget = Context.createTempSymbol();
3985 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
3986 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
3989 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3992 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3996 TOut.getStreamer().EmitLabel(BrTarget);
3998 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4002 unsigned ATReg = getATReg(IDLoc);
4007 TOut.getStreamer().EmitLabel(BrTarget);
4009 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4011 // Temporary label for the second branch target.
4012 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4013 MCOperand LabelOpEnd =
4014 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4016 // Branch to the mflo instruction.
4017 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4020 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4021 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
4023 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4027 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4029 // Branch to the mflo instruction.
4030 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4031 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
4032 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4035 TOut.getStreamer().EmitLabel(BrTargetEnd);
4036 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4040 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4041 SMLoc IDLoc, MCStreamer &Out,
4042 const MCSubtargetInfo *STI) {
4043 MipsTargetStreamer &TOut = getTargetStreamer();
4045 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4046 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4047 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4049 unsigned FirstReg = Inst.getOperand(0).getReg();
4050 unsigned SecondReg = Inst.getOperand(1).getReg();
4051 unsigned ThirdReg = Inst.getOperand(2).getReg();
4053 if (hasMips1() && !hasMips2()) {
4054 unsigned ATReg = getATReg(IDLoc);
4057 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4058 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4059 TOut.emitNop(IDLoc, STI);
4060 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4061 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4062 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4063 TOut.emitNop(IDLoc, STI);
4064 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4066 FirstReg, SecondReg, IDLoc, STI);
4067 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4068 TOut.emitNop(IDLoc, STI);
4072 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4074 FirstReg, SecondReg, IDLoc, STI);
4079 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4080 MCStreamer &Out, const MCSubtargetInfo *STI) {
4081 if (hasMips32r6() || hasMips64r6()) {
4082 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4085 const MCOperand &DstRegOp = Inst.getOperand(0);
4086 assert(DstRegOp.isReg() && "expected register operand kind");
4087 const MCOperand &SrcRegOp = Inst.getOperand(1);
4088 assert(SrcRegOp.isReg() && "expected register operand kind");
4089 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4090 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4092 MipsTargetStreamer &TOut = getTargetStreamer();
4093 unsigned DstReg = DstRegOp.getReg();
4094 unsigned SrcReg = SrcRegOp.getReg();
4095 int64_t OffsetValue = OffsetImmOp.getImm();
4097 // NOTE: We always need AT for ULHU, as it is always used as the source
4098 // register for one of the LBu's.
4099 warnIfNoMacro(IDLoc);
4100 unsigned ATReg = getATReg(IDLoc);
4104 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4105 if (IsLargeOffset) {
4106 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4111 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4112 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4114 std::swap(FirstOffset, SecondOffset);
4116 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4117 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4119 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4120 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4122 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4123 FirstOffset, IDLoc, STI);
4124 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4125 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4126 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4131 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4132 const MCSubtargetInfo *STI) {
4133 if (hasMips32r6() || hasMips64r6()) {
4134 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4137 const MCOperand &DstRegOp = Inst.getOperand(0);
4138 assert(DstRegOp.isReg() && "expected register operand kind");
4139 const MCOperand &SrcRegOp = Inst.getOperand(1);
4140 assert(SrcRegOp.isReg() && "expected register operand kind");
4141 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4142 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4144 MipsTargetStreamer &TOut = getTargetStreamer();
4145 unsigned DstReg = DstRegOp.getReg();
4146 unsigned SrcReg = SrcRegOp.getReg();
4147 int64_t OffsetValue = OffsetImmOp.getImm();
4149 warnIfNoMacro(IDLoc);
4150 unsigned ATReg = getATReg(IDLoc);
4154 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4155 if (IsLargeOffset) {
4156 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4161 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4162 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4164 std::swap(FirstOffset, SecondOffset);
4166 if (IsLargeOffset) {
4167 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4168 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4169 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4170 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4171 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4172 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4174 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4175 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4176 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4182 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4183 const MCSubtargetInfo *STI) {
4184 if (hasMips32r6() || hasMips64r6()) {
4185 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4188 const MCOperand &DstRegOp = Inst.getOperand(0);
4189 assert(DstRegOp.isReg() && "expected register operand kind");
4190 const MCOperand &SrcRegOp = Inst.getOperand(1);
4191 assert(SrcRegOp.isReg() && "expected register operand kind");
4192 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4193 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4195 MipsTargetStreamer &TOut = getTargetStreamer();
4196 unsigned DstReg = DstRegOp.getReg();
4197 unsigned SrcReg = SrcRegOp.getReg();
4198 int64_t OffsetValue = OffsetImmOp.getImm();
4200 // Compute left/right load/store offsets.
4201 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4202 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4203 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4205 std::swap(LxlOffset, LxrOffset);
4207 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4208 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4209 unsigned TmpReg = SrcReg;
4210 if (IsLargeOffset || DoMove) {
4211 warnIfNoMacro(IDLoc);
4212 TmpReg = getATReg(IDLoc);
4217 if (IsLargeOffset) {
4218 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4224 std::swap(DstReg, TmpReg);
4226 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4227 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4228 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4229 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4232 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4237 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4239 const MCSubtargetInfo *STI) {
4240 MipsTargetStreamer &TOut = getTargetStreamer();
4242 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4243 assert(Inst.getOperand(0).isReg() &&
4244 Inst.getOperand(1).isReg() &&
4245 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4247 unsigned ATReg = Mips::NoRegister;
4248 unsigned FinalDstReg = Mips::NoRegister;
4249 unsigned DstReg = Inst.getOperand(0).getReg();
4250 unsigned SrcReg = Inst.getOperand(1).getReg();
4251 int64_t ImmValue = Inst.getOperand(2).getImm();
4253 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4255 unsigned FinalOpcode = Inst.getOpcode();
4257 if (DstReg == SrcReg) {
4258 ATReg = getATReg(Inst.getLoc());
4261 FinalDstReg = DstReg;
4265 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
4266 switch (FinalOpcode) {
4268 llvm_unreachable("unimplemented expansion");
4270 FinalOpcode = Mips::ADD;
4273 FinalOpcode = Mips::ADDu;
4276 FinalOpcode = Mips::AND;
4279 FinalOpcode = Mips::NOR;
4282 FinalOpcode = Mips::OR;
4285 FinalOpcode = Mips::SLT;
4288 FinalOpcode = Mips::SLTu;
4291 FinalOpcode = Mips::XOR;
4294 FinalOpcode = Mips::ADD_MM;
4296 case Mips::ADDiu_MM:
4297 FinalOpcode = Mips::ADDu_MM;
4300 FinalOpcode = Mips::AND_MM;
4303 FinalOpcode = Mips::OR_MM;
4306 FinalOpcode = Mips::SLT_MM;
4308 case Mips::SLTiu_MM:
4309 FinalOpcode = Mips::SLTu_MM;
4312 FinalOpcode = Mips::XOR_MM;
4315 FinalOpcode = Mips::AND64;
4317 case Mips::NORImm64:
4318 FinalOpcode = Mips::NOR64;
4321 FinalOpcode = Mips::OR64;
4323 case Mips::SLTImm64:
4324 FinalOpcode = Mips::SLT64;
4326 case Mips::SLTUImm64:
4327 FinalOpcode = Mips::SLTu64;
4330 FinalOpcode = Mips::XOR64;
4334 if (FinalDstReg == Mips::NoRegister)
4335 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4337 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4343 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4344 const MCSubtargetInfo *STI) {
4345 MipsTargetStreamer &TOut = getTargetStreamer();
4346 unsigned ATReg = Mips::NoRegister;
4347 unsigned DReg = Inst.getOperand(0).getReg();
4348 unsigned SReg = Inst.getOperand(1).getReg();
4349 unsigned TReg = Inst.getOperand(2).getReg();
4350 unsigned TmpReg = DReg;
4352 unsigned FirstShift = Mips::NOP;
4353 unsigned SecondShift = Mips::NOP;
4355 if (hasMips32r2()) {
4357 TmpReg = getATReg(Inst.getLoc());
4362 if (Inst.getOpcode() == Mips::ROL) {
4363 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4364 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4368 if (Inst.getOpcode() == Mips::ROR) {
4369 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4377 switch (Inst.getOpcode()) {
4379 llvm_unreachable("unexpected instruction opcode");
4381 FirstShift = Mips::SRLV;
4382 SecondShift = Mips::SLLV;
4385 FirstShift = Mips::SLLV;
4386 SecondShift = Mips::SRLV;
4390 ATReg = getATReg(Inst.getLoc());
4394 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4395 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4396 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4397 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4405 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4407 const MCSubtargetInfo *STI) {
4408 MipsTargetStreamer &TOut = getTargetStreamer();
4409 unsigned ATReg = Mips::NoRegister;
4410 unsigned DReg = Inst.getOperand(0).getReg();
4411 unsigned SReg = Inst.getOperand(1).getReg();
4412 int64_t ImmValue = Inst.getOperand(2).getImm();
4414 unsigned FirstShift = Mips::NOP;
4415 unsigned SecondShift = Mips::NOP;
4417 if (hasMips32r2()) {
4418 if (Inst.getOpcode() == Mips::ROLImm) {
4419 uint64_t MaxShift = 32;
4420 uint64_t ShiftValue = ImmValue;
4422 ShiftValue = MaxShift - ImmValue;
4423 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4427 if (Inst.getOpcode() == Mips::RORImm) {
4428 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4436 if (ImmValue == 0) {
4437 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4441 switch (Inst.getOpcode()) {
4443 llvm_unreachable("unexpected instruction opcode");
4445 FirstShift = Mips::SLL;
4446 SecondShift = Mips::SRL;
4449 FirstShift = Mips::SRL;
4450 SecondShift = Mips::SLL;
4454 ATReg = getATReg(Inst.getLoc());
4458 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4459 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4460 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4468 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4469 const MCSubtargetInfo *STI) {
4470 MipsTargetStreamer &TOut = getTargetStreamer();
4471 unsigned ATReg = Mips::NoRegister;
4472 unsigned DReg = Inst.getOperand(0).getReg();
4473 unsigned SReg = Inst.getOperand(1).getReg();
4474 unsigned TReg = Inst.getOperand(2).getReg();
4475 unsigned TmpReg = DReg;
4477 unsigned FirstShift = Mips::NOP;
4478 unsigned SecondShift = Mips::NOP;
4480 if (hasMips64r2()) {
4481 if (TmpReg == SReg) {
4482 TmpReg = getATReg(Inst.getLoc());
4487 if (Inst.getOpcode() == Mips::DROL) {
4488 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4489 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4493 if (Inst.getOpcode() == Mips::DROR) {
4494 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4502 switch (Inst.getOpcode()) {
4504 llvm_unreachable("unexpected instruction opcode");
4506 FirstShift = Mips::DSRLV;
4507 SecondShift = Mips::DSLLV;
4510 FirstShift = Mips::DSLLV;
4511 SecondShift = Mips::DSRLV;
4515 ATReg = getATReg(Inst.getLoc());
4519 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4520 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4521 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4522 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4530 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4532 const MCSubtargetInfo *STI) {
4533 MipsTargetStreamer &TOut = getTargetStreamer();
4534 unsigned ATReg = Mips::NoRegister;
4535 unsigned DReg = Inst.getOperand(0).getReg();
4536 unsigned SReg = Inst.getOperand(1).getReg();
4537 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4539 unsigned FirstShift = Mips::NOP;
4540 unsigned SecondShift = Mips::NOP;
4544 if (hasMips64r2()) {
4545 unsigned FinalOpcode = Mips::NOP;
4547 FinalOpcode = Mips::DROTR;
4548 else if (ImmValue % 32 == 0)
4549 FinalOpcode = Mips::DROTR32;
4550 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4551 if (Inst.getOpcode() == Mips::DROLImm)
4552 FinalOpcode = Mips::DROTR32;
4554 FinalOpcode = Mips::DROTR;
4555 } else if (ImmValue >= 33) {
4556 if (Inst.getOpcode() == Mips::DROLImm)
4557 FinalOpcode = Mips::DROTR;
4559 FinalOpcode = Mips::DROTR32;
4562 uint64_t ShiftValue = ImmValue % 32;
4563 if (Inst.getOpcode() == Mips::DROLImm)
4564 ShiftValue = (32 - ImmValue % 32) % 32;
4566 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4572 if (ImmValue == 0) {
4573 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4577 switch (Inst.getOpcode()) {
4579 llvm_unreachable("unexpected instruction opcode");
4581 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4582 FirstShift = Mips::DSLL;
4583 SecondShift = Mips::DSRL32;
4585 if (ImmValue == 32) {
4586 FirstShift = Mips::DSLL32;
4587 SecondShift = Mips::DSRL32;
4589 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4590 FirstShift = Mips::DSLL32;
4591 SecondShift = Mips::DSRL;
4595 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4596 FirstShift = Mips::DSRL;
4597 SecondShift = Mips::DSLL32;
4599 if (ImmValue == 32) {
4600 FirstShift = Mips::DSRL32;
4601 SecondShift = Mips::DSLL32;
4603 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4604 FirstShift = Mips::DSRL32;
4605 SecondShift = Mips::DSLL;
4610 ATReg = getATReg(Inst.getLoc());
4614 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4615 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4616 Inst.getLoc(), STI);
4617 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4625 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4626 const MCSubtargetInfo *STI) {
4627 MipsTargetStreamer &TOut = getTargetStreamer();
4628 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4629 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4631 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4632 if (FirstRegOp != SecondRegOp)
4633 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4635 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4636 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4641 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4642 const MCSubtargetInfo *STI) {
4643 MipsTargetStreamer &TOut = getTargetStreamer();
4644 unsigned ATReg = Mips::NoRegister;
4645 unsigned DstReg = Inst.getOperand(0).getReg();
4646 unsigned SrcReg = Inst.getOperand(1).getReg();
4647 int32_t ImmValue = Inst.getOperand(2).getImm();
4649 ATReg = getATReg(IDLoc);
4653 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, STI);
4655 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4656 SrcReg, ATReg, IDLoc, STI);
4658 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4663 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4664 const MCSubtargetInfo *STI) {
4665 MipsTargetStreamer &TOut = getTargetStreamer();
4666 unsigned ATReg = Mips::NoRegister;
4667 unsigned DstReg = Inst.getOperand(0).getReg();
4668 unsigned SrcReg = Inst.getOperand(1).getReg();
4669 unsigned TmpReg = Inst.getOperand(2).getReg();
4671 ATReg = getATReg(Inst.getLoc());
4675 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4676 SrcReg, TmpReg, IDLoc, STI);
4678 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4680 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4681 DstReg, DstReg, 0x1F, IDLoc, STI);
4683 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4686 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4688 MCContext & Context = TOut.getStreamer().getContext();
4689 MCSymbol * BrTarget = Context.createTempSymbol();
4691 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4693 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4694 if (AssemblerOptions.back()->isReorder())
4695 TOut.emitNop(IDLoc, STI);
4696 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4698 TOut.getStreamer().EmitLabel(BrTarget);
4700 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4705 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4706 const MCSubtargetInfo *STI) {
4707 MipsTargetStreamer &TOut = getTargetStreamer();
4708 unsigned ATReg = Mips::NoRegister;
4709 unsigned DstReg = Inst.getOperand(0).getReg();
4710 unsigned SrcReg = Inst.getOperand(1).getReg();
4711 unsigned TmpReg = Inst.getOperand(2).getReg();
4713 ATReg = getATReg(IDLoc);
4717 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4718 SrcReg, TmpReg, IDLoc, STI);
4720 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4721 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4723 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4725 MCContext & Context = TOut.getStreamer().getContext();
4726 MCSymbol * BrTarget = Context.createTempSymbol();
4728 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4730 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4731 if (AssemblerOptions.back()->isReorder())
4732 TOut.emitNop(IDLoc, STI);
4733 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4735 TOut.getStreamer().EmitLabel(BrTarget);
4741 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4742 const MCSubtargetInfo *STI) {
4743 MipsTargetStreamer &TOut = getTargetStreamer();
4744 unsigned DstReg = Inst.getOperand(0).getReg();
4745 unsigned SrcReg = Inst.getOperand(1).getReg();
4746 unsigned TmpReg = Inst.getOperand(2).getReg();
4748 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4749 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4754 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4755 // lw $<reg+1>>, offset+4($reg2)'
4756 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4757 // sw $<reg+1>>, offset+4($reg2)'
4759 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4761 const MCSubtargetInfo *STI,
4766 warnIfNoMacro(IDLoc);
4768 MipsTargetStreamer &TOut = getTargetStreamer();
4769 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4770 unsigned FirstReg = Inst.getOperand(0).getReg();
4771 unsigned SecondReg = nextReg(FirstReg);
4772 unsigned BaseReg = Inst.getOperand(1).getReg();
4776 warnIfRegIndexIsAT(FirstReg, IDLoc);
4778 assert(Inst.getOperand(2).isImm() &&
4779 "Offset for load macro is not immediate!");
4781 MCOperand &FirstOffset = Inst.getOperand(2);
4782 signed NextOffset = FirstOffset.getImm() + 4;
4783 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4785 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4788 // For loads, clobber the base register with the second load instead of the
4789 // first if the BaseReg == FirstReg.
4790 if (FirstReg != BaseReg || !IsLoad) {
4791 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4792 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4794 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4795 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4801 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4802 const MCSubtargetInfo *STI) {
4804 warnIfNoMacro(IDLoc);
4805 MipsTargetStreamer &TOut = getTargetStreamer();
4807 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4808 Inst.getOperand(2).getReg() != Mips::ZERO) {
4809 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4810 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4812 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4813 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4818 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4819 Reg = Inst.getOperand(2).getReg();
4821 Reg = Inst.getOperand(1).getReg();
4823 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4827 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4828 const MCSubtargetInfo *STI) {
4829 warnIfNoMacro(IDLoc);
4830 MipsTargetStreamer &TOut = getTargetStreamer();
4833 int64_t Imm = Inst.getOperand(2).getImm();
4834 unsigned Reg = Inst.getOperand(1).getReg();
4837 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4838 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4842 if (Reg == Mips::ZERO) {
4843 Warning(IDLoc, "comparison is always false");
4844 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4845 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4849 if (Imm > -0x8000 && Imm < 0) {
4851 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4856 if (!isUInt<16>(Imm)) {
4857 unsigned ATReg = getATReg(IDLoc);
4861 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4865 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4866 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4867 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4868 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4872 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4874 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4875 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4880 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
4881 const OperandVector &Operands) {
4882 switch (Inst.getOpcode()) {
4884 return Match_Success;
4887 case Mips::DATI_MM64R6:
4888 case Mips::DAHI_MM64R6:
4889 if (static_cast<MipsOperand &>(*Operands[1])
4890 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4891 return Match_Success;
4892 return Match_RequiresSameSrcAndDst;
4896 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4897 switch (Inst.getOpcode()) {
4898 // As described by the MIPSR6 spec, daui must not use the zero operand for
4899 // its source operand.
4901 case Mips::DAUI_MM64R6:
4902 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4903 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4904 return Match_RequiresNoZeroRegister;
4905 return Match_Success;
4906 // As described by the Mips32r2 spec, the registers Rd and Rs for
4907 // jalr.hb must be different.
4908 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
4909 // and registers Rd and Base for microMIPS lwp instruction
4911 case Mips::JALRC_HB_MMR6:
4912 case Mips::JALRC_MMR6:
4913 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4914 return Match_RequiresDifferentSrcAndDst;
4915 return Match_Success;
4917 case Mips::LWP_MMR6:
4918 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
4919 return Match_RequiresDifferentSrcAndDst;
4920 return Match_Success;
4922 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
4923 return Match_NonZeroOperandForSync;
4924 return Match_Success;
4925 // As described the MIPSR6 spec, the compact branches that compare registers
4927 // a) Not use the zero register.
4928 // b) Not use the same register twice.
4929 // c) rs < rt for bnec, beqc.
4930 // NB: For this case, the encoding will swap the operands as their
4931 // ordering doesn't matter. GAS performs this transformation too.
4932 // Hence, that constraint does not have to be enforced.
4934 // The compact branches that branch iff the signed addition of two registers
4935 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
4936 // operand swapping. They do not have restriction of using the zero register.
4937 case Mips::BLEZC: case Mips::BLEZC_MMR6:
4938 case Mips::BGEZC: case Mips::BGEZC_MMR6:
4939 case Mips::BGTZC: case Mips::BGTZC_MMR6:
4940 case Mips::BLTZC: case Mips::BLTZC_MMR6:
4941 case Mips::BEQZC: case Mips::BEQZC_MMR6:
4942 case Mips::BNEZC: case Mips::BNEZC_MMR6:
4949 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4950 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4951 return Match_RequiresNoZeroRegister;
4952 return Match_Success;
4953 case Mips::BGEC: case Mips::BGEC_MMR6:
4954 case Mips::BLTC: case Mips::BLTC_MMR6:
4955 case Mips::BGEUC: case Mips::BGEUC_MMR6:
4956 case Mips::BLTUC: case Mips::BLTUC_MMR6:
4957 case Mips::BEQC: case Mips::BEQC_MMR6:
4958 case Mips::BNEC: case Mips::BNEC_MMR6:
4965 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4966 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4967 return Match_RequiresNoZeroRegister;
4968 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4969 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4970 return Match_RequiresNoZeroRegister;
4971 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4972 return Match_RequiresDifferentOperands;
4973 return Match_Success;
4976 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
4977 if ((TSFlags & MipsII::HasFCCRegOperand) &&
4978 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
4979 return Match_NoFCCRegisterForCurrentISA;
4981 return Match_Success;
4985 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
4986 uint64_t ErrorInfo) {
4987 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
4988 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4989 if (ErrorLoc == SMLoc())
4996 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4997 OperandVector &Operands,
4999 uint64_t &ErrorInfo,
5000 bool MatchingInlineAsm) {
5002 unsigned MatchResult =
5003 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5005 switch (MatchResult) {
5007 if (processInstruction(Inst, IDLoc, Out, STI))
5010 case Match_MissingFeature:
5011 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5013 case Match_InvalidOperand: {
5014 SMLoc ErrorLoc = IDLoc;
5015 if (ErrorInfo != ~0ULL) {
5016 if (ErrorInfo >= Operands.size())
5017 return Error(IDLoc, "too few operands for instruction");
5019 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5020 if (ErrorLoc == SMLoc())
5024 return Error(ErrorLoc, "invalid operand for instruction");
5026 case Match_NonZeroOperandForSync:
5027 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5028 case Match_MnemonicFail:
5029 return Error(IDLoc, "invalid instruction");
5030 case Match_RequiresDifferentSrcAndDst:
5031 return Error(IDLoc, "source and destination must be different");
5032 case Match_RequiresDifferentOperands:
5033 return Error(IDLoc, "registers must be different");
5034 case Match_RequiresNoZeroRegister:
5035 return Error(IDLoc, "invalid operand ($zero) for instruction");
5036 case Match_RequiresSameSrcAndDst:
5037 return Error(IDLoc, "source and destination must match");
5038 case Match_NoFCCRegisterForCurrentISA:
5039 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5040 "non-zero fcc register doesn't exist in current ISA level");
5042 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5044 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5045 "expected 1-bit unsigned immediate");
5047 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5048 "expected 2-bit unsigned immediate");
5050 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5051 "expected immediate in range 1 .. 4");
5053 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5054 "expected 3-bit unsigned immediate");
5056 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5057 "expected 4-bit unsigned immediate");
5059 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5060 "expected 4-bit signed immediate");
5062 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5063 "expected 5-bit unsigned immediate");
5065 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5066 "expected 5-bit signed immediate");
5068 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5069 "expected immediate in range 1 .. 32");
5070 case Match_UImm5_32:
5071 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5072 "expected immediate in range 32 .. 63");
5073 case Match_UImm5_33:
5074 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5075 "expected immediate in range 33 .. 64");
5076 case Match_UImm5_0_Report_UImm6:
5077 // This is used on UImm5 operands that have a corresponding UImm5_32
5078 // operand to avoid confusing the user.
5079 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5080 "expected 6-bit unsigned immediate");
5081 case Match_UImm5_Lsl2:
5082 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5083 "expected both 7-bit unsigned immediate and multiple of 4");
5084 case Match_UImmRange2_64:
5085 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5086 "expected immediate in range 2 .. 64");
5088 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5089 "expected 6-bit unsigned immediate");
5090 case Match_UImm6_Lsl2:
5091 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5092 "expected both 8-bit unsigned immediate and multiple of 4");
5094 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5095 "expected 6-bit signed immediate");
5097 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5098 "expected 7-bit unsigned immediate");
5099 case Match_UImm7_N1:
5100 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5101 "expected immediate in range -1 .. 126");
5102 case Match_SImm7_Lsl2:
5103 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5104 "expected both 9-bit signed immediate and multiple of 4");
5106 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5107 "expected 8-bit unsigned immediate");
5108 case Match_UImm10_0:
5109 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5110 "expected 10-bit unsigned immediate");
5111 case Match_SImm10_0:
5112 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5113 "expected 10-bit signed immediate");
5114 case Match_SImm11_0:
5115 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5116 "expected 11-bit signed immediate");
5118 case Match_UImm16_Relaxed:
5119 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5120 "expected 16-bit unsigned immediate");
5122 case Match_SImm16_Relaxed:
5123 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5124 "expected 16-bit signed immediate");
5125 case Match_SImm19_Lsl2:
5126 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5127 "expected both 19-bit signed immediate and multiple of 4");
5128 case Match_UImm20_0:
5129 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5130 "expected 20-bit unsigned immediate");
5131 case Match_UImm26_0:
5132 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5133 "expected 26-bit unsigned immediate");
5135 case Match_SImm32_Relaxed:
5136 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5137 "expected 32-bit signed immediate");
5138 case Match_UImm32_Coerced:
5139 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5140 "expected 32-bit immediate");
5141 case Match_MemSImm9:
5142 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5143 "expected memory with 9-bit signed offset");
5144 case Match_MemSImm10:
5145 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5146 "expected memory with 10-bit signed offset");
5147 case Match_MemSImm10Lsl1:
5148 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5149 "expected memory with 11-bit signed offset and multiple of 2");
5150 case Match_MemSImm10Lsl2:
5151 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5152 "expected memory with 12-bit signed offset and multiple of 4");
5153 case Match_MemSImm10Lsl3:
5154 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5155 "expected memory with 13-bit signed offset and multiple of 8");
5156 case Match_MemSImm11:
5157 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5158 "expected memory with 11-bit signed offset");
5159 case Match_MemSImm12:
5160 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5161 "expected memory with 12-bit signed offset");
5162 case Match_MemSImm16:
5163 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5164 "expected memory with 16-bit signed offset");
5167 llvm_unreachable("Implement any new match types added!");
5170 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5171 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5172 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5173 ") without \".set noat\"");
5176 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5177 if (!AssemblerOptions.back()->isMacro())
5178 Warning(Loc, "macro instruction expanded into multiple instructions");
5182 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5183 SMRange Range, bool ShowColors) {
5184 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5185 Range, SMFixIt(Range, FixMsg),
5189 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5192 CC = StringSwitch<unsigned>(Name)
5194 .Cases("at", "AT", 1)
5228 if (!(isABI_N32() || isABI_N64()))
5231 if (12 <= CC && CC <= 15) {
5232 // Name is one of t4-t7
5233 AsmToken RegTok = getLexer().peekTok();
5234 SMRange RegRange = RegTok.getLocRange();
5236 StringRef FixedName = StringSwitch<StringRef>(Name)
5242 assert(FixedName != "" && "Register name is not one of t4-t7.");
5244 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5245 "Did you mean $" + FixedName + "?", RegRange);
5248 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5249 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5250 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5251 if (8 <= CC && CC <= 11)
5255 CC = StringSwitch<unsigned>(Name)
5267 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5270 CC = StringSwitch<unsigned>(Name)
5271 .Case("hwr_cpunum", 0)
5272 .Case("hwr_synci_step", 1)
5274 .Case("hwr_ccres", 3)
5275 .Case("hwr_ulr", 29)
5281 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5282 if (Name[0] == 'f') {
5283 StringRef NumString = Name.substr(1);
5285 if (NumString.getAsInteger(10, IntVal))
5286 return -1; // This is not an integer.
5287 if (IntVal > 31) // Maximum index for fpu register.
5294 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5295 if (Name.startswith("fcc")) {
5296 StringRef NumString = Name.substr(3);
5298 if (NumString.getAsInteger(10, IntVal))
5299 return -1; // This is not an integer.
5300 if (IntVal > 7) // There are only 8 fcc registers.
5307 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5308 if (Name.startswith("ac")) {
5309 StringRef NumString = Name.substr(2);
5311 if (NumString.getAsInteger(10, IntVal))
5312 return -1; // This is not an integer.
5313 if (IntVal > 3) // There are only 3 acc registers.
5320 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5323 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5332 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5335 CC = StringSwitch<unsigned>(Name)
5338 .Case("msaaccess", 2)
5340 .Case("msamodify", 4)
5341 .Case("msarequest", 5)
5343 .Case("msaunmap", 7)
5349 bool MipsAsmParser::canUseATReg() {
5350 return AssemblerOptions.back()->getATRegIndex() != 0;
5353 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5354 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5356 reportParseError(Loc,
5357 "pseudo-instruction requires $at, which is not available");
5360 unsigned AT = getReg(
5361 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5365 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5366 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5369 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5370 MCAsmParser &Parser = getParser();
5371 DEBUG(dbgs() << "parseOperand\n");
5373 // Check if the current operand has a custom associated parser, if so, try to
5374 // custom parse the operand, or fallback to the general approach.
5375 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5376 if (ResTy == MatchOperand_Success)
5378 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5379 // there was a match, but an error occurred, in which case, just return that
5380 // the operand parsing failed.
5381 if (ResTy == MatchOperand_ParseFail)
5384 DEBUG(dbgs() << ".. Generic Parser\n");
5386 switch (getLexer().getKind()) {
5387 case AsmToken::Dollar: {
5388 // Parse the register.
5389 SMLoc S = Parser.getTok().getLoc();
5391 // Almost all registers have been parsed by custom parsers. There is only
5392 // one exception to this. $zero (and it's alias $0) will reach this point
5393 // for div, divu, and similar instructions because it is not an operand
5394 // to the instruction definition but an explicit register. Special case
5395 // this situation for now.
5396 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5399 // Maybe it is a symbol reference.
5400 StringRef Identifier;
5401 if (Parser.parseIdentifier(Identifier))
5404 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5405 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5406 // Otherwise create a symbol reference.
5408 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5410 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5414 DEBUG(dbgs() << ".. generic integer expression\n");
5417 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5418 if (getParser().parseExpression(Expr))
5421 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5423 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5426 } // switch(getLexer().getKind())
5430 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5431 switch (Expr->getKind()) {
5432 case MCExpr::Constant:
5434 case MCExpr::SymbolRef:
5435 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5436 case MCExpr::Binary:
5437 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
5438 if (!isEvaluated(BE->getLHS()))
5440 return isEvaluated(BE->getRHS());
5443 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5444 case MCExpr::Target:
5450 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5452 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5453 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5454 if (ResTy == MatchOperand_Success) {
5455 assert(Operands.size() == 1);
5456 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5457 StartLoc = Operand.getStartLoc();
5458 EndLoc = Operand.getEndLoc();
5460 // AFAIK, we only support numeric registers and named GPR's in CFI
5462 // Don't worry about eating tokens before failing. Using an unrecognised
5463 // register is a parse error.
5464 if (Operand.isGPRAsmReg()) {
5465 // Resolve to GPR32 or GPR64 appropriately.
5466 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5469 return (RegNo == (unsigned)-1);
5472 assert(Operands.size() == 0);
5473 return (RegNo == (unsigned)-1);
5476 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5480 return getParser().parseParenExprOfDepth(0, Res, S);
5481 return getParser().parseExpression(Res);
5484 OperandMatchResultTy
5485 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5486 MCAsmParser &Parser = getParser();
5487 DEBUG(dbgs() << "parseMemOperand\n");
5488 const MCExpr *IdVal = nullptr;
5490 bool isParenExpr = false;
5491 OperandMatchResultTy Res = MatchOperand_NoMatch;
5492 // First operand is the offset.
5493 S = Parser.getTok().getLoc();
5495 if (getLexer().getKind() == AsmToken::LParen) {
5500 if (getLexer().getKind() != AsmToken::Dollar) {
5501 if (parseMemOffset(IdVal, isParenExpr))
5502 return MatchOperand_ParseFail;
5504 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5505 if (Tok.isNot(AsmToken::LParen)) {
5506 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5507 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5509 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5510 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5511 return MatchOperand_Success;
5513 if (Tok.is(AsmToken::EndOfStatement)) {
5515 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5517 // Zero register assumed, add a memory operand with ZERO as its base.
5518 // "Base" will be managed by k_Memory.
5519 auto Base = MipsOperand::createGPRReg(
5520 0, "0", getContext().getRegisterInfo(), S, E, *this);
5522 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5523 return MatchOperand_Success;
5525 MCBinaryExpr::Opcode Opcode;
5526 // GAS and LLVM treat comparison operators different. GAS will generate -1
5527 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5528 // highly unlikely to be found in a memory offset expression, we don't
5530 switch (Tok.getKind()) {
5531 case AsmToken::Plus:
5532 Opcode = MCBinaryExpr::Add;
5535 case AsmToken::Minus:
5536 Opcode = MCBinaryExpr::Sub;
5539 case AsmToken::Star:
5540 Opcode = MCBinaryExpr::Mul;
5543 case AsmToken::Pipe:
5544 Opcode = MCBinaryExpr::Or;
5548 Opcode = MCBinaryExpr::And;
5551 case AsmToken::LessLess:
5552 Opcode = MCBinaryExpr::Shl;
5555 case AsmToken::GreaterGreater:
5556 Opcode = MCBinaryExpr::LShr;
5559 case AsmToken::Caret:
5560 Opcode = MCBinaryExpr::Xor;
5563 case AsmToken::Slash:
5564 Opcode = MCBinaryExpr::Div;
5567 case AsmToken::Percent:
5568 Opcode = MCBinaryExpr::Mod;
5572 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5573 return MatchOperand_ParseFail;
5575 const MCExpr * NextExpr;
5576 if (getParser().parseExpression(NextExpr))
5577 return MatchOperand_ParseFail;
5578 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5581 Parser.Lex(); // Eat the '(' token.
5584 Res = parseAnyRegister(Operands);
5585 if (Res != MatchOperand_Success)
5588 if (Parser.getTok().isNot(AsmToken::RParen)) {
5589 Error(Parser.getTok().getLoc(), "')' expected");
5590 return MatchOperand_ParseFail;
5593 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5595 Parser.Lex(); // Eat the ')' token.
5598 IdVal = MCConstantExpr::create(0, getContext());
5600 // Replace the register operand with the memory operand.
5601 std::unique_ptr<MipsOperand> op(
5602 static_cast<MipsOperand *>(Operands.back().release()));
5603 // Remove the register from the operands.
5604 // "op" will be managed by k_Memory.
5605 Operands.pop_back();
5606 // Add the memory operand.
5607 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5609 if (IdVal->evaluateAsAbsolute(Imm))
5610 IdVal = MCConstantExpr::create(Imm, getContext());
5611 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5612 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5616 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5617 return MatchOperand_Success;
5620 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5621 MCAsmParser &Parser = getParser();
5622 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5624 SMLoc S = Parser.getTok().getLoc();
5626 if (Sym->isVariable())
5627 Expr = Sym->getVariableValue();
5630 if (Expr->getKind() == MCExpr::SymbolRef) {
5631 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5632 StringRef DefSymbol = Ref->getSymbol().getName();
5633 if (DefSymbol.startswith("$")) {
5634 OperandMatchResultTy ResTy =
5635 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5636 if (ResTy == MatchOperand_Success) {
5639 } else if (ResTy == MatchOperand_ParseFail)
5640 llvm_unreachable("Should never ParseFail");
5648 OperandMatchResultTy
5649 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
5650 StringRef Identifier,
5652 int Index = matchCPURegisterName(Identifier);
5654 Operands.push_back(MipsOperand::createGPRReg(
5655 Index, Identifier, getContext().getRegisterInfo(), S,
5656 getLexer().getLoc(), *this));
5657 return MatchOperand_Success;
5660 Index = matchHWRegsRegisterName(Identifier);
5662 Operands.push_back(MipsOperand::createHWRegsReg(
5663 Index, Identifier, getContext().getRegisterInfo(), S,
5664 getLexer().getLoc(), *this));
5665 return MatchOperand_Success;
5668 Index = matchFPURegisterName(Identifier);
5670 Operands.push_back(MipsOperand::createFGRReg(
5671 Index, Identifier, getContext().getRegisterInfo(), S,
5672 getLexer().getLoc(), *this));
5673 return MatchOperand_Success;
5676 Index = matchFCCRegisterName(Identifier);
5678 Operands.push_back(MipsOperand::createFCCReg(
5679 Index, Identifier, getContext().getRegisterInfo(), S,
5680 getLexer().getLoc(), *this));
5681 return MatchOperand_Success;
5684 Index = matchACRegisterName(Identifier);
5686 Operands.push_back(MipsOperand::createACCReg(
5687 Index, Identifier, getContext().getRegisterInfo(), S,
5688 getLexer().getLoc(), *this));
5689 return MatchOperand_Success;
5692 Index = matchMSA128RegisterName(Identifier);
5694 Operands.push_back(MipsOperand::createMSA128Reg(
5695 Index, Identifier, getContext().getRegisterInfo(), S,
5696 getLexer().getLoc(), *this));
5697 return MatchOperand_Success;
5700 Index = matchMSA128CtrlRegisterName(Identifier);
5702 Operands.push_back(MipsOperand::createMSACtrlReg(
5703 Index, Identifier, getContext().getRegisterInfo(), S,
5704 getLexer().getLoc(), *this));
5705 return MatchOperand_Success;
5708 return MatchOperand_NoMatch;
5711 OperandMatchResultTy
5712 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
5713 MCAsmParser &Parser = getParser();
5714 auto Token = Parser.getLexer().peekTok(false);
5716 if (Token.is(AsmToken::Identifier)) {
5717 DEBUG(dbgs() << ".. identifier\n");
5718 StringRef Identifier = Token.getIdentifier();
5719 OperandMatchResultTy ResTy =
5720 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
5722 } else if (Token.is(AsmToken::Integer)) {
5723 DEBUG(dbgs() << ".. integer\n");
5724 Operands.push_back(MipsOperand::createNumericReg(
5725 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
5726 Token.getLoc(), *this));
5727 return MatchOperand_Success;
5730 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
5732 return MatchOperand_NoMatch;
5735 OperandMatchResultTy
5736 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
5737 MCAsmParser &Parser = getParser();
5738 DEBUG(dbgs() << "parseAnyRegister\n");
5740 auto Token = Parser.getTok();
5742 SMLoc S = Token.getLoc();
5744 if (Token.isNot(AsmToken::Dollar)) {
5745 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
5746 if (Token.is(AsmToken::Identifier)) {
5747 if (searchSymbolAlias(Operands))
5748 return MatchOperand_Success;
5750 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
5751 return MatchOperand_NoMatch;
5753 DEBUG(dbgs() << ".. $\n");
5755 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
5756 if (ResTy == MatchOperand_Success) {
5758 Parser.Lex(); // identifier
5763 OperandMatchResultTy
5764 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
5765 MCAsmParser &Parser = getParser();
5766 DEBUG(dbgs() << "parseJumpTarget\n");
5768 SMLoc S = getLexer().getLoc();
5770 // Registers are a valid target and have priority over symbols.
5771 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5772 if (ResTy != MatchOperand_NoMatch)
5775 // Integers and expressions are acceptable
5776 const MCExpr *Expr = nullptr;
5777 if (Parser.parseExpression(Expr)) {
5778 // We have no way of knowing if a symbol was consumed so we must ParseFail
5779 return MatchOperand_ParseFail;
5782 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
5783 return MatchOperand_Success;
5786 OperandMatchResultTy
5787 MipsAsmParser::parseInvNum(OperandVector &Operands) {
5788 MCAsmParser &Parser = getParser();
5789 const MCExpr *IdVal;
5790 // If the first token is '$' we may have register operand.
5791 if (Parser.getTok().is(AsmToken::Dollar))
5792 return MatchOperand_NoMatch;
5793 SMLoc S = Parser.getTok().getLoc();
5794 if (getParser().parseExpression(IdVal))
5795 return MatchOperand_ParseFail;
5796 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
5797 assert(MCE && "Unexpected MCExpr type.");
5798 int64_t Val = MCE->getValue();
5799 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5800 Operands.push_back(MipsOperand::CreateImm(
5801 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
5802 return MatchOperand_Success;
5805 OperandMatchResultTy
5806 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
5807 MCAsmParser &Parser = getParser();
5808 SmallVector<unsigned, 10> Regs;
5810 unsigned PrevReg = Mips::NoRegister;
5811 bool RegRange = false;
5812 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5814 if (Parser.getTok().isNot(AsmToken::Dollar))
5815 return MatchOperand_ParseFail;
5817 SMLoc S = Parser.getTok().getLoc();
5818 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
5819 SMLoc E = getLexer().getLoc();
5820 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
5821 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
5823 // Remove last register operand because registers from register range
5824 // should be inserted first.
5825 if ((isGP64bit() && RegNo == Mips::RA_64) ||
5826 (!isGP64bit() && RegNo == Mips::RA)) {
5827 Regs.push_back(RegNo);
5829 unsigned TmpReg = PrevReg + 1;
5830 while (TmpReg <= RegNo) {
5831 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
5832 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
5834 Error(E, "invalid register operand");
5835 return MatchOperand_ParseFail;
5839 Regs.push_back(TmpReg++);
5845 if ((PrevReg == Mips::NoRegister) &&
5846 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5847 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5848 Error(E, "$16 or $31 expected");
5849 return MatchOperand_ParseFail;
5850 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5851 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5853 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5854 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5856 Error(E, "invalid register operand");
5857 return MatchOperand_ParseFail;
5858 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5859 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5860 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5862 Error(E, "consecutive register numbers expected");
5863 return MatchOperand_ParseFail;
5866 Regs.push_back(RegNo);
5869 if (Parser.getTok().is(AsmToken::Minus))
5872 if (!Parser.getTok().isNot(AsmToken::Minus) &&
5873 !Parser.getTok().isNot(AsmToken::Comma)) {
5874 Error(E, "',' or '-' expected");
5875 return MatchOperand_ParseFail;
5878 Lex(); // Consume comma or minus
5879 if (Parser.getTok().isNot(AsmToken::Dollar))
5885 SMLoc E = Parser.getTok().getLoc();
5886 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5887 parseMemOperand(Operands);
5888 return MatchOperand_Success;
5891 OperandMatchResultTy
5892 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
5893 MCAsmParser &Parser = getParser();
5895 SMLoc S = Parser.getTok().getLoc();
5896 if (parseAnyRegister(Operands) != MatchOperand_Success)
5897 return MatchOperand_ParseFail;
5899 SMLoc E = Parser.getTok().getLoc();
5900 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
5902 Operands.pop_back();
5903 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
5904 return MatchOperand_Success;
5907 OperandMatchResultTy
5908 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
5909 MCAsmParser &Parser = getParser();
5910 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5911 SmallVector<unsigned, 10> Regs;
5913 if (Parser.getTok().isNot(AsmToken::Dollar))
5914 return MatchOperand_ParseFail;
5916 SMLoc S = Parser.getTok().getLoc();
5918 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5919 return MatchOperand_ParseFail;
5921 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5922 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5923 Regs.push_back(RegNo);
5925 SMLoc E = Parser.getTok().getLoc();
5926 if (Parser.getTok().isNot(AsmToken::Comma)) {
5927 Error(E, "',' expected");
5928 return MatchOperand_ParseFail;
5934 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5935 return MatchOperand_ParseFail;
5937 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5938 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5939 Regs.push_back(RegNo);
5941 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5943 return MatchOperand_Success;
5946 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
5948 /// ::= '(', register, ')'
5949 /// handle it before we iterate so we don't get tripped up by the lack of
5951 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
5952 MCAsmParser &Parser = getParser();
5953 if (getLexer().is(AsmToken::LParen)) {
5955 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
5957 if (parseOperand(Operands, Name)) {
5958 SMLoc Loc = getLexer().getLoc();
5959 return Error(Loc, "unexpected token in argument list");
5961 if (Parser.getTok().isNot(AsmToken::RParen)) {
5962 SMLoc Loc = getLexer().getLoc();
5963 return Error(Loc, "unexpected token, expected ')'");
5966 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
5972 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
5973 /// either one of these.
5974 /// ::= '[', register, ']'
5975 /// ::= '[', integer, ']'
5976 /// handle it before we iterate so we don't get tripped up by the lack of
5978 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
5979 OperandVector &Operands) {
5980 MCAsmParser &Parser = getParser();
5981 if (getLexer().is(AsmToken::LBrac)) {
5983 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
5985 if (parseOperand(Operands, Name)) {
5986 SMLoc Loc = getLexer().getLoc();
5987 return Error(Loc, "unexpected token in argument list");
5989 if (Parser.getTok().isNot(AsmToken::RBrac)) {
5990 SMLoc Loc = getLexer().getLoc();
5991 return Error(Loc, "unexpected token, expected ']'");
5994 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6000 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6001 SMLoc NameLoc, OperandVector &Operands) {
6002 MCAsmParser &Parser = getParser();
6003 DEBUG(dbgs() << "ParseInstruction\n");
6005 // We have reached first instruction, module directive are now forbidden.
6006 getTargetStreamer().forbidModuleDirective();
6008 // Check if we have valid mnemonic
6009 if (!mnemonicIsValid(Name, 0)) {
6010 return Error(NameLoc, "unknown instruction");
6012 // First operand in MCInst is instruction mnemonic.
6013 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6015 // Read the remaining operands.
6016 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6017 // Read the first operand.
6018 if (parseOperand(Operands, Name)) {
6019 SMLoc Loc = getLexer().getLoc();
6020 return Error(Loc, "unexpected token in argument list");
6022 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6024 // AFAIK, parenthesis suffixes are never on the first operand
6026 while (getLexer().is(AsmToken::Comma)) {
6027 Parser.Lex(); // Eat the comma.
6028 // Parse and remember the operand.
6029 if (parseOperand(Operands, Name)) {
6030 SMLoc Loc = getLexer().getLoc();
6031 return Error(Loc, "unexpected token in argument list");
6033 // Parse bracket and parenthesis suffixes before we iterate
6034 if (getLexer().is(AsmToken::LBrac)) {
6035 if (parseBracketSuffix(Name, Operands))
6037 } else if (getLexer().is(AsmToken::LParen) &&
6038 parseParenSuffix(Name, Operands))
6042 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6043 SMLoc Loc = getLexer().getLoc();
6044 return Error(Loc, "unexpected token in argument list");
6046 Parser.Lex(); // Consume the EndOfStatement.
6050 // FIXME: Given that these have the same name, these should both be
6051 // consistent on affecting the Parser.
6052 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6053 SMLoc Loc = getLexer().getLoc();
6054 return Error(Loc, ErrorMsg);
6057 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6058 return Error(Loc, ErrorMsg);
6061 bool MipsAsmParser::parseSetNoAtDirective() {
6062 MCAsmParser &Parser = getParser();
6063 // Line should look like: ".set noat".
6065 // Set the $at register to $0.
6066 AssemblerOptions.back()->setATRegIndex(0);
6068 Parser.Lex(); // Eat "noat".
6070 // If this is not the end of the statement, report an error.
6071 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6072 reportParseError("unexpected token, expected end of statement");
6076 getTargetStreamer().emitDirectiveSetNoAt();
6077 Parser.Lex(); // Consume the EndOfStatement.
6081 bool MipsAsmParser::parseSetAtDirective() {
6082 // Line can be: ".set at", which sets $at to $1
6083 // or ".set at=$reg", which sets $at to $reg.
6084 MCAsmParser &Parser = getParser();
6085 Parser.Lex(); // Eat "at".
6087 if (getLexer().is(AsmToken::EndOfStatement)) {
6088 // No register was specified, so we set $at to $1.
6089 AssemblerOptions.back()->setATRegIndex(1);
6091 getTargetStreamer().emitDirectiveSetAt();
6092 Parser.Lex(); // Consume the EndOfStatement.
6096 if (getLexer().isNot(AsmToken::Equal)) {
6097 reportParseError("unexpected token, expected equals sign");
6100 Parser.Lex(); // Eat "=".
6102 if (getLexer().isNot(AsmToken::Dollar)) {
6103 if (getLexer().is(AsmToken::EndOfStatement)) {
6104 reportParseError("no register specified");
6107 reportParseError("unexpected token, expected dollar sign '$'");
6111 Parser.Lex(); // Eat "$".
6113 // Find out what "reg" is.
6115 const AsmToken &Reg = Parser.getTok();
6116 if (Reg.is(AsmToken::Identifier)) {
6117 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6118 } else if (Reg.is(AsmToken::Integer)) {
6119 AtRegNo = Reg.getIntVal();
6121 reportParseError("unexpected token, expected identifier or integer");
6125 // Check if $reg is a valid register. If it is, set $at to $reg.
6126 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6127 reportParseError("invalid register");
6130 Parser.Lex(); // Eat "reg".
6132 // If this is not the end of the statement, report an error.
6133 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6134 reportParseError("unexpected token, expected end of statement");
6138 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6140 Parser.Lex(); // Consume the EndOfStatement.
6144 bool MipsAsmParser::parseSetReorderDirective() {
6145 MCAsmParser &Parser = getParser();
6147 // If this is not the end of the statement, report an error.
6148 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6149 reportParseError("unexpected token, expected end of statement");
6152 AssemblerOptions.back()->setReorder();
6153 getTargetStreamer().emitDirectiveSetReorder();
6154 Parser.Lex(); // Consume the EndOfStatement.
6158 bool MipsAsmParser::parseSetNoReorderDirective() {
6159 MCAsmParser &Parser = getParser();
6161 // If this is not the end of the statement, report an error.
6162 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6163 reportParseError("unexpected token, expected end of statement");
6166 AssemblerOptions.back()->setNoReorder();
6167 getTargetStreamer().emitDirectiveSetNoReorder();
6168 Parser.Lex(); // Consume the EndOfStatement.
6172 bool MipsAsmParser::parseSetMacroDirective() {
6173 MCAsmParser &Parser = getParser();
6175 // If this is not the end of the statement, report an error.
6176 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6177 reportParseError("unexpected token, expected end of statement");
6180 AssemblerOptions.back()->setMacro();
6181 getTargetStreamer().emitDirectiveSetMacro();
6182 Parser.Lex(); // Consume the EndOfStatement.
6186 bool MipsAsmParser::parseSetNoMacroDirective() {
6187 MCAsmParser &Parser = getParser();
6189 // If this is not the end of the statement, report an error.
6190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6191 reportParseError("unexpected token, expected end of statement");
6194 if (AssemblerOptions.back()->isReorder()) {
6195 reportParseError("`noreorder' must be set before `nomacro'");
6198 AssemblerOptions.back()->setNoMacro();
6199 getTargetStreamer().emitDirectiveSetNoMacro();
6200 Parser.Lex(); // Consume the EndOfStatement.
6204 bool MipsAsmParser::parseSetMsaDirective() {
6205 MCAsmParser &Parser = getParser();
6208 // If this is not the end of the statement, report an error.
6209 if (getLexer().isNot(AsmToken::EndOfStatement))
6210 return reportParseError("unexpected token, expected end of statement");
6212 setFeatureBits(Mips::FeatureMSA, "msa");
6213 getTargetStreamer().emitDirectiveSetMsa();
6217 bool MipsAsmParser::parseSetNoMsaDirective() {
6218 MCAsmParser &Parser = getParser();
6221 // If this is not the end of the statement, report an error.
6222 if (getLexer().isNot(AsmToken::EndOfStatement))
6223 return reportParseError("unexpected token, expected end of statement");
6225 clearFeatureBits(Mips::FeatureMSA, "msa");
6226 getTargetStreamer().emitDirectiveSetNoMsa();
6230 bool MipsAsmParser::parseSetNoDspDirective() {
6231 MCAsmParser &Parser = getParser();
6232 Parser.Lex(); // Eat "nodsp".
6234 // If this is not the end of the statement, report an error.
6235 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6236 reportParseError("unexpected token, expected end of statement");
6240 clearFeatureBits(Mips::FeatureDSP, "dsp");
6241 getTargetStreamer().emitDirectiveSetNoDsp();
6245 bool MipsAsmParser::parseSetMips16Directive() {
6246 MCAsmParser &Parser = getParser();
6247 Parser.Lex(); // Eat "mips16".
6249 // If this is not the end of the statement, report an error.
6250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6251 reportParseError("unexpected token, expected end of statement");
6255 setFeatureBits(Mips::FeatureMips16, "mips16");
6256 getTargetStreamer().emitDirectiveSetMips16();
6257 Parser.Lex(); // Consume the EndOfStatement.
6261 bool MipsAsmParser::parseSetNoMips16Directive() {
6262 MCAsmParser &Parser = getParser();
6263 Parser.Lex(); // Eat "nomips16".
6265 // If this is not the end of the statement, report an error.
6266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6267 reportParseError("unexpected token, expected end of statement");
6271 clearFeatureBits(Mips::FeatureMips16, "mips16");
6272 getTargetStreamer().emitDirectiveSetNoMips16();
6273 Parser.Lex(); // Consume the EndOfStatement.
6277 bool MipsAsmParser::parseSetFpDirective() {
6278 MCAsmParser &Parser = getParser();
6279 MipsABIFlagsSection::FpABIKind FpAbiVal;
6280 // Line can be: .set fp=32
6283 Parser.Lex(); // Eat fp token
6284 AsmToken Tok = Parser.getTok();
6285 if (Tok.isNot(AsmToken::Equal)) {
6286 reportParseError("unexpected token, expected equals sign '='");
6289 Parser.Lex(); // Eat '=' token.
6290 Tok = Parser.getTok();
6292 if (!parseFpABIValue(FpAbiVal, ".set"))
6295 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6296 reportParseError("unexpected token, expected end of statement");
6299 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6300 Parser.Lex(); // Consume the EndOfStatement.
6304 bool MipsAsmParser::parseSetOddSPRegDirective() {
6305 MCAsmParser &Parser = getParser();
6307 Parser.Lex(); // Eat "oddspreg".
6308 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6309 reportParseError("unexpected token, expected end of statement");
6313 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6314 getTargetStreamer().emitDirectiveSetOddSPReg();
6318 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6319 MCAsmParser &Parser = getParser();
6321 Parser.Lex(); // Eat "nooddspreg".
6322 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6323 reportParseError("unexpected token, expected end of statement");
6327 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6328 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6332 bool MipsAsmParser::parseSetPopDirective() {
6333 MCAsmParser &Parser = getParser();
6334 SMLoc Loc = getLexer().getLoc();
6337 if (getLexer().isNot(AsmToken::EndOfStatement))
6338 return reportParseError("unexpected token, expected end of statement");
6340 // Always keep an element on the options "stack" to prevent the user
6341 // from changing the initial options. This is how we remember them.
6342 if (AssemblerOptions.size() == 2)
6343 return reportParseError(Loc, ".set pop with no .set push");
6345 MCSubtargetInfo &STI = copySTI();
6346 AssemblerOptions.pop_back();
6347 setAvailableFeatures(
6348 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6349 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6351 getTargetStreamer().emitDirectiveSetPop();
6355 bool MipsAsmParser::parseSetPushDirective() {
6356 MCAsmParser &Parser = getParser();
6358 if (getLexer().isNot(AsmToken::EndOfStatement))
6359 return reportParseError("unexpected token, expected end of statement");
6361 // Create a copy of the current assembler options environment and push it.
6362 AssemblerOptions.push_back(
6363 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6365 getTargetStreamer().emitDirectiveSetPush();
6369 bool MipsAsmParser::parseSetSoftFloatDirective() {
6370 MCAsmParser &Parser = getParser();
6372 if (getLexer().isNot(AsmToken::EndOfStatement))
6373 return reportParseError("unexpected token, expected end of statement");
6375 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6376 getTargetStreamer().emitDirectiveSetSoftFloat();
6380 bool MipsAsmParser::parseSetHardFloatDirective() {
6381 MCAsmParser &Parser = getParser();
6383 if (getLexer().isNot(AsmToken::EndOfStatement))
6384 return reportParseError("unexpected token, expected end of statement");
6386 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6387 getTargetStreamer().emitDirectiveSetHardFloat();
6391 bool MipsAsmParser::parseSetAssignment() {
6393 const MCExpr *Value;
6394 MCAsmParser &Parser = getParser();
6396 if (Parser.parseIdentifier(Name))
6397 reportParseError("expected identifier after .set");
6399 if (getLexer().isNot(AsmToken::Comma))
6400 return reportParseError("unexpected token, expected comma");
6403 if (Parser.parseExpression(Value))
6404 return reportParseError("expected valid expression after comma");
6406 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6407 Sym->setVariableValue(Value);
6412 bool MipsAsmParser::parseSetMips0Directive() {
6413 MCAsmParser &Parser = getParser();
6415 if (getLexer().isNot(AsmToken::EndOfStatement))
6416 return reportParseError("unexpected token, expected end of statement");
6418 // Reset assembler options to their initial values.
6419 MCSubtargetInfo &STI = copySTI();
6420 setAvailableFeatures(
6421 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6422 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6423 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6425 getTargetStreamer().emitDirectiveSetMips0();
6429 bool MipsAsmParser::parseSetArchDirective() {
6430 MCAsmParser &Parser = getParser();
6432 if (getLexer().isNot(AsmToken::Equal))
6433 return reportParseError("unexpected token, expected equals sign");
6437 if (Parser.parseIdentifier(Arch))
6438 return reportParseError("expected arch identifier");
6440 StringRef ArchFeatureName =
6441 StringSwitch<StringRef>(Arch)
6442 .Case("mips1", "mips1")
6443 .Case("mips2", "mips2")
6444 .Case("mips3", "mips3")
6445 .Case("mips4", "mips4")
6446 .Case("mips5", "mips5")
6447 .Case("mips32", "mips32")
6448 .Case("mips32r2", "mips32r2")
6449 .Case("mips32r3", "mips32r3")
6450 .Case("mips32r5", "mips32r5")
6451 .Case("mips32r6", "mips32r6")
6452 .Case("mips64", "mips64")
6453 .Case("mips64r2", "mips64r2")
6454 .Case("mips64r3", "mips64r3")
6455 .Case("mips64r5", "mips64r5")
6456 .Case("mips64r6", "mips64r6")
6457 .Case("octeon", "cnmips")
6458 .Case("r4000", "mips3") // This is an implementation of Mips3.
6461 if (ArchFeatureName.empty())
6462 return reportParseError("unsupported architecture");
6464 selectArch(ArchFeatureName);
6465 getTargetStreamer().emitDirectiveSetArch(Arch);
6469 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6470 MCAsmParser &Parser = getParser();
6472 if (getLexer().isNot(AsmToken::EndOfStatement))
6473 return reportParseError("unexpected token, expected end of statement");
6477 llvm_unreachable("Unimplemented feature");
6478 case Mips::FeatureDSP:
6479 setFeatureBits(Mips::FeatureDSP, "dsp");
6480 getTargetStreamer().emitDirectiveSetDsp();
6482 case Mips::FeatureMicroMips:
6483 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6484 getTargetStreamer().emitDirectiveSetMicroMips();
6486 case Mips::FeatureMips1:
6487 selectArch("mips1");
6488 getTargetStreamer().emitDirectiveSetMips1();
6490 case Mips::FeatureMips2:
6491 selectArch("mips2");
6492 getTargetStreamer().emitDirectiveSetMips2();
6494 case Mips::FeatureMips3:
6495 selectArch("mips3");
6496 getTargetStreamer().emitDirectiveSetMips3();
6498 case Mips::FeatureMips4:
6499 selectArch("mips4");
6500 getTargetStreamer().emitDirectiveSetMips4();
6502 case Mips::FeatureMips5:
6503 selectArch("mips5");
6504 getTargetStreamer().emitDirectiveSetMips5();
6506 case Mips::FeatureMips32:
6507 selectArch("mips32");
6508 getTargetStreamer().emitDirectiveSetMips32();
6510 case Mips::FeatureMips32r2:
6511 selectArch("mips32r2");
6512 getTargetStreamer().emitDirectiveSetMips32R2();
6514 case Mips::FeatureMips32r3:
6515 selectArch("mips32r3");
6516 getTargetStreamer().emitDirectiveSetMips32R3();
6518 case Mips::FeatureMips32r5:
6519 selectArch("mips32r5");
6520 getTargetStreamer().emitDirectiveSetMips32R5();
6522 case Mips::FeatureMips32r6:
6523 selectArch("mips32r6");
6524 getTargetStreamer().emitDirectiveSetMips32R6();
6526 case Mips::FeatureMips64:
6527 selectArch("mips64");
6528 getTargetStreamer().emitDirectiveSetMips64();
6530 case Mips::FeatureMips64r2:
6531 selectArch("mips64r2");
6532 getTargetStreamer().emitDirectiveSetMips64R2();
6534 case Mips::FeatureMips64r3:
6535 selectArch("mips64r3");
6536 getTargetStreamer().emitDirectiveSetMips64R3();
6538 case Mips::FeatureMips64r5:
6539 selectArch("mips64r5");
6540 getTargetStreamer().emitDirectiveSetMips64R5();
6542 case Mips::FeatureMips64r6:
6543 selectArch("mips64r6");
6544 getTargetStreamer().emitDirectiveSetMips64R6();
6550 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6551 MCAsmParser &Parser = getParser();
6552 if (getLexer().isNot(AsmToken::Comma)) {
6553 SMLoc Loc = getLexer().getLoc();
6554 return Error(Loc, ErrorStr);
6557 Parser.Lex(); // Eat the comma.
6561 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
6562 // In this class, it is only used for .cprestore.
6563 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
6564 // MipsTargetELFStreamer and MipsAsmParser.
6565 bool MipsAsmParser::isPicAndNotNxxAbi() {
6566 return inPicMode() && !(isABI_N32() || isABI_N64());
6569 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
6570 if (AssemblerOptions.back()->isReorder())
6571 Warning(Loc, ".cpload should be inside a noreorder section");
6573 if (inMips16Mode()) {
6574 reportParseError(".cpload is not supported in Mips16 mode");
6578 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
6579 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
6580 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6581 reportParseError("expected register containing function address");
6585 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
6586 if (!RegOpnd.isGPRAsmReg()) {
6587 reportParseError(RegOpnd.getStartLoc(), "invalid register");
6591 // If this is not the end of the statement, report an error.
6592 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6593 reportParseError("unexpected token, expected end of statement");
6597 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
6601 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
6602 MCAsmParser &Parser = getParser();
6604 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
6605 // is used in non-PIC mode.
6607 if (inMips16Mode()) {
6608 reportParseError(".cprestore is not supported in Mips16 mode");
6612 // Get the stack offset value.
6613 const MCExpr *StackOffset;
6614 int64_t StackOffsetVal;
6615 if (Parser.parseExpression(StackOffset)) {
6616 reportParseError("expected stack offset value");
6620 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
6621 reportParseError("stack offset is not an absolute expression");
6625 if (StackOffsetVal < 0) {
6626 Warning(Loc, ".cprestore with negative stack offset has no effect");
6627 IsCpRestoreSet = false;
6629 IsCpRestoreSet = true;
6630 CpRestoreOffset = StackOffsetVal;
6633 // If this is not the end of the statement, report an error.
6634 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6635 reportParseError("unexpected token, expected end of statement");
6639 if (!getTargetStreamer().emitDirectiveCpRestore(
6640 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
6642 Parser.Lex(); // Consume the EndOfStatement.
6646 bool MipsAsmParser::parseDirectiveCPSetup() {
6647 MCAsmParser &Parser = getParser();
6650 bool SaveIsReg = true;
6652 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6653 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6654 if (ResTy == MatchOperand_NoMatch) {
6655 reportParseError("expected register containing function address");
6659 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6660 if (!FuncRegOpnd.isGPRAsmReg()) {
6661 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
6665 FuncReg = FuncRegOpnd.getGPR32Reg();
6668 if (!eatComma("unexpected token, expected comma"))
6671 ResTy = parseAnyRegister(TmpReg);
6672 if (ResTy == MatchOperand_NoMatch) {
6673 const MCExpr *OffsetExpr;
6675 SMLoc ExprLoc = getLexer().getLoc();
6677 if (Parser.parseExpression(OffsetExpr) ||
6678 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
6679 reportParseError(ExprLoc, "expected save register or stack offset");
6686 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6687 if (!SaveOpnd.isGPRAsmReg()) {
6688 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
6691 Save = SaveOpnd.getGPR32Reg();
6694 if (!eatComma("unexpected token, expected comma"))
6698 if (Parser.parseExpression(Expr)) {
6699 reportParseError("expected expression");
6703 if (Expr->getKind() != MCExpr::SymbolRef) {
6704 reportParseError("expected symbol");
6707 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6709 CpSaveLocation = Save;
6710 CpSaveLocationIsRegister = SaveIsReg;
6712 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
6717 bool MipsAsmParser::parseDirectiveCPReturn() {
6718 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
6719 CpSaveLocationIsRegister);
6723 bool MipsAsmParser::parseDirectiveNaN() {
6724 MCAsmParser &Parser = getParser();
6725 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6726 const AsmToken &Tok = Parser.getTok();
6728 if (Tok.getString() == "2008") {
6730 getTargetStreamer().emitDirectiveNaN2008();
6732 } else if (Tok.getString() == "legacy") {
6734 getTargetStreamer().emitDirectiveNaNLegacy();
6738 // If we don't recognize the option passed to the .nan
6739 // directive (e.g. no option or unknown option), emit an error.
6740 reportParseError("invalid option in .nan directive");
6744 bool MipsAsmParser::parseDirectiveSet() {
6745 MCAsmParser &Parser = getParser();
6746 // Get the next token.
6747 const AsmToken &Tok = Parser.getTok();
6749 if (Tok.getString() == "noat") {
6750 return parseSetNoAtDirective();
6751 } else if (Tok.getString() == "at") {
6752 return parseSetAtDirective();
6753 } else if (Tok.getString() == "arch") {
6754 return parseSetArchDirective();
6755 } else if (Tok.getString() == "bopt") {
6756 Warning(Tok.getLoc(), "'bopt' feature is unsupported");
6759 } else if (Tok.getString() == "nobopt") {
6760 // We're already running in nobopt mode, so nothing to do.
6763 } else if (Tok.getString() == "fp") {
6764 return parseSetFpDirective();
6765 } else if (Tok.getString() == "oddspreg") {
6766 return parseSetOddSPRegDirective();
6767 } else if (Tok.getString() == "nooddspreg") {
6768 return parseSetNoOddSPRegDirective();
6769 } else if (Tok.getString() == "pop") {
6770 return parseSetPopDirective();
6771 } else if (Tok.getString() == "push") {
6772 return parseSetPushDirective();
6773 } else if (Tok.getString() == "reorder") {
6774 return parseSetReorderDirective();
6775 } else if (Tok.getString() == "noreorder") {
6776 return parseSetNoReorderDirective();
6777 } else if (Tok.getString() == "macro") {
6778 return parseSetMacroDirective();
6779 } else if (Tok.getString() == "nomacro") {
6780 return parseSetNoMacroDirective();
6781 } else if (Tok.getString() == "mips16") {
6782 return parseSetMips16Directive();
6783 } else if (Tok.getString() == "nomips16") {
6784 return parseSetNoMips16Directive();
6785 } else if (Tok.getString() == "nomicromips") {
6786 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
6787 getTargetStreamer().emitDirectiveSetNoMicroMips();
6788 Parser.eatToEndOfStatement();
6790 } else if (Tok.getString() == "micromips") {
6791 return parseSetFeature(Mips::FeatureMicroMips);
6792 } else if (Tok.getString() == "mips0") {
6793 return parseSetMips0Directive();
6794 } else if (Tok.getString() == "mips1") {
6795 return parseSetFeature(Mips::FeatureMips1);
6796 } else if (Tok.getString() == "mips2") {
6797 return parseSetFeature(Mips::FeatureMips2);
6798 } else if (Tok.getString() == "mips3") {
6799 return parseSetFeature(Mips::FeatureMips3);
6800 } else if (Tok.getString() == "mips4") {
6801 return parseSetFeature(Mips::FeatureMips4);
6802 } else if (Tok.getString() == "mips5") {
6803 return parseSetFeature(Mips::FeatureMips5);
6804 } else if (Tok.getString() == "mips32") {
6805 return parseSetFeature(Mips::FeatureMips32);
6806 } else if (Tok.getString() == "mips32r2") {
6807 return parseSetFeature(Mips::FeatureMips32r2);
6808 } else if (Tok.getString() == "mips32r3") {
6809 return parseSetFeature(Mips::FeatureMips32r3);
6810 } else if (Tok.getString() == "mips32r5") {
6811 return parseSetFeature(Mips::FeatureMips32r5);
6812 } else if (Tok.getString() == "mips32r6") {
6813 return parseSetFeature(Mips::FeatureMips32r6);
6814 } else if (Tok.getString() == "mips64") {
6815 return parseSetFeature(Mips::FeatureMips64);
6816 } else if (Tok.getString() == "mips64r2") {
6817 return parseSetFeature(Mips::FeatureMips64r2);
6818 } else if (Tok.getString() == "mips64r3") {
6819 return parseSetFeature(Mips::FeatureMips64r3);
6820 } else if (Tok.getString() == "mips64r5") {
6821 return parseSetFeature(Mips::FeatureMips64r5);
6822 } else if (Tok.getString() == "mips64r6") {
6823 return parseSetFeature(Mips::FeatureMips64r6);
6824 } else if (Tok.getString() == "dsp") {
6825 return parseSetFeature(Mips::FeatureDSP);
6826 } else if (Tok.getString() == "nodsp") {
6827 return parseSetNoDspDirective();
6828 } else if (Tok.getString() == "msa") {
6829 return parseSetMsaDirective();
6830 } else if (Tok.getString() == "nomsa") {
6831 return parseSetNoMsaDirective();
6832 } else if (Tok.getString() == "softfloat") {
6833 return parseSetSoftFloatDirective();
6834 } else if (Tok.getString() == "hardfloat") {
6835 return parseSetHardFloatDirective();
6837 // It is just an identifier, look for an assignment.
6838 parseSetAssignment();
6845 /// parseDataDirective
6846 /// ::= .word [ expression (, expression)* ]
6847 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
6848 MCAsmParser &Parser = getParser();
6849 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6851 const MCExpr *Value;
6852 if (getParser().parseExpression(Value))
6855 getParser().getStreamer().EmitValue(Value, Size);
6857 if (getLexer().is(AsmToken::EndOfStatement))
6860 if (getLexer().isNot(AsmToken::Comma))
6861 return Error(L, "unexpected token, expected comma");
6870 /// parseDirectiveGpWord
6871 /// ::= .gpword local_sym
6872 bool MipsAsmParser::parseDirectiveGpWord() {
6873 MCAsmParser &Parser = getParser();
6874 const MCExpr *Value;
6875 // EmitGPRel32Value requires an expression, so we are using base class
6876 // method to evaluate the expression.
6877 if (getParser().parseExpression(Value))
6879 getParser().getStreamer().EmitGPRel32Value(Value);
6881 if (getLexer().isNot(AsmToken::EndOfStatement))
6882 return Error(getLexer().getLoc(),
6883 "unexpected token, expected end of statement");
6884 Parser.Lex(); // Eat EndOfStatement token.
6888 /// parseDirectiveGpDWord
6889 /// ::= .gpdword local_sym
6890 bool MipsAsmParser::parseDirectiveGpDWord() {
6891 MCAsmParser &Parser = getParser();
6892 const MCExpr *Value;
6893 // EmitGPRel64Value requires an expression, so we are using base class
6894 // method to evaluate the expression.
6895 if (getParser().parseExpression(Value))
6897 getParser().getStreamer().EmitGPRel64Value(Value);
6899 if (getLexer().isNot(AsmToken::EndOfStatement))
6900 return Error(getLexer().getLoc(),
6901 "unexpected token, expected end of statement");
6902 Parser.Lex(); // Eat EndOfStatement token.
6906 /// parseDirectiveDtpRelWord
6907 /// ::= .dtprelword tls_sym
6908 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6909 MCAsmParser &Parser = getParser();
6910 const MCExpr *Value;
6911 // EmitDTPRel32Value requires an expression, so we are using base class
6912 // method to evaluate the expression.
6913 if (getParser().parseExpression(Value))
6915 getParser().getStreamer().EmitDTPRel32Value(Value);
6917 if (getLexer().isNot(AsmToken::EndOfStatement))
6918 return Error(getLexer().getLoc(),
6919 "unexpected token, expected end of statement");
6920 Parser.Lex(); // Eat EndOfStatement token.
6924 /// parseDirectiveDtpRelDWord
6925 /// ::= .dtpreldword tls_sym
6926 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6927 MCAsmParser &Parser = getParser();
6928 const MCExpr *Value;
6929 // EmitDTPRel64Value requires an expression, so we are using base class
6930 // method to evaluate the expression.
6931 if (getParser().parseExpression(Value))
6933 getParser().getStreamer().EmitDTPRel64Value(Value);
6935 if (getLexer().isNot(AsmToken::EndOfStatement))
6936 return Error(getLexer().getLoc(),
6937 "unexpected token, expected end of statement");
6938 Parser.Lex(); // Eat EndOfStatement token.
6942 /// parseDirectiveTpRelWord
6943 /// ::= .tprelword tls_sym
6944 bool MipsAsmParser::parseDirectiveTpRelWord() {
6945 MCAsmParser &Parser = getParser();
6946 const MCExpr *Value;
6947 // EmitTPRel32Value requires an expression, so we are using base class
6948 // method to evaluate the expression.
6949 if (getParser().parseExpression(Value))
6951 getParser().getStreamer().EmitTPRel32Value(Value);
6953 if (getLexer().isNot(AsmToken::EndOfStatement))
6954 return Error(getLexer().getLoc(),
6955 "unexpected token, expected end of statement");
6956 Parser.Lex(); // Eat EndOfStatement token.
6960 /// parseDirectiveTpRelDWord
6961 /// ::= .tpreldword tls_sym
6962 bool MipsAsmParser::parseDirectiveTpRelDWord() {
6963 MCAsmParser &Parser = getParser();
6964 const MCExpr *Value;
6965 // EmitTPRel64Value requires an expression, so we are using base class
6966 // method to evaluate the expression.
6967 if (getParser().parseExpression(Value))
6969 getParser().getStreamer().EmitTPRel64Value(Value);
6971 if (getLexer().isNot(AsmToken::EndOfStatement))
6972 return Error(getLexer().getLoc(),
6973 "unexpected token, expected end of statement");
6974 Parser.Lex(); // Eat EndOfStatement token.
6978 bool MipsAsmParser::parseDirectiveOption() {
6979 MCAsmParser &Parser = getParser();
6980 // Get the option token.
6981 AsmToken Tok = Parser.getTok();
6982 // At the moment only identifiers are supported.
6983 if (Tok.isNot(AsmToken::Identifier)) {
6984 return Error(Parser.getTok().getLoc(),
6985 "unexpected token, expected identifier");
6988 StringRef Option = Tok.getIdentifier();
6990 if (Option == "pic0") {
6991 // MipsAsmParser needs to know if the current PIC mode changes.
6992 IsPicEnabled = false;
6994 getTargetStreamer().emitDirectiveOptionPic0();
6996 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6997 return Error(Parser.getTok().getLoc(),
6998 "unexpected token, expected end of statement");
7003 if (Option == "pic2") {
7004 // MipsAsmParser needs to know if the current PIC mode changes.
7005 IsPicEnabled = true;
7007 getTargetStreamer().emitDirectiveOptionPic2();
7009 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7010 return Error(Parser.getTok().getLoc(),
7011 "unexpected token, expected end of statement");
7017 Warning(Parser.getTok().getLoc(),
7018 "unknown option, expected 'pic0' or 'pic2'");
7019 Parser.eatToEndOfStatement();
7023 /// parseInsnDirective
7025 bool MipsAsmParser::parseInsnDirective() {
7026 // If this is not the end of the statement, report an error.
7027 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7028 reportParseError("unexpected token, expected end of statement");
7032 // The actual label marking happens in
7033 // MipsELFStreamer::createPendingLabelRelocs().
7034 getTargetStreamer().emitDirectiveInsn();
7036 getParser().Lex(); // Eat EndOfStatement token.
7040 /// parseRSectionDirective
7042 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7043 // If this is not the end of the statement, report an error.
7044 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7045 reportParseError("unexpected token, expected end of statement");
7049 MCSection *ELFSection = getContext().getELFSection(
7050 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7051 getParser().getStreamer().SwitchSection(ELFSection);
7053 getParser().Lex(); // Eat EndOfStatement token.
7057 /// parseSSectionDirective
7060 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7061 // If this is not the end of the statement, report an error.
7062 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7063 reportParseError("unexpected token, expected end of statement");
7067 MCSection *ELFSection = getContext().getELFSection(
7068 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7069 getParser().getStreamer().SwitchSection(ELFSection);
7071 getParser().Lex(); // Eat EndOfStatement token.
7075 /// parseDirectiveModule
7076 /// ::= .module oddspreg
7077 /// ::= .module nooddspreg
7078 /// ::= .module fp=value
7079 /// ::= .module softfloat
7080 /// ::= .module hardfloat
7081 bool MipsAsmParser::parseDirectiveModule() {
7082 MCAsmParser &Parser = getParser();
7083 MCAsmLexer &Lexer = getLexer();
7084 SMLoc L = Lexer.getLoc();
7086 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7087 // TODO : get a better message.
7088 reportParseError(".module directive must appear before any code");
7093 if (Parser.parseIdentifier(Option)) {
7094 reportParseError("expected .module option identifier");
7098 if (Option == "oddspreg") {
7099 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7101 // Synchronize the abiflags information with the FeatureBits information we
7103 getTargetStreamer().updateABIInfo(*this);
7105 // If printing assembly, use the recently updated abiflags information.
7106 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7107 // emitted at the end).
7108 getTargetStreamer().emitDirectiveModuleOddSPReg();
7110 // If this is not the end of the statement, report an error.
7111 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7112 reportParseError("unexpected token, expected end of statement");
7116 return false; // parseDirectiveModule has finished successfully.
7117 } else if (Option == "nooddspreg") {
7119 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7122 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7124 // Synchronize the abiflags information with the FeatureBits information we
7126 getTargetStreamer().updateABIInfo(*this);
7128 // If printing assembly, use the recently updated abiflags information.
7129 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7130 // emitted at the end).
7131 getTargetStreamer().emitDirectiveModuleOddSPReg();
7133 // If this is not the end of the statement, report an error.
7134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7135 reportParseError("unexpected token, expected end of statement");
7139 return false; // parseDirectiveModule has finished successfully.
7140 } else if (Option == "fp") {
7141 return parseDirectiveModuleFP();
7142 } else if (Option == "softfloat") {
7143 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7145 // Synchronize the ABI Flags information with the FeatureBits information we
7147 getTargetStreamer().updateABIInfo(*this);
7149 // If printing assembly, use the recently updated ABI Flags information.
7150 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7152 getTargetStreamer().emitDirectiveModuleSoftFloat();
7154 // If this is not the end of the statement, report an error.
7155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7156 reportParseError("unexpected token, expected end of statement");
7160 return false; // parseDirectiveModule has finished successfully.
7161 } else if (Option == "hardfloat") {
7162 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7164 // Synchronize the ABI Flags information with the FeatureBits information we
7166 getTargetStreamer().updateABIInfo(*this);
7168 // If printing assembly, use the recently updated ABI Flags information.
7169 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7171 getTargetStreamer().emitDirectiveModuleHardFloat();
7173 // If this is not the end of the statement, report an error.
7174 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7175 reportParseError("unexpected token, expected end of statement");
7179 return false; // parseDirectiveModule has finished successfully.
7181 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7185 /// parseDirectiveModuleFP
7189 bool MipsAsmParser::parseDirectiveModuleFP() {
7190 MCAsmParser &Parser = getParser();
7191 MCAsmLexer &Lexer = getLexer();
7193 if (Lexer.isNot(AsmToken::Equal)) {
7194 reportParseError("unexpected token, expected equals sign '='");
7197 Parser.Lex(); // Eat '=' token.
7199 MipsABIFlagsSection::FpABIKind FpABI;
7200 if (!parseFpABIValue(FpABI, ".module"))
7203 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7204 reportParseError("unexpected token, expected end of statement");
7208 // Synchronize the abiflags information with the FeatureBits information we
7210 getTargetStreamer().updateABIInfo(*this);
7212 // If printing assembly, use the recently updated abiflags information.
7213 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7214 // emitted at the end).
7215 getTargetStreamer().emitDirectiveModuleFP();
7217 Parser.Lex(); // Consume the EndOfStatement.
7221 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7222 StringRef Directive) {
7223 MCAsmParser &Parser = getParser();
7224 MCAsmLexer &Lexer = getLexer();
7225 bool ModuleLevelOptions = Directive == ".module";
7227 if (Lexer.is(AsmToken::Identifier)) {
7228 StringRef Value = Parser.getTok().getString();
7231 if (Value != "xx") {
7232 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7237 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7241 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7242 if (ModuleLevelOptions) {
7243 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7244 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7246 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7247 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7252 if (Lexer.is(AsmToken::Integer)) {
7253 unsigned Value = Parser.getTok().getIntVal();
7256 if (Value != 32 && Value != 64) {
7257 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7263 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7267 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7268 if (ModuleLevelOptions) {
7269 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7270 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7272 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7273 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7276 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7277 if (ModuleLevelOptions) {
7278 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7279 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7281 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7282 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7292 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7293 // This returns false if this function recognizes the directive
7294 // regardless of whether it is successfully handles or reports an
7295 // error. Otherwise it returns true to give the generic parser a
7296 // chance at recognizing it.
7298 MCAsmParser &Parser = getParser();
7299 StringRef IDVal = DirectiveID.getString();
7301 if (IDVal == ".cpload") {
7302 parseDirectiveCpLoad(DirectiveID.getLoc());
7305 if (IDVal == ".cprestore") {
7306 parseDirectiveCpRestore(DirectiveID.getLoc());
7309 if (IDVal == ".dword") {
7310 parseDataDirective(8, DirectiveID.getLoc());
7313 if (IDVal == ".ent") {
7314 StringRef SymbolName;
7316 if (Parser.parseIdentifier(SymbolName)) {
7317 reportParseError("expected identifier after .ent");
7321 // There's an undocumented extension that allows an integer to
7322 // follow the name of the procedure which AFAICS is ignored by GAS.
7323 // Example: .ent foo,2
7324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7325 if (getLexer().isNot(AsmToken::Comma)) {
7326 // Even though we accept this undocumented extension for compatibility
7327 // reasons, the additional integer argument does not actually change
7328 // the behaviour of the '.ent' directive, so we would like to discourage
7329 // its use. We do this by not referring to the extended version in
7330 // error messages which are not directly related to its use.
7331 reportParseError("unexpected token, expected end of statement");
7334 Parser.Lex(); // Eat the comma.
7335 const MCExpr *DummyNumber;
7336 int64_t DummyNumberVal;
7337 // If the user was explicitly trying to use the extended version,
7338 // we still give helpful extension-related error messages.
7339 if (Parser.parseExpression(DummyNumber)) {
7340 reportParseError("expected number after comma");
7343 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7344 reportParseError("expected an absolute expression after comma");
7349 // If this is not the end of the statement, report an error.
7350 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7351 reportParseError("unexpected token, expected end of statement");
7355 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7357 getTargetStreamer().emitDirectiveEnt(*Sym);
7359 IsCpRestoreSet = false;
7363 if (IDVal == ".end") {
7364 StringRef SymbolName;
7366 if (Parser.parseIdentifier(SymbolName)) {
7367 reportParseError("expected identifier after .end");
7371 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7372 reportParseError("unexpected token, expected end of statement");
7376 if (CurrentFn == nullptr) {
7377 reportParseError(".end used without .ent");
7381 if ((SymbolName != CurrentFn->getName())) {
7382 reportParseError(".end symbol does not match .ent symbol");
7386 getTargetStreamer().emitDirectiveEnd(SymbolName);
7387 CurrentFn = nullptr;
7388 IsCpRestoreSet = false;
7392 if (IDVal == ".frame") {
7393 // .frame $stack_reg, frame_size_in_bytes, $return_reg
7394 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7395 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7396 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7397 reportParseError("expected stack register");
7401 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7402 if (!StackRegOpnd.isGPRAsmReg()) {
7403 reportParseError(StackRegOpnd.getStartLoc(),
7404 "expected general purpose register");
7407 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7409 if (Parser.getTok().is(AsmToken::Comma))
7412 reportParseError("unexpected token, expected comma");
7416 // Parse the frame size.
7417 const MCExpr *FrameSize;
7418 int64_t FrameSizeVal;
7420 if (Parser.parseExpression(FrameSize)) {
7421 reportParseError("expected frame size value");
7425 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
7426 reportParseError("frame size not an absolute expression");
7430 if (Parser.getTok().is(AsmToken::Comma))
7433 reportParseError("unexpected token, expected comma");
7437 // Parse the return register.
7439 ResTy = parseAnyRegister(TmpReg);
7440 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7441 reportParseError("expected return register");
7445 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7446 if (!ReturnRegOpnd.isGPRAsmReg()) {
7447 reportParseError(ReturnRegOpnd.getStartLoc(),
7448 "expected general purpose register");
7452 // If this is not the end of the statement, report an error.
7453 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7454 reportParseError("unexpected token, expected end of statement");
7458 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
7459 ReturnRegOpnd.getGPR32Reg());
7460 IsCpRestoreSet = false;
7464 if (IDVal == ".set") {
7465 parseDirectiveSet();
7469 if (IDVal == ".mask" || IDVal == ".fmask") {
7470 // .mask bitmask, frame_offset
7471 // bitmask: One bit for each register used.
7472 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
7473 // first register is expected to be saved.
7475 // .mask 0x80000000, -4
7476 // .fmask 0x80000000, -4
7479 // Parse the bitmask
7480 const MCExpr *BitMask;
7483 if (Parser.parseExpression(BitMask)) {
7484 reportParseError("expected bitmask value");
7488 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
7489 reportParseError("bitmask not an absolute expression");
7493 if (Parser.getTok().is(AsmToken::Comma))
7496 reportParseError("unexpected token, expected comma");
7500 // Parse the frame_offset
7501 const MCExpr *FrameOffset;
7502 int64_t FrameOffsetVal;
7504 if (Parser.parseExpression(FrameOffset)) {
7505 reportParseError("expected frame offset value");
7509 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
7510 reportParseError("frame offset not an absolute expression");
7514 // If this is not the end of the statement, report an error.
7515 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7516 reportParseError("unexpected token, expected end of statement");
7520 if (IDVal == ".mask")
7521 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
7523 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
7527 if (IDVal == ".nan")
7528 return parseDirectiveNaN();
7530 if (IDVal == ".gpword") {
7531 parseDirectiveGpWord();
7535 if (IDVal == ".gpdword") {
7536 parseDirectiveGpDWord();
7540 if (IDVal == ".dtprelword") {
7541 parseDirectiveDtpRelWord();
7545 if (IDVal == ".dtpreldword") {
7546 parseDirectiveDtpRelDWord();
7550 if (IDVal == ".tprelword") {
7551 parseDirectiveTpRelWord();
7555 if (IDVal == ".tpreldword") {
7556 parseDirectiveTpRelDWord();
7560 if (IDVal == ".word") {
7561 parseDataDirective(4, DirectiveID.getLoc());
7565 if (IDVal == ".hword") {
7566 parseDataDirective(2, DirectiveID.getLoc());
7570 if (IDVal == ".option") {
7571 parseDirectiveOption();
7575 if (IDVal == ".abicalls") {
7576 getTargetStreamer().emitDirectiveAbiCalls();
7577 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7578 Error(Parser.getTok().getLoc(),
7579 "unexpected token, expected end of statement");
7584 if (IDVal == ".cpsetup") {
7585 parseDirectiveCPSetup();
7588 if (IDVal == ".cpreturn") {
7589 parseDirectiveCPReturn();
7592 if (IDVal == ".module") {
7593 parseDirectiveModule();
7596 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
7597 parseInternalDirectiveReallowModule();
7600 if (IDVal == ".insn") {
7601 parseInsnDirective();
7604 if (IDVal == ".rdata") {
7605 parseRSectionDirective(".rodata");
7608 if (IDVal == ".sbss") {
7609 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
7612 if (IDVal == ".sdata") {
7613 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
7620 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
7621 // If this is not the end of the statement, report an error.
7622 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7623 reportParseError("unexpected token, expected end of statement");
7627 getTargetStreamer().reallowModuleDirective();
7629 getParser().Lex(); // Eat EndOfStatement token.
7633 extern "C" void LLVMInitializeMipsAsmParser() {
7634 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
7635 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
7636 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
7637 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
7640 #define GET_REGISTER_MATCHER
7641 #define GET_MATCHER_IMPLEMENTATION
7642 #include "MipsGenAsmMatcher.inc"
7644 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
7645 // Find the appropriate table for this asm variant.
7646 const MatchEntry *Start, *End;
7647 switch (VariantID) {
7648 default: llvm_unreachable("invalid variant!");
7649 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
7651 // Search the table.
7652 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
7653 return MnemonicRange.first != MnemonicRange.second;