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/MipsMCExpr.h"
13 #include "MCTargetDesc/MipsMCTargetDesc.h"
14 #include "MipsTargetStreamer.h"
15 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCExpr.h"
25 #include "llvm/MC/MCInst.h"
26 #include "llvm/MC/MCInstrDesc.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCParser/MCAsmLexer.h"
29 #include "llvm/MC/MCParser/MCAsmParser.h"
30 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
31 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
32 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
33 #include "llvm/MC/MCSectionELF.h"
34 #include "llvm/MC/MCStreamer.h"
35 #include "llvm/MC/MCSubtargetInfo.h"
36 #include "llvm/MC/MCSymbol.h"
37 #include "llvm/MC/MCSymbolELF.h"
38 #include "llvm/MC/MCValue.h"
39 #include "llvm/MC/SubtargetFeature.h"
40 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/Compiler.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/ELF.h"
44 #include "llvm/Support/ErrorHandling.h"
45 #include "llvm/Support/MathExtras.h"
46 #include "llvm/Support/raw_ostream.h"
47 #include "llvm/Support/SMLoc.h"
48 #include "llvm/Support/SourceMgr.h"
49 #include "llvm/Support/TargetRegistry.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 parseSSectionDirective(StringRef Section, unsigned Type);
327 bool parseSetAtDirective();
328 bool parseSetNoAtDirective();
329 bool parseSetMacroDirective();
330 bool parseSetNoMacroDirective();
331 bool parseSetMsaDirective();
332 bool parseSetNoMsaDirective();
333 bool parseSetNoDspDirective();
334 bool parseSetReorderDirective();
335 bool parseSetNoReorderDirective();
336 bool parseSetMips16Directive();
337 bool parseSetNoMips16Directive();
338 bool parseSetFpDirective();
339 bool parseSetOddSPRegDirective();
340 bool parseSetNoOddSPRegDirective();
341 bool parseSetPopDirective();
342 bool parseSetPushDirective();
343 bool parseSetSoftFloatDirective();
344 bool parseSetHardFloatDirective();
346 bool parseSetAssignment();
348 bool parseDataDirective(unsigned Size, SMLoc L);
349 bool parseDirectiveGpWord();
350 bool parseDirectiveGpDWord();
351 bool parseDirectiveDtpRelWord();
352 bool parseDirectiveDtpRelDWord();
353 bool parseDirectiveTpRelWord();
354 bool parseDirectiveTpRelDWord();
355 bool parseDirectiveModule();
356 bool parseDirectiveModuleFP();
357 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
358 StringRef Directive);
360 bool parseInternalDirectiveReallowModule();
362 bool eatComma(StringRef ErrorStr);
364 int matchCPURegisterName(StringRef Symbol);
366 int matchHWRegsRegisterName(StringRef Symbol);
368 int matchFPURegisterName(StringRef Name);
370 int matchFCCRegisterName(StringRef Name);
372 int matchACRegisterName(StringRef Name);
374 int matchMSA128RegisterName(StringRef Name);
376 int matchMSA128CtrlRegisterName(StringRef Name);
378 unsigned getReg(int RC, int RegNo);
380 /// Returns the internal register number for the current AT. Also checks if
381 /// the current AT is unavailable (set to $0) and gives an error if it is.
382 /// This should be used in pseudo-instruction expansions which need AT.
383 unsigned getATReg(SMLoc Loc);
387 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
388 const MCSubtargetInfo *STI);
390 // Helper function that checks if the value of a vector index is within the
391 // boundaries of accepted values for each RegisterKind
392 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
393 bool validateMSAIndex(int Val, int RegKind);
395 // Selects a new architecture by updating the FeatureBits with the necessary
396 // info including implied dependencies.
397 // Internally, it clears all the feature bits related to *any* architecture
398 // and selects the new one using the ToggleFeature functionality of the
399 // MCSubtargetInfo object that handles implied dependencies. The reason we
400 // clear all the arch related bits manually is because ToggleFeature only
401 // clears the features that imply the feature being cleared and not the
402 // features implied by the feature being cleared. This is easier to see
404 // --------------------------------------------------
405 // | Feature | Implies |
406 // | -------------------------------------------------|
407 // | FeatureMips1 | None |
408 // | FeatureMips2 | FeatureMips1 |
409 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
410 // | FeatureMips4 | FeatureMips3 |
412 // --------------------------------------------------
414 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
415 // FeatureMipsGP64 | FeatureMips1)
416 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
417 void selectArch(StringRef ArchFeature) {
418 MCSubtargetInfo &STI = copySTI();
419 FeatureBitset FeatureBits = STI.getFeatureBits();
420 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
421 STI.setFeatureBits(FeatureBits);
422 setAvailableFeatures(
423 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
424 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
427 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
428 if (!(getSTI().getFeatureBits()[Feature])) {
429 MCSubtargetInfo &STI = copySTI();
430 setAvailableFeatures(
431 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
432 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
436 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
437 if (getSTI().getFeatureBits()[Feature]) {
438 MCSubtargetInfo &STI = copySTI();
439 setAvailableFeatures(
440 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
441 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
445 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
446 setFeatureBits(Feature, FeatureString);
447 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
450 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
451 clearFeatureBits(Feature, FeatureString);
452 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
456 enum MipsMatchResultTy {
457 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
458 Match_RequiresDifferentOperands,
459 Match_RequiresNoZeroRegister,
460 Match_RequiresSameSrcAndDst,
461 Match_NoFCCRegisterForCurrentISA,
462 Match_NonZeroOperandForSync,
463 #define GET_OPERAND_DIAGNOSTIC_TYPES
464 #include "MipsGenAsmMatcher.inc"
465 #undef GET_OPERAND_DIAGNOSTIC_TYPES
468 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
469 const MCInstrInfo &MII, const MCTargetOptions &Options)
470 : MCTargetAsmParser(Options, sti),
471 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
472 sti.getCPU(), Options)) {
473 MCAsmParserExtension::Initialize(parser);
475 parser.addAliasForDirective(".asciiz", ".asciz");
477 // Initialize the set of available features.
478 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
480 // Remember the initial assembler options. The user can not modify these.
481 AssemblerOptions.push_back(
482 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
484 // Create an assembler options environment for the user to modify.
485 AssemblerOptions.push_back(
486 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
488 getTargetStreamer().updateABIInfo(*this);
490 if (!isABI_O32() && !useOddSPReg() != 0)
491 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
495 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
497 IsCpRestoreSet = false;
498 CpRestoreOffset = -1;
500 const Triple &TheTriple = sti.getTargetTriple();
501 if ((TheTriple.getArch() == Triple::mips) ||
502 (TheTriple.getArch() == Triple::mips64))
503 IsLittleEndian = false;
505 IsLittleEndian = true;
508 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
509 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
511 bool isGP64bit() const {
512 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
515 bool isFP64bit() const {
516 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
519 const MipsABIInfo &getABI() const { return ABI; }
520 bool isABI_N32() const { return ABI.IsN32(); }
521 bool isABI_N64() const { return ABI.IsN64(); }
522 bool isABI_O32() const { return ABI.IsO32(); }
523 bool isABI_FPXX() const {
524 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
527 bool useOddSPReg() const {
528 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
531 bool inMicroMipsMode() const {
532 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
535 bool hasMips1() const {
536 return getSTI().getFeatureBits()[Mips::FeatureMips1];
539 bool hasMips2() const {
540 return getSTI().getFeatureBits()[Mips::FeatureMips2];
543 bool hasMips3() const {
544 return getSTI().getFeatureBits()[Mips::FeatureMips3];
547 bool hasMips4() const {
548 return getSTI().getFeatureBits()[Mips::FeatureMips4];
551 bool hasMips5() const {
552 return getSTI().getFeatureBits()[Mips::FeatureMips5];
555 bool hasMips32() const {
556 return getSTI().getFeatureBits()[Mips::FeatureMips32];
559 bool hasMips64() const {
560 return getSTI().getFeatureBits()[Mips::FeatureMips64];
563 bool hasMips32r2() const {
564 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
567 bool hasMips64r2() const {
568 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
571 bool hasMips32r3() const {
572 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
575 bool hasMips64r3() const {
576 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
579 bool hasMips32r5() const {
580 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
583 bool hasMips64r5() const {
584 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
587 bool hasMips32r6() const {
588 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
591 bool hasMips64r6() const {
592 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
595 bool hasDSP() const {
596 return getSTI().getFeatureBits()[Mips::FeatureDSP];
599 bool hasDSPR2() const {
600 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
603 bool hasDSPR3() const {
604 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
607 bool hasMSA() const {
608 return getSTI().getFeatureBits()[Mips::FeatureMSA];
611 bool hasCnMips() const {
612 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
619 bool inMips16Mode() const {
620 return getSTI().getFeatureBits()[Mips::FeatureMips16];
623 bool useTraps() const {
624 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
627 bool useSoftFloat() const {
628 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
631 /// Warn if RegIndex is the same as the current AT.
632 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
634 void warnIfNoMacro(SMLoc Loc);
636 bool isLittle() const { return IsLittleEndian; }
638 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
639 AsmToken::TokenKind OperatorToken,
640 MCContext &Ctx) override {
641 switch(OperatorToken) {
643 llvm_unreachable("Unknown token");
645 case AsmToken::PercentCall16:
646 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
647 case AsmToken::PercentCall_Hi:
648 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
649 case AsmToken::PercentCall_Lo:
650 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
651 case AsmToken::PercentDtprel_Hi:
652 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
653 case AsmToken::PercentDtprel_Lo:
654 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
655 case AsmToken::PercentGot:
656 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
657 case AsmToken::PercentGot_Disp:
658 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
659 case AsmToken::PercentGot_Hi:
660 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
661 case AsmToken::PercentGot_Lo:
662 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
663 case AsmToken::PercentGot_Ofst:
664 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
665 case AsmToken::PercentGot_Page:
666 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
667 case AsmToken::PercentGottprel:
668 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
669 case AsmToken::PercentGp_Rel:
670 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
671 case AsmToken::PercentHi:
672 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
673 case AsmToken::PercentHigher:
674 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
675 case AsmToken::PercentHighest:
676 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
677 case AsmToken::PercentLo:
678 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
679 case AsmToken::PercentNeg:
680 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
681 case AsmToken::PercentPcrel_Hi:
682 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
683 case AsmToken::PercentPcrel_Lo:
684 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
685 case AsmToken::PercentTlsgd:
686 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
687 case AsmToken::PercentTlsldm:
688 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
689 case AsmToken::PercentTprel_Hi:
690 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
691 case AsmToken::PercentTprel_Lo:
692 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
697 /// MipsOperand - Instances of this class represent a parsed Mips machine
699 class MipsOperand : public MCParsedAsmOperand {
701 /// Broad categories of register classes
702 /// The exact class is finalized by the render method.
704 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
705 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
707 RegKind_FCC = 4, /// FCC
708 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
709 RegKind_MSACtrl = 16, /// MSA control registers
710 RegKind_COP2 = 32, /// COP2
711 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
713 RegKind_CCR = 128, /// CCR
714 RegKind_HWRegs = 256, /// HWRegs
715 RegKind_COP3 = 512, /// COP3
716 RegKind_COP0 = 1024, /// COP0
717 /// Potentially any (e.g. $1)
718 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
719 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
720 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
725 k_Immediate, /// An immediate (possibly involving symbol references)
726 k_Memory, /// Base + Offset Memory Address
727 k_RegisterIndex, /// A register index in one or more RegKind.
728 k_Token, /// A simple token
729 k_RegList, /// A physical register list
730 k_RegPair /// A pair of physical register
734 MipsOperand(KindTy K, MipsAsmParser &Parser)
735 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
737 ~MipsOperand() override {
746 case k_RegisterIndex:
754 /// For diagnostics, and checking the assembler temporary
755 MipsAsmParser &AsmParser;
763 unsigned Index; /// Index into the register class
764 RegKind Kind; /// Bitfield of the kinds it could possibly be
765 struct Token Tok; /// The input token this operand originated from.
766 const MCRegisterInfo *RegInfo;
779 SmallVector<unsigned, 10> *List;
784 struct RegIdxOp RegIdx;
787 struct RegListOp RegList;
790 SMLoc StartLoc, EndLoc;
792 /// Internal constructor for register kinds
793 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
795 const MCRegisterInfo *RegInfo,
797 MipsAsmParser &Parser) {
798 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
799 Op->RegIdx.Index = Index;
800 Op->RegIdx.RegInfo = RegInfo;
801 Op->RegIdx.Kind = RegKind;
802 Op->RegIdx.Tok.Data = Str.data();
803 Op->RegIdx.Tok.Length = Str.size();
810 /// Coerce the register to GPR32 and return the real register for the current
812 unsigned getGPR32Reg() const {
813 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
814 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
815 unsigned ClassID = Mips::GPR32RegClassID;
816 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
819 /// Coerce the register to GPR32 and return the real register for the current
821 unsigned getGPRMM16Reg() const {
822 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
823 unsigned ClassID = Mips::GPR32RegClassID;
824 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
827 /// Coerce the register to GPR64 and return the real register for the current
829 unsigned getGPR64Reg() const {
830 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
831 unsigned ClassID = Mips::GPR64RegClassID;
832 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
836 /// Coerce the register to AFGR64 and return the real register for the current
838 unsigned getAFGR64Reg() const {
839 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
840 if (RegIdx.Index % 2 != 0)
841 AsmParser.Warning(StartLoc, "Float register should be even.");
842 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
843 .getRegister(RegIdx.Index / 2);
846 /// Coerce the register to FGR64 and return the real register for the current
848 unsigned getFGR64Reg() const {
849 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
850 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
851 .getRegister(RegIdx.Index);
854 /// Coerce the register to FGR32 and return the real register for the current
856 unsigned getFGR32Reg() const {
857 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
858 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
859 .getRegister(RegIdx.Index);
862 /// Coerce the register to FGRH32 and return the real register for the current
864 unsigned getFGRH32Reg() const {
865 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
866 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
867 .getRegister(RegIdx.Index);
870 /// Coerce the register to FCC and return the real register for the current
872 unsigned getFCCReg() const {
873 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
874 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
875 .getRegister(RegIdx.Index);
878 /// Coerce the register to MSA128 and return the real register for the current
880 unsigned getMSA128Reg() const {
881 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
882 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
884 unsigned ClassID = Mips::MSA128BRegClassID;
885 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
888 /// Coerce the register to MSACtrl and return the real register for the
890 unsigned getMSACtrlReg() const {
891 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
892 unsigned ClassID = Mips::MSACtrlRegClassID;
893 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
896 /// Coerce the register to COP0 and return the real register for the
898 unsigned getCOP0Reg() const {
899 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
900 unsigned ClassID = Mips::COP0RegClassID;
901 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
904 /// Coerce the register to COP2 and return the real register for the
906 unsigned getCOP2Reg() const {
907 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
908 unsigned ClassID = Mips::COP2RegClassID;
909 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
912 /// Coerce the register to COP3 and return the real register for the
914 unsigned getCOP3Reg() const {
915 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
916 unsigned ClassID = Mips::COP3RegClassID;
917 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
920 /// Coerce the register to ACC64DSP and return the real register for the
922 unsigned getACC64DSPReg() const {
923 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
924 unsigned ClassID = Mips::ACC64DSPRegClassID;
925 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
928 /// Coerce the register to HI32DSP and return the real register for the
930 unsigned getHI32DSPReg() const {
931 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
932 unsigned ClassID = Mips::HI32DSPRegClassID;
933 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
936 /// Coerce the register to LO32DSP and return the real register for the
938 unsigned getLO32DSPReg() const {
939 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
940 unsigned ClassID = Mips::LO32DSPRegClassID;
941 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
944 /// Coerce the register to CCR and return the real register for the
946 unsigned getCCRReg() const {
947 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
948 unsigned ClassID = Mips::CCRRegClassID;
949 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
952 /// Coerce the register to HWRegs and return the real register for the
954 unsigned getHWRegsReg() const {
955 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
956 unsigned ClassID = Mips::HWRegsRegClassID;
957 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
961 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
962 // Add as immediate when possible. Null MCExpr = 0.
964 Inst.addOperand(MCOperand::createImm(0));
965 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
966 Inst.addOperand(MCOperand::createImm(CE->getValue()));
968 Inst.addOperand(MCOperand::createExpr(Expr));
971 void addRegOperands(MCInst &Inst, unsigned N) const {
972 llvm_unreachable("Use a custom parser instead");
975 /// Render the operand to an MCInst as a GPR32
976 /// Asserts if the wrong number of operands are requested, or the operand
977 /// is not a k_RegisterIndex compatible with RegKind_GPR
978 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
979 assert(N == 1 && "Invalid number of operands!");
980 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
983 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
984 assert(N == 1 && "Invalid number of operands!");
985 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
988 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
989 assert(N == 1 && "Invalid number of operands!");
990 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
993 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
994 assert(N == 1 && "Invalid number of operands!");
995 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
998 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
999 assert(N == 1 && "Invalid number of operands!");
1000 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1003 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1004 assert(N == 1 && "Invalid number of operands!");
1005 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1008 /// Render the operand to an MCInst as a GPR64
1009 /// Asserts if the wrong number of operands are requested, or the operand
1010 /// is not a k_RegisterIndex compatible with RegKind_GPR
1011 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1012 assert(N == 1 && "Invalid number of operands!");
1013 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1016 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1017 assert(N == 1 && "Invalid number of operands!");
1018 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1021 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1022 assert(N == 1 && "Invalid number of operands!");
1023 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1026 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1027 assert(N == 1 && "Invalid number of operands!");
1028 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1031 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1032 assert(N == 1 && "Invalid number of operands!");
1033 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1036 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1037 assert(N == 1 && "Invalid number of operands!");
1038 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1039 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1040 // FIXME: This should propagate failure up to parseStatement.
1041 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1042 AsmParser.getParser().printError(
1043 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1047 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1048 assert(N == 1 && "Invalid number of operands!");
1049 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1050 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1051 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1052 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1056 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1057 assert(N == 1 && "Invalid number of operands!");
1058 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1061 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1062 assert(N == 1 && "Invalid number of operands!");
1063 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1066 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1067 assert(N == 1 && "Invalid number of operands!");
1068 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1071 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1072 assert(N == 1 && "Invalid number of operands!");
1073 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1076 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1077 assert(N == 1 && "Invalid number of operands!");
1078 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1081 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1082 assert(N == 1 && "Invalid number of operands!");
1083 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1086 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1087 assert(N == 1 && "Invalid number of operands!");
1088 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1091 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1096 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1097 assert(N == 1 && "Invalid number of operands!");
1098 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1101 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1102 assert(N == 1 && "Invalid number of operands!");
1103 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1106 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1107 assert(N == 1 && "Invalid number of operands!");
1108 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1111 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1112 assert(N == 1 && "Invalid number of operands!");
1113 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1116 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1117 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1118 assert(N == 1 && "Invalid number of operands!");
1119 uint64_t Imm = getConstantImm() - Offset;
1120 Imm &= (1ULL << Bits) - 1;
1122 Imm += AdjustOffset;
1123 Inst.addOperand(MCOperand::createImm(Imm));
1126 template <unsigned Bits>
1127 void addSImmOperands(MCInst &Inst, unsigned N) const {
1128 if (isImm() && !isConstantImm()) {
1129 addExpr(Inst, getImm());
1132 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1135 template <unsigned Bits>
1136 void addUImmOperands(MCInst &Inst, unsigned N) const {
1137 if (isImm() && !isConstantImm()) {
1138 addExpr(Inst, getImm());
1141 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1144 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1145 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1146 assert(N == 1 && "Invalid number of operands!");
1147 int64_t Imm = getConstantImm() - Offset;
1148 Imm = SignExtend64<Bits>(Imm);
1150 Imm += AdjustOffset;
1151 Inst.addOperand(MCOperand::createImm(Imm));
1154 void addImmOperands(MCInst &Inst, unsigned N) const {
1155 assert(N == 1 && "Invalid number of operands!");
1156 const MCExpr *Expr = getImm();
1157 addExpr(Inst, Expr);
1160 void addMemOperands(MCInst &Inst, unsigned N) const {
1161 assert(N == 2 && "Invalid number of operands!");
1163 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1164 ? getMemBase()->getGPR64Reg()
1165 : getMemBase()->getGPR32Reg()));
1167 const MCExpr *Expr = getMemOff();
1168 addExpr(Inst, Expr);
1171 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1172 assert(N == 2 && "Invalid number of operands!");
1174 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1176 const MCExpr *Expr = getMemOff();
1177 addExpr(Inst, Expr);
1180 void addRegListOperands(MCInst &Inst, unsigned N) const {
1181 assert(N == 1 && "Invalid number of operands!");
1183 for (auto RegNo : getRegList())
1184 Inst.addOperand(MCOperand::createReg(RegNo));
1187 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1188 assert(N == 2 && "Invalid number of operands!");
1189 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1190 unsigned RegNo = getRegPair();
1191 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1192 Inst.addOperand(MCOperand::createReg(
1193 RegIdx.RegInfo->getRegClass(
1194 AsmParser.getABI().AreGprs64bit()
1195 ? Mips::GPR64RegClassID
1196 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1197 Inst.addOperand(MCOperand::createReg(
1198 RegIdx.RegInfo->getRegClass(
1199 AsmParser.getABI().AreGprs64bit()
1200 ? Mips::GPR64RegClassID
1201 : Mips::GPR32RegClassID).getRegister(RegNo)));
1204 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1205 assert(N == 2 && "Invalid number of operands!");
1206 for (auto RegNo : getRegList())
1207 Inst.addOperand(MCOperand::createReg(RegNo));
1210 bool isReg() const override {
1211 // As a special case until we sort out the definition of div/divu, accept
1212 // $0/$zero here so that MCK_ZERO works correctly.
1213 return isGPRAsmReg() && RegIdx.Index == 0;
1216 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1217 bool isImm() const override { return Kind == k_Immediate; }
1219 bool isConstantImm() const {
1221 return isImm() && getImm()->evaluateAsAbsolute(Res);
1224 bool isConstantImmz() const {
1225 return isConstantImm() && getConstantImm() == 0;
1228 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1229 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1232 template <unsigned Bits> bool isSImm() const {
1233 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1236 template <unsigned Bits> bool isUImm() const {
1237 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1240 template <unsigned Bits> bool isAnyImm() const {
1241 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1242 isUInt<Bits>(getConstantImm()))
1246 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1247 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1250 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1251 return isConstantImm() && getConstantImm() >= Bottom &&
1252 getConstantImm() <= Top;
1255 bool isToken() const override {
1256 // Note: It's not possible to pretend that other operand kinds are tokens.
1257 // The matcher emitter checks tokens first.
1258 return Kind == k_Token;
1261 bool isMem() const override { return Kind == k_Memory; }
1263 bool isConstantMemOff() const {
1264 return isMem() && isa<MCConstantExpr>(getMemOff());
1267 // Allow relocation operators.
1268 // FIXME: This predicate and others need to look through binary expressions
1269 // and determine whether a Value is a constant or not.
1270 template <unsigned Bits, unsigned ShiftAmount = 0>
1271 bool isMemWithSimmOffset() const {
1274 if (!getMemBase()->isGPRAsmReg())
1276 if (isa<MCTargetExpr>(getMemOff()) ||
1277 (isConstantMemOff() &&
1278 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1281 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1282 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1285 bool isMemWithGRPMM16Base() const {
1286 return isMem() && getMemBase()->isMM16AsmReg();
1289 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1290 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1291 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1294 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1295 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1296 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1297 && (getMemBase()->getGPR32Reg() == Mips::SP);
1300 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1301 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1302 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1303 && (getMemBase()->getGPR32Reg() == Mips::GP);
1306 template <unsigned Bits, unsigned ShiftLeftAmount>
1307 bool isScaledUImm() const {
1308 return isConstantImm() &&
1309 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1312 template <unsigned Bits, unsigned ShiftLeftAmount>
1313 bool isScaledSImm() const {
1314 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1316 // Operand can also be a symbol or symbol plus offset in case of relocations.
1317 if (Kind != k_Immediate)
1320 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1321 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1324 bool isRegList16() const {
1328 int Size = RegList.List->size();
1329 if (Size < 2 || Size > 5)
1332 unsigned R0 = RegList.List->front();
1333 unsigned R1 = RegList.List->back();
1334 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1335 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1338 int PrevReg = *RegList.List->begin();
1339 for (int i = 1; i < Size - 1; i++) {
1340 int Reg = (*(RegList.List))[i];
1341 if ( Reg != PrevReg + 1)
1349 bool isInvNum() const { return Kind == k_Immediate; }
1351 bool isLSAImm() const {
1352 if (!isConstantImm())
1354 int64_t Val = getConstantImm();
1355 return 1 <= Val && Val <= 4;
1358 bool isRegList() const { return Kind == k_RegList; }
1360 bool isMovePRegPair() const {
1361 if (Kind != k_RegList || RegList.List->size() != 2)
1364 unsigned R0 = RegList.List->front();
1365 unsigned R1 = RegList.List->back();
1367 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1368 (R0 == Mips::A1 && R1 == Mips::A3) ||
1369 (R0 == Mips::A2 && R1 == Mips::A3) ||
1370 (R0 == Mips::A0 && R1 == Mips::S5) ||
1371 (R0 == Mips::A0 && R1 == Mips::S6) ||
1372 (R0 == Mips::A0 && R1 == Mips::A1) ||
1373 (R0 == Mips::A0 && R1 == Mips::A2) ||
1374 (R0 == Mips::A0 && R1 == Mips::A3) ||
1375 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1376 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1377 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1378 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1379 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1380 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1381 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1382 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1388 StringRef getToken() const {
1389 assert(Kind == k_Token && "Invalid access!");
1390 return StringRef(Tok.Data, Tok.Length);
1393 bool isRegPair() const {
1394 return Kind == k_RegPair && RegIdx.Index <= 30;
1397 unsigned getReg() const override {
1398 // As a special case until we sort out the definition of div/divu, accept
1399 // $0/$zero here so that MCK_ZERO works correctly.
1400 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1401 RegIdx.Kind & RegKind_GPR)
1402 return getGPR32Reg(); // FIXME: GPR64 too
1404 llvm_unreachable("Invalid access!");
1408 const MCExpr *getImm() const {
1409 assert((Kind == k_Immediate) && "Invalid access!");
1413 int64_t getConstantImm() const {
1414 const MCExpr *Val = getImm();
1416 (void)Val->evaluateAsAbsolute(Value);
1420 MipsOperand *getMemBase() const {
1421 assert((Kind == k_Memory) && "Invalid access!");
1425 const MCExpr *getMemOff() const {
1426 assert((Kind == k_Memory) && "Invalid access!");
1430 int64_t getConstantMemOff() const {
1431 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1434 const SmallVectorImpl<unsigned> &getRegList() const {
1435 assert((Kind == k_RegList) && "Invalid access!");
1436 return *(RegList.List);
1439 unsigned getRegPair() const {
1440 assert((Kind == k_RegPair) && "Invalid access!");
1441 return RegIdx.Index;
1444 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1445 MipsAsmParser &Parser) {
1446 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1447 Op->Tok.Data = Str.data();
1448 Op->Tok.Length = Str.size();
1454 /// Create a numeric register (e.g. $1). The exact register remains
1455 /// unresolved until an instruction successfully matches
1456 static std::unique_ptr<MipsOperand>
1457 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1458 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1459 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1460 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1463 /// Create a register that is definitely a GPR.
1464 /// This is typically only used for named registers such as $gp.
1465 static std::unique_ptr<MipsOperand>
1466 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1467 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1468 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1471 /// Create a register that is definitely a FGR.
1472 /// This is typically only used for named registers such as $f0.
1473 static std::unique_ptr<MipsOperand>
1474 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1475 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1476 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1479 /// Create a register that is definitely a HWReg.
1480 /// This is typically only used for named registers such as $hwr_cpunum.
1481 static std::unique_ptr<MipsOperand>
1482 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1483 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1484 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1487 /// Create a register that is definitely an FCC.
1488 /// This is typically only used for named registers such as $fcc0.
1489 static std::unique_ptr<MipsOperand>
1490 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1491 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1492 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1495 /// Create a register that is definitely an ACC.
1496 /// This is typically only used for named registers such as $ac0.
1497 static std::unique_ptr<MipsOperand>
1498 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1499 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1500 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1503 /// Create a register that is definitely an MSA128.
1504 /// This is typically only used for named registers such as $w0.
1505 static std::unique_ptr<MipsOperand>
1506 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1507 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1508 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1511 /// Create a register that is definitely an MSACtrl.
1512 /// This is typically only used for named registers such as $msaaccess.
1513 static std::unique_ptr<MipsOperand>
1514 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1515 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1516 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1519 static std::unique_ptr<MipsOperand>
1520 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1521 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1528 static std::unique_ptr<MipsOperand>
1529 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1530 SMLoc E, MipsAsmParser &Parser) {
1531 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1532 Op->Mem.Base = Base.release();
1539 static std::unique_ptr<MipsOperand>
1540 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1541 MipsAsmParser &Parser) {
1542 assert(Regs.size() > 0 && "Empty list not allowed");
1544 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1545 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1546 Op->StartLoc = StartLoc;
1547 Op->EndLoc = EndLoc;
1551 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1553 MipsAsmParser &Parser) {
1554 auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
1555 Op->RegIdx.Index = MOP.RegIdx.Index;
1556 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1557 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1563 bool isGPRZeroAsmReg() const {
1564 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1567 bool isGPRNonZeroAsmReg() const {
1568 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1572 bool isGPRAsmReg() const {
1573 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1576 bool isMM16AsmReg() const {
1577 if (!(isRegIdx() && RegIdx.Kind))
1579 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1580 || RegIdx.Index == 16 || RegIdx.Index == 17);
1583 bool isMM16AsmRegZero() const {
1584 if (!(isRegIdx() && RegIdx.Kind))
1586 return (RegIdx.Index == 0 ||
1587 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1588 RegIdx.Index == 17);
1591 bool isMM16AsmRegMoveP() const {
1592 if (!(isRegIdx() && RegIdx.Kind))
1594 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1595 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1598 bool isFGRAsmReg() const {
1599 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1600 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1603 bool isStrictlyFGRAsmReg() const {
1604 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1605 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1608 bool isHWRegsAsmReg() const {
1609 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1612 bool isCCRAsmReg() const {
1613 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1616 bool isFCCAsmReg() const {
1617 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1619 return RegIdx.Index <= 7;
1622 bool isACCAsmReg() const {
1623 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1626 bool isCOP0AsmReg() const {
1627 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1630 bool isCOP2AsmReg() const {
1631 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1634 bool isCOP3AsmReg() const {
1635 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1638 bool isMSA128AsmReg() const {
1639 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1642 bool isMSACtrlAsmReg() const {
1643 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1646 /// getStartLoc - Get the location of the first token of this operand.
1647 SMLoc getStartLoc() const override { return StartLoc; }
1648 /// getEndLoc - Get the location of the last token of this operand.
1649 SMLoc getEndLoc() const override { return EndLoc; }
1651 void print(raw_ostream &OS) const override {
1660 Mem.Base->print(OS);
1665 case k_RegisterIndex:
1666 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1667 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1674 for (auto Reg : (*RegList.List))
1679 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1684 bool isValidForTie(const MipsOperand &Other) const {
1685 if (Kind != Other.Kind)
1690 llvm_unreachable("Unexpected kind");
1692 case k_RegisterIndex: {
1693 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1694 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1695 return Token == OtherToken;
1699 }; // class MipsOperand
1701 } // end anonymous namespace
1705 extern const MCInstrDesc MipsInsts[];
1707 } // end namespace llvm
1709 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1710 return MipsInsts[Opcode];
1713 static bool hasShortDelaySlot(unsigned Opcode) {
1716 case Mips::JALRS_MM:
1717 case Mips::JALRS16_MM:
1718 case Mips::BGEZALS_MM:
1719 case Mips::BLTZALS_MM:
1726 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1727 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1728 return &SRExpr->getSymbol();
1731 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1732 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1733 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1744 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1745 return getSingleMCSymbol(UExpr->getSubExpr());
1750 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1751 if (isa<MCSymbolRefExpr>(Expr))
1754 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1755 return countMCSymbolRefExpr(BExpr->getLHS()) +
1756 countMCSymbolRefExpr(BExpr->getRHS());
1758 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1759 return countMCSymbolRefExpr(UExpr->getSubExpr());
1764 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1766 const MCSubtargetInfo *STI) {
1767 MipsTargetStreamer &TOut = getTargetStreamer();
1768 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1769 bool ExpandedJalSym = false;
1773 if (MCID.isBranch() || MCID.isCall()) {
1774 const unsigned Opcode = Inst.getOpcode();
1784 assert(hasCnMips() && "instruction only valid for octeon cpus");
1791 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1792 Offset = Inst.getOperand(2);
1793 if (!Offset.isImm())
1794 break; // We'll deal with this situation later on when applying fixups.
1795 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1796 return Error(IDLoc, "branch target out of range");
1797 if (OffsetToAlignment(Offset.getImm(),
1798 1LL << (inMicroMipsMode() ? 1 : 2)))
1799 return Error(IDLoc, "branch to misaligned address");
1813 case Mips::BGEZAL_MM:
1814 case Mips::BLTZAL_MM:
1817 case Mips::BC1EQZC_MMR6:
1818 case Mips::BC1NEZC_MMR6:
1819 case Mips::BC2EQZC_MMR6:
1820 case Mips::BC2NEZC_MMR6:
1821 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1822 Offset = Inst.getOperand(1);
1823 if (!Offset.isImm())
1824 break; // We'll deal with this situation later on when applying fixups.
1825 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1826 return Error(IDLoc, "branch target out of range");
1827 if (OffsetToAlignment(Offset.getImm(),
1828 1LL << (inMicroMipsMode() ? 1 : 2)))
1829 return Error(IDLoc, "branch to misaligned address");
1831 case Mips::BGEC: case Mips::BGEC_MMR6:
1832 case Mips::BLTC: case Mips::BLTC_MMR6:
1833 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1834 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1835 case Mips::BEQC: case Mips::BEQC_MMR6:
1836 case Mips::BNEC: case Mips::BNEC_MMR6:
1837 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1838 Offset = Inst.getOperand(2);
1839 if (!Offset.isImm())
1840 break; // We'll deal with this situation later on when applying fixups.
1841 if (!isIntN(18, Offset.getImm()))
1842 return Error(IDLoc, "branch target out of range");
1843 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1844 return Error(IDLoc, "branch to misaligned address");
1846 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1847 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1848 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1849 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1850 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1851 Offset = Inst.getOperand(1);
1852 if (!Offset.isImm())
1853 break; // We'll deal with this situation later on when applying fixups.
1854 if (!isIntN(18, Offset.getImm()))
1855 return Error(IDLoc, "branch target out of range");
1856 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1857 return Error(IDLoc, "branch to misaligned address");
1859 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1860 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1861 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1862 Offset = Inst.getOperand(1);
1863 if (!Offset.isImm())
1864 break; // We'll deal with this situation later on when applying fixups.
1865 if (!isIntN(23, Offset.getImm()))
1866 return Error(IDLoc, "branch target out of range");
1867 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1868 return Error(IDLoc, "branch to misaligned address");
1870 case Mips::BEQZ16_MM:
1871 case Mips::BEQZC16_MMR6:
1872 case Mips::BNEZ16_MM:
1873 case Mips::BNEZC16_MMR6:
1874 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1875 Offset = Inst.getOperand(1);
1876 if (!Offset.isImm())
1877 break; // We'll deal with this situation later on when applying fixups.
1878 if (!isInt<8>(Offset.getImm()))
1879 return Error(IDLoc, "branch target out of range");
1880 if (OffsetToAlignment(Offset.getImm(), 2LL))
1881 return Error(IDLoc, "branch to misaligned address");
1886 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1887 // We still accept it but it is a normal nop.
1888 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1889 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1890 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1895 const unsigned Opcode = Inst.getOpcode();
1907 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1908 // The offset is handled above
1909 Opnd = Inst.getOperand(1);
1911 return Error(IDLoc, "expected immediate operand kind");
1912 Imm = Opnd.getImm();
1913 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1914 Opcode == Mips::BBIT1 ? 63 : 31))
1915 return Error(IDLoc, "immediate operand value out of range");
1917 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1919 Inst.getOperand(1).setImm(Imm - 32);
1925 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1926 Opnd = Inst.getOperand(2);
1928 return Error(IDLoc, "expected immediate operand kind");
1929 Imm = Opnd.getImm();
1930 if (!isInt<10>(Imm))
1931 return Error(IDLoc, "immediate operand value out of range");
1936 // Warn on division by zero. We're checking here as all instructions get
1937 // processed here, not just the macros that need expansion.
1939 // The MIPS backend models most of the divison instructions and macros as
1940 // three operand instructions. The pre-R6 divide instructions however have
1941 // two operands and explicitly define HI/LO as part of the instruction,
1942 // not in the operands.
1943 unsigned FirstOp = 1;
1944 unsigned SecondOp = 2;
1945 switch (Inst.getOpcode()) {
1948 case Mips::SDivIMacro:
1949 case Mips::UDivIMacro:
1950 case Mips::DSDivIMacro:
1951 case Mips::DUDivIMacro:
1952 if (Inst.getOperand(2).getImm() == 0) {
1953 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1954 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1955 Warning(IDLoc, "dividing zero by zero");
1957 Warning(IDLoc, "division by zero");
1968 case Mips::SDivMacro:
1969 case Mips::DSDivMacro:
1970 case Mips::UDivMacro:
1971 case Mips::DUDivMacro:
1976 case Mips::DIVU_MMR6:
1977 case Mips::DDIVU_MM64R6:
1978 case Mips::DIV_MMR6:
1979 case Mips::DDIV_MM64R6:
1980 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1981 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1982 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1983 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1984 Warning(IDLoc, "dividing zero by zero");
1986 Warning(IDLoc, "division by zero");
1991 // For PIC code convert unconditional jump to unconditional branch.
1992 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1995 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1996 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1997 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1998 BInst.addOperand(Inst.getOperand(0));
2002 // This expansion is not in a function called by tryExpandInstruction()
2003 // because the pseudo-instruction doesn't have a distinct opcode.
2004 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2006 warnIfNoMacro(IDLoc);
2008 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2010 // We can do this expansion if there's only 1 symbol in the argument
2012 if (countMCSymbolRefExpr(JalExpr) > 1)
2013 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2015 // FIXME: This is checking the expression can be handled by the later stages
2016 // of the assembler. We ought to leave it to those later stages.
2017 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2019 // FIXME: Add support for label+offset operands (currently causes an error).
2020 // FIXME: Add support for forward-declared local symbols.
2021 // FIXME: Add expansion for when the LargeGOT option is enabled.
2022 if (JalSym->isInSection() || JalSym->isTemporary() ||
2023 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2025 // If it's a local symbol and the O32 ABI is being used, we expand to:
2027 // R_(MICRO)MIPS_GOT16 label
2028 // addiu $25, $25, 0
2029 // R_(MICRO)MIPS_LO16 label
2031 const MCExpr *Got16RelocExpr =
2032 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2033 const MCExpr *Lo16RelocExpr =
2034 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2036 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2037 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2038 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2039 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2040 } else if (isABI_N32() || isABI_N64()) {
2041 // If it's a local symbol and the N32/N64 ABIs are being used,
2043 // lw/ld $25, 0($gp)
2044 // R_(MICRO)MIPS_GOT_DISP label
2046 const MCExpr *GotDispRelocExpr =
2047 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2049 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2050 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2054 // If it's an external/weak symbol, we expand to:
2055 // lw/ld $25, 0($gp)
2056 // R_(MICRO)MIPS_CALL16 label
2058 const MCExpr *Call16RelocExpr =
2059 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2061 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2062 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2066 if (IsCpRestoreSet && inMicroMipsMode())
2067 JalrInst.setOpcode(Mips::JALRS_MM);
2069 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2070 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2071 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2073 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
2074 // This relocation is supposed to be an optimization hint for the linker
2075 // and is not necessary for correctness.
2078 ExpandedJalSym = true;
2081 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2082 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2083 // Check the offset of memory operand, if it is a symbol
2084 // reference or immediate we may have to expand instructions.
2085 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2086 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2087 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2088 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2089 MCOperand &Op = Inst.getOperand(i);
2091 int MemOffset = Op.getImm();
2092 if (MemOffset < -32768 || MemOffset > 32767) {
2093 // Offset can't exceed 16bit value.
2094 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
2095 return getParser().hasPendingError();
2097 } else if (Op.isExpr()) {
2098 const MCExpr *Expr = Op.getExpr();
2099 if (Expr->getKind() == MCExpr::SymbolRef) {
2100 const MCSymbolRefExpr *SR =
2101 static_cast<const MCSymbolRefExpr *>(Expr);
2102 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2104 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2105 return getParser().hasPendingError();
2107 } else if (!isEvaluated(Expr)) {
2108 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2109 return getParser().hasPendingError();
2116 if (inMicroMipsMode()) {
2117 if (MCID.mayLoad()) {
2118 // Try to create 16-bit GP relative load instruction.
2119 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2120 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2121 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2122 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2123 MCOperand &Op = Inst.getOperand(i);
2125 int MemOffset = Op.getImm();
2126 MCOperand &DstReg = Inst.getOperand(0);
2127 MCOperand &BaseReg = Inst.getOperand(1);
2128 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2129 getContext().getRegisterInfo()->getRegClass(
2130 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2131 (BaseReg.getReg() == Mips::GP ||
2132 BaseReg.getReg() == Mips::GP_64)) {
2134 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2143 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2148 switch (Inst.getOpcode()) {
2151 case Mips::ADDIUSP_MM:
2152 Opnd = Inst.getOperand(0);
2154 return Error(IDLoc, "expected immediate operand kind");
2155 Imm = Opnd.getImm();
2156 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2158 return Error(IDLoc, "immediate operand value out of range");
2160 case Mips::SLL16_MM:
2161 case Mips::SRL16_MM:
2162 Opnd = Inst.getOperand(2);
2164 return Error(IDLoc, "expected immediate operand kind");
2165 Imm = Opnd.getImm();
2166 if (Imm < 1 || Imm > 8)
2167 return Error(IDLoc, "immediate operand value out of range");
2170 Opnd = Inst.getOperand(1);
2172 return Error(IDLoc, "expected immediate operand kind");
2173 Imm = Opnd.getImm();
2174 if (Imm < -1 || Imm > 126)
2175 return Error(IDLoc, "immediate operand value out of range");
2177 case Mips::ADDIUR2_MM:
2178 Opnd = Inst.getOperand(2);
2180 return Error(IDLoc, "expected immediate operand kind");
2181 Imm = Opnd.getImm();
2182 if (!(Imm == 1 || Imm == -1 ||
2183 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2184 return Error(IDLoc, "immediate operand value out of range");
2186 case Mips::ANDI16_MM:
2187 Opnd = Inst.getOperand(2);
2189 return Error(IDLoc, "expected immediate operand kind");
2190 Imm = Opnd.getImm();
2191 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2192 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2193 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2194 return Error(IDLoc, "immediate operand value out of range");
2196 case Mips::LBU16_MM:
2197 Opnd = Inst.getOperand(2);
2199 return Error(IDLoc, "expected immediate operand kind");
2200 Imm = Opnd.getImm();
2201 if (Imm < -1 || Imm > 14)
2202 return Error(IDLoc, "immediate operand value out of range");
2205 case Mips::SB16_MMR6:
2206 Opnd = Inst.getOperand(2);
2208 return Error(IDLoc, "expected immediate operand kind");
2209 Imm = Opnd.getImm();
2210 if (Imm < 0 || Imm > 15)
2211 return Error(IDLoc, "immediate operand value out of range");
2213 case Mips::LHU16_MM:
2215 case Mips::SH16_MMR6:
2216 Opnd = Inst.getOperand(2);
2218 return Error(IDLoc, "expected immediate operand kind");
2219 Imm = Opnd.getImm();
2220 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2221 return Error(IDLoc, "immediate operand value out of range");
2225 case Mips::SW16_MMR6:
2226 Opnd = Inst.getOperand(2);
2228 return Error(IDLoc, "expected immediate operand kind");
2229 Imm = Opnd.getImm();
2230 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2231 return Error(IDLoc, "immediate operand value out of range");
2233 case Mips::ADDIUPC_MM:
2234 MCOperand Opnd = Inst.getOperand(1);
2236 return Error(IDLoc, "expected immediate operand kind");
2237 int Imm = Opnd.getImm();
2238 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2239 return Error(IDLoc, "immediate operand value out of range");
2244 bool FillDelaySlot =
2245 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2247 TOut.emitDirectiveSetNoReorder();
2249 MacroExpanderResultTy ExpandResult =
2250 tryExpandInstruction(Inst, IDLoc, Out, STI);
2251 switch (ExpandResult) {
2253 Out.EmitInstruction(Inst, *STI);
2261 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2262 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2263 if (inMicroMipsMode())
2264 TOut.setUsesMicroMips();
2266 // If this instruction has a delay slot and .set reorder is active,
2267 // emit a NOP after it.
2268 if (FillDelaySlot) {
2269 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2270 TOut.emitDirectiveSetReorder();
2273 if ((Inst.getOpcode() == Mips::JalOneReg ||
2274 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2275 isPicAndNotNxxAbi()) {
2276 if (IsCpRestoreSet) {
2277 // We need a NOP between the JALR and the LW:
2278 // If .set reorder has been used, we've already emitted a NOP.
2279 // If .set noreorder has been used, we need to emit a NOP at this point.
2280 if (!AssemblerOptions.back()->isReorder())
2281 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2284 // Load the $gp from the stack.
2285 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2287 Warning(IDLoc, "no .cprestore used in PIC mode");
2293 MipsAsmParser::MacroExpanderResultTy
2294 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2295 const MCSubtargetInfo *STI) {
2296 switch (Inst.getOpcode()) {
2298 return MER_NotAMacro;
2299 case Mips::LoadImm32:
2300 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2301 case Mips::LoadImm64:
2302 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2303 case Mips::LoadAddrImm32:
2304 case Mips::LoadAddrImm64:
2305 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2306 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2307 "expected immediate operand kind");
2309 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2311 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2315 case Mips::LoadAddrReg32:
2316 case Mips::LoadAddrReg64:
2317 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2318 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2319 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2320 "expected immediate operand kind");
2322 return expandLoadAddress(Inst.getOperand(0).getReg(),
2323 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2324 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2328 case Mips::B_MM_Pseudo:
2329 case Mips::B_MMR6_Pseudo:
2330 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2334 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2336 case Mips::JalOneReg:
2337 case Mips::JalTwoReg:
2338 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2341 case Mips::BEQLImmMacro:
2342 case Mips::BNELImmMacro:
2343 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2360 case Mips::BLTImmMacro:
2361 case Mips::BLEImmMacro:
2362 case Mips::BGEImmMacro:
2363 case Mips::BGTImmMacro:
2364 case Mips::BLTUImmMacro:
2365 case Mips::BLEUImmMacro:
2366 case Mips::BGEUImmMacro:
2367 case Mips::BGTUImmMacro:
2368 case Mips::BLTLImmMacro:
2369 case Mips::BLELImmMacro:
2370 case Mips::BGELImmMacro:
2371 case Mips::BGTLImmMacro:
2372 case Mips::BLTULImmMacro:
2373 case Mips::BLEULImmMacro:
2374 case Mips::BGEULImmMacro:
2375 case Mips::BGTULImmMacro:
2376 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2377 case Mips::SDivMacro:
2378 case Mips::SDivIMacro:
2379 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2381 case Mips::DSDivMacro:
2382 case Mips::DSDivIMacro:
2383 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2385 case Mips::UDivMacro:
2386 case Mips::UDivIMacro:
2387 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2389 case Mips::DUDivMacro:
2390 case Mips::DUDivIMacro:
2391 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2393 case Mips::PseudoTRUNC_W_S:
2394 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2396 case Mips::PseudoTRUNC_W_D32:
2397 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2399 case Mips::PseudoTRUNC_W_D:
2400 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2403 case Mips::LoadImmSingleGPR:
2404 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2407 case Mips::LoadImmSingleFGR:
2408 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2411 case Mips::LoadImmDoubleGPR:
2412 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2415 case Mips::LoadImmDoubleFGR:
2416 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2419 case Mips::LoadImmDoubleFGR_32:
2420 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2424 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2426 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2428 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2431 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2433 case Mips::NORImm64:
2434 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2435 case Mips::SLTImm64:
2436 if (isInt<16>(Inst.getOperand(2).getImm())) {
2437 Inst.setOpcode(Mips::SLTi64);
2438 return MER_NotAMacro;
2440 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2441 case Mips::SLTUImm64:
2442 if (isInt<16>(Inst.getOperand(2).getImm())) {
2443 Inst.setOpcode(Mips::SLTiu64);
2444 return MER_NotAMacro;
2446 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2447 case Mips::ADDi: case Mips::ADDi_MM:
2448 case Mips::ADDiu: case Mips::ADDiu_MM:
2449 case Mips::SLTi: case Mips::SLTi_MM:
2450 case Mips::SLTiu: case Mips::SLTiu_MM:
2451 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2452 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2453 int64_t ImmValue = Inst.getOperand(2).getImm();
2454 if (isInt<16>(ImmValue))
2455 return MER_NotAMacro;
2456 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2459 return MER_NotAMacro;
2460 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2461 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2462 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2463 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2464 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2465 int64_t ImmValue = Inst.getOperand(2).getImm();
2466 if (isUInt<16>(ImmValue))
2467 return MER_NotAMacro;
2468 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2471 return MER_NotAMacro;
2474 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2477 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2480 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2483 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 case Mips::ABSMacro:
2485 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2486 case Mips::MULImmMacro:
2487 case Mips::DMULImmMacro:
2488 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2489 case Mips::MULOMacro:
2490 case Mips::DMULOMacro:
2491 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2492 case Mips::MULOUMacro:
2493 case Mips::DMULOUMacro:
2494 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2495 case Mips::DMULMacro:
2496 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2499 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2500 Inst.getOpcode() == Mips::LDMacro)
2503 case Mips::SEQMacro:
2504 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2505 case Mips::SEQIMacro:
2506 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2510 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2512 const MCSubtargetInfo *STI) {
2513 MipsTargetStreamer &TOut = getTargetStreamer();
2515 // Create a JALR instruction which is going to replace the pseudo-JAL.
2517 JalrInst.setLoc(IDLoc);
2518 const MCOperand FirstRegOp = Inst.getOperand(0);
2519 const unsigned Opcode = Inst.getOpcode();
2521 if (Opcode == Mips::JalOneReg) {
2522 // jal $rs => jalr $rs
2523 if (IsCpRestoreSet && inMicroMipsMode()) {
2524 JalrInst.setOpcode(Mips::JALRS16_MM);
2525 JalrInst.addOperand(FirstRegOp);
2526 } else if (inMicroMipsMode()) {
2527 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2528 JalrInst.addOperand(FirstRegOp);
2530 JalrInst.setOpcode(Mips::JALR);
2531 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2532 JalrInst.addOperand(FirstRegOp);
2534 } else if (Opcode == Mips::JalTwoReg) {
2535 // jal $rd, $rs => jalr $rd, $rs
2536 if (IsCpRestoreSet && inMicroMipsMode())
2537 JalrInst.setOpcode(Mips::JALRS_MM);
2539 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2540 JalrInst.addOperand(FirstRegOp);
2541 const MCOperand SecondRegOp = Inst.getOperand(1);
2542 JalrInst.addOperand(SecondRegOp);
2544 Out.EmitInstruction(JalrInst, *STI);
2546 // If .set reorder is active and branch instruction has a delay slot,
2547 // emit a NOP after it.
2548 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2549 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2550 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2556 /// Can the value be represented by a unsigned N-bit value and a shift left?
2557 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2558 unsigned BitNum = findFirstSet(x);
2560 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2563 /// Load (or add) an immediate into a register.
2565 /// @param ImmValue The immediate to load.
2566 /// @param DstReg The register that will hold the immediate.
2567 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2568 /// for a simple initialization.
2569 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2570 /// @param IsAddress True if the immediate represents an address. False if it
2572 /// @param IDLoc Location of the immediate in the source file.
2573 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2574 unsigned SrcReg, bool Is32BitImm,
2575 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2576 const MCSubtargetInfo *STI) {
2577 MipsTargetStreamer &TOut = getTargetStreamer();
2579 if (!Is32BitImm && !isGP64bit()) {
2580 Error(IDLoc, "instruction requires a 64-bit architecture");
2585 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2586 // Sign extend up to 64-bit so that the predicates match the hardware
2587 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2589 ImmValue = SignExtend64<32>(ImmValue);
2591 Error(IDLoc, "instruction requires a 32-bit immediate");
2596 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2597 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2599 bool UseSrcReg = false;
2600 if (SrcReg != Mips::NoRegister)
2603 unsigned TmpReg = DstReg;
2605 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2606 // At this point we need AT to perform the expansions and we exit if it is
2608 unsigned ATReg = getATReg(IDLoc);
2614 if (isInt<16>(ImmValue)) {
2618 // This doesn't quite follow the usual ABI expectations for N32 but matches
2619 // traditional assembler behaviour. N32 would normally use addiu for both
2620 // integers and addresses.
2621 if (IsAddress && !Is32BitImm) {
2622 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2626 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2630 if (isUInt<16>(ImmValue)) {
2631 unsigned TmpReg = DstReg;
2632 if (SrcReg == DstReg) {
2633 TmpReg = getATReg(IDLoc);
2638 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2640 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2644 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2645 warnIfNoMacro(IDLoc);
2647 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2648 uint16_t Bits15To0 = ImmValue & 0xffff;
2649 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2650 // Traditional behaviour seems to special case this particular value. It's
2651 // not clear why other masks are handled differently.
2652 if (ImmValue == 0xffffffff) {
2653 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2654 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2656 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2660 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2662 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2663 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2665 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2667 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2671 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2673 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2675 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2679 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2681 Error(IDLoc, "instruction requires a 32-bit immediate");
2685 // Traditionally, these immediates are shifted as little as possible and as
2686 // such we align the most significant bit to bit 15 of our temporary.
2687 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2688 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2689 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2690 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2691 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2692 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2695 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2700 warnIfNoMacro(IDLoc);
2702 // The remaining case is packed with a sequence of dsll and ori with zeros
2703 // being omitted and any neighbouring dsll's being coalesced.
2704 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2706 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2707 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2711 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2712 // skip it and defer the shift to the next chunk.
2713 unsigned ShiftCarriedForwards = 16;
2714 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2715 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2717 if (ImmChunk != 0) {
2718 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2719 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2720 ShiftCarriedForwards = 0;
2723 ShiftCarriedForwards += 16;
2725 ShiftCarriedForwards -= 16;
2727 // Finish any remaining shifts left by trailing zeros.
2728 if (ShiftCarriedForwards)
2729 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2732 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2737 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2738 MCStreamer &Out, const MCSubtargetInfo *STI) {
2739 const MCOperand &ImmOp = Inst.getOperand(1);
2740 assert(ImmOp.isImm() && "expected immediate operand kind");
2741 const MCOperand &DstRegOp = Inst.getOperand(0);
2742 assert(DstRegOp.isReg() && "expected register operand kind");
2744 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2745 Is32BitImm, false, IDLoc, Out, STI))
2751 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2752 const MCOperand &Offset,
2753 bool Is32BitAddress, SMLoc IDLoc,
2755 const MCSubtargetInfo *STI) {
2756 // la can't produce a usable address when addresses are 64-bit.
2757 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2758 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2759 // We currently can't do this because we depend on the equality
2760 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2761 Error(IDLoc, "la used to load 64-bit address");
2762 // Continue as if we had 'dla' instead.
2763 Is32BitAddress = false;
2767 // dla requires 64-bit addresses.
2768 if (!Is32BitAddress && !hasMips3()) {
2769 Error(IDLoc, "instruction requires a 64-bit architecture");
2773 if (!Offset.isImm())
2774 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2775 Is32BitAddress, IDLoc, Out, STI);
2777 if (!ABI.ArePtrs64bit()) {
2778 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2779 Is32BitAddress = true;
2782 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2786 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2787 unsigned DstReg, unsigned SrcReg,
2788 bool Is32BitSym, SMLoc IDLoc,
2790 const MCSubtargetInfo *STI) {
2791 MipsTargetStreamer &TOut = getTargetStreamer();
2792 bool UseSrcReg = SrcReg != Mips::NoRegister;
2793 warnIfNoMacro(IDLoc);
2795 if (inPicMode() && ABI.IsO32()) {
2797 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2798 Error(IDLoc, "expected relocatable expression");
2801 if (Res.getSymB() != nullptr) {
2802 Error(IDLoc, "expected relocatable expression with only one symbol");
2806 // The case where the result register is $25 is somewhat special. If the
2807 // symbol in the final relocation is external and not modified with a
2808 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2809 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2810 Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
2811 !Res.getSymA()->getSymbol().isTemporary()) {
2812 const MCExpr *CallExpr =
2813 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2814 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2815 MCOperand::createExpr(CallExpr), IDLoc, STI);
2819 // The remaining cases are:
2820 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2821 // >addiu $tmp, $tmp, %lo(offset)
2822 // >addiu $rd, $tmp, $rs
2823 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2824 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2825 // >addiu $rd, $tmp, $rs
2826 // The addiu's marked with a '>' may be omitted if they are redundant. If
2827 // this happens then the last instruction must use $rd as the result
2829 const MipsMCExpr *GotExpr =
2830 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2831 const MCExpr *LoExpr = nullptr;
2832 if (Res.getSymA()->getSymbol().isInSection() ||
2833 Res.getSymA()->getSymbol().isTemporary())
2834 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2835 else if (Res.getConstant() != 0) {
2836 // External symbols fully resolve the symbol with just the %got(symbol)
2837 // but we must still account for any offset to the symbol for expressions
2839 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2842 unsigned TmpReg = DstReg;
2844 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2846 // If $rs is the same as $rd, we need to use AT.
2847 // If it is not available we exit.
2848 unsigned ATReg = getATReg(IDLoc);
2854 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2855 MCOperand::createExpr(GotExpr), IDLoc, STI);
2858 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2862 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2867 const MipsMCExpr *HiExpr =
2868 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2869 const MipsMCExpr *LoExpr =
2870 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2872 // This is the 64-bit symbol address expansion.
2873 if (ABI.ArePtrs64bit() && isGP64bit()) {
2874 // We need AT for the 64-bit expansion in the cases where the optional
2875 // source register is the destination register and for the superscalar
2878 // If it is not available we exit if the destination is the same as the
2881 const MipsMCExpr *HighestExpr =
2882 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2883 const MipsMCExpr *HigherExpr =
2884 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2887 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
2889 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
2890 unsigned ATReg = getATReg(IDLoc);
2892 // If $rs is the same as $rd:
2893 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2894 // daddiu $at, $at, %higher(sym)
2895 // dsll $at, $at, 16
2896 // daddiu $at, $at, %hi(sym)
2897 // dsll $at, $at, 16
2898 // daddiu $at, $at, %lo(sym)
2899 // daddu $rd, $at, $rd
2900 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2902 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2903 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2904 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2905 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2907 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2908 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2910 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2913 } else if (canUseATReg() && !RdRegIsRsReg) {
2914 unsigned ATReg = getATReg(IDLoc);
2916 // If the $rs is different from $rd or if $rs isn't specified and we
2917 // have $at available:
2918 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2919 // lui $at, %hi(sym)
2920 // daddiu $rd, $rd, %higher(sym)
2921 // daddiu $at, $at, %lo(sym)
2922 // dsll32 $rd, $rd, 0
2923 // daddu $rd, $rd, $at
2924 // (daddu $rd, $rd, $rs)
2926 // Which is preferred for superscalar issue.
2927 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2929 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2930 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2931 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2932 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2934 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2935 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2937 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2940 } else if (!canUseATReg() && !RdRegIsRsReg) {
2941 // Otherwise, synthesize the address in the destination register
2943 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2944 // daddiu $rd, $rd, %higher(sym)
2945 // dsll $rd, $rd, 16
2946 // daddiu $rd, $rd, %hi(sym)
2947 // dsll $rd, $rd, 16
2948 // daddiu $rd, $rd, %lo(sym)
2949 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2951 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2952 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2953 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
2954 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2955 MCOperand::createExpr(HiExpr), IDLoc, STI);
2956 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
2957 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2958 MCOperand::createExpr(LoExpr), IDLoc, STI);
2960 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2964 // We have a case where SrcReg == DstReg and we don't have $at
2965 // available. We can't expand this case, so error out appropriately.
2966 assert(SrcReg == DstReg && !canUseATReg() &&
2967 "Could have expanded dla but didn't?");
2968 reportParseError(IDLoc,
2969 "pseudo-instruction requires $at, which is not available");
2974 // And now, the 32-bit symbol address expansion:
2975 // If $rs is the same as $rd:
2976 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2977 // ori $at, $at, %lo(sym)
2978 // addu $rd, $at, $rd
2979 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2980 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2981 // ori $rd, $rd, %lo(sym)
2982 // (addu $rd, $rd, $rs)
2983 unsigned TmpReg = DstReg;
2985 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2986 // If $rs is the same as $rd, we need to use AT.
2987 // If it is not available we exit.
2988 unsigned ATReg = getATReg(IDLoc);
2994 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2995 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2999 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3002 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3007 // Each double-precision register DO-D15 overlaps with two of the single
3008 // precision registers F0-F31. As an example, all of the following hold true:
3009 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3010 static unsigned nextReg(unsigned Reg) {
3011 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3012 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3014 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3015 case Mips::ZERO: return Mips::AT;
3016 case Mips::AT: return Mips::V0;
3017 case Mips::V0: return Mips::V1;
3018 case Mips::V1: return Mips::A0;
3019 case Mips::A0: return Mips::A1;
3020 case Mips::A1: return Mips::A2;
3021 case Mips::A2: return Mips::A3;
3022 case Mips::A3: return Mips::T0;
3023 case Mips::T0: return Mips::T1;
3024 case Mips::T1: return Mips::T2;
3025 case Mips::T2: return Mips::T3;
3026 case Mips::T3: return Mips::T4;
3027 case Mips::T4: return Mips::T5;
3028 case Mips::T5: return Mips::T6;
3029 case Mips::T6: return Mips::T7;
3030 case Mips::T7: return Mips::S0;
3031 case Mips::S0: return Mips::S1;
3032 case Mips::S1: return Mips::S2;
3033 case Mips::S2: return Mips::S3;
3034 case Mips::S3: return Mips::S4;
3035 case Mips::S4: return Mips::S5;
3036 case Mips::S5: return Mips::S6;
3037 case Mips::S6: return Mips::S7;
3038 case Mips::S7: return Mips::T8;
3039 case Mips::T8: return Mips::T9;
3040 case Mips::T9: return Mips::K0;
3041 case Mips::K0: return Mips::K1;
3042 case Mips::K1: return Mips::GP;
3043 case Mips::GP: return Mips::SP;
3044 case Mips::SP: return Mips::FP;
3045 case Mips::FP: return Mips::RA;
3046 case Mips::RA: return Mips::ZERO;
3047 case Mips::D0: return Mips::F1;
3048 case Mips::D1: return Mips::F3;
3049 case Mips::D2: return Mips::F5;
3050 case Mips::D3: return Mips::F7;
3051 case Mips::D4: return Mips::F9;
3052 case Mips::D5: return Mips::F11;
3053 case Mips::D6: return Mips::F13;
3054 case Mips::D7: return Mips::F15;
3055 case Mips::D8: return Mips::F17;
3056 case Mips::D9: return Mips::F19;
3057 case Mips::D10: return Mips::F21;
3058 case Mips::D11: return Mips::F23;
3059 case Mips::D12: return Mips::F25;
3060 case Mips::D13: return Mips::F27;
3061 case Mips::D14: return Mips::F29;
3062 case Mips::D15: return Mips::F31;
3066 // FIXME: This method is too general. In principle we should compute the number
3067 // of instructions required to synthesize the immediate inline compared to
3068 // synthesizing the address inline and relying on non .text sections.
3069 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3070 // likely to yield a much larger benefit as we have to synthesize a 64bit
3071 // address to load a 64 bit value.
3072 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3074 unsigned ATReg = getATReg(IDLoc);
3079 const MCExpr *GotSym =
3080 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3081 const MipsMCExpr *GotExpr =
3082 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3084 if(isABI_O32() || isABI_N32()) {
3085 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3087 } else { //isABI_N64()
3088 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3091 } else { //!IsPicEnabled
3092 const MCExpr *HiSym =
3093 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3094 const MipsMCExpr *HiExpr =
3095 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3097 // FIXME: This is technically correct but gives a different result to gas,
3098 // but gas is incomplete there (it has a fixme noting it doesn't work with
3099 // 64-bit addresses).
3100 // FIXME: With -msym32 option, the address expansion for N64 should probably
3101 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3102 // symbol's value is considered sign extended.
3103 if(isABI_O32() || isABI_N32()) {
3104 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3105 } else { //isABI_N64()
3106 const MCExpr *HighestSym =
3107 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3108 const MipsMCExpr *HighestExpr =
3109 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3110 const MCExpr *HigherSym =
3111 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3112 const MipsMCExpr *HigherExpr =
3113 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3115 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3117 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3118 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3119 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3120 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3122 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3128 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3129 bool Is64FPU, SMLoc IDLoc,
3131 const MCSubtargetInfo *STI) {
3132 MipsTargetStreamer &TOut = getTargetStreamer();
3133 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3134 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3135 "Invalid instruction operand.");
3137 unsigned FirstReg = Inst.getOperand(0).getReg();
3138 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3140 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3141 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3142 // exponent field), convert it to double (e.g. 1 to 1.0)
3143 if ((HiImmOp64 & 0x7ff00000) == 0) {
3144 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3145 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3148 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3149 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3152 // Conversion of a double in an uint64_t to a float in a uint32_t,
3153 // retaining the bit pattern of a float.
3155 double doubleImm = BitsToDouble(ImmOp64);
3156 float tmp_float = static_cast<float>(doubleImm);
3157 ImmOp32 = FloatToBits(tmp_float);
3160 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3165 unsigned ATReg = getATReg(IDLoc);
3168 if (LoImmOp64 == 0) {
3169 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3172 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3176 MCSection *CS = getStreamer().getCurrentSectionOnly();
3177 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3178 // where appropriate.
3179 MCSection *ReadOnlySection = getContext().getELFSection(
3180 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3182 MCSymbol *Sym = getContext().createTempSymbol();
3183 const MCExpr *LoSym =
3184 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3185 const MipsMCExpr *LoExpr =
3186 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3188 getStreamer().SwitchSection(ReadOnlySection);
3189 getStreamer().EmitLabel(Sym, IDLoc);
3190 getStreamer().EmitIntValue(ImmOp32, 4);
3191 getStreamer().SwitchSection(CS);
3193 if(emitPartialAddress(TOut, IDLoc, Sym))
3195 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3196 MCOperand::createExpr(LoExpr), IDLoc, STI);
3202 unsigned ATReg = getATReg(IDLoc);
3207 if (LoImmOp64 == 0) {
3208 if(isABI_N32() || isABI_N64()) {
3209 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3214 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3218 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3225 MCSection *CS = getStreamer().getCurrentSectionOnly();
3226 MCSection *ReadOnlySection = getContext().getELFSection(
3227 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3229 MCSymbol *Sym = getContext().createTempSymbol();
3230 const MCExpr *LoSym =
3231 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3232 const MipsMCExpr *LoExpr =
3233 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3235 getStreamer().SwitchSection(ReadOnlySection);
3236 getStreamer().EmitLabel(Sym, IDLoc);
3237 getStreamer().EmitIntValue(HiImmOp64, 4);
3238 getStreamer().EmitIntValue(LoImmOp64, 4);
3239 getStreamer().SwitchSection(CS);
3241 if(emitPartialAddress(TOut, IDLoc, Sym))
3244 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3245 MCOperand::createExpr(LoExpr), IDLoc, STI);
3247 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3248 MCOperand::createExpr(LoExpr), IDLoc, STI);
3250 if(isABI_N32() || isABI_N64())
3251 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3253 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3254 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3257 } else { // if(!IsGPR && !IsSingle)
3258 if ((LoImmOp64 == 0) &&
3259 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3260 // FIXME: In the case where the constant is zero, we can load the
3261 // register directly from the zero register.
3262 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3265 if (isABI_N32() || isABI_N64())
3266 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3267 else if (hasMips32r2()) {
3268 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3269 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3271 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3272 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3277 MCSection *CS = getStreamer().getCurrentSectionOnly();
3278 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3279 // where appropriate.
3280 MCSection *ReadOnlySection = getContext().getELFSection(
3281 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3283 MCSymbol *Sym = getContext().createTempSymbol();
3284 const MCExpr *LoSym =
3285 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3286 const MipsMCExpr *LoExpr =
3287 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3289 getStreamer().SwitchSection(ReadOnlySection);
3290 getStreamer().EmitLabel(Sym, IDLoc);
3291 getStreamer().EmitIntValue(HiImmOp64, 4);
3292 getStreamer().EmitIntValue(LoImmOp64, 4);
3293 getStreamer().SwitchSection(CS);
3295 if(emitPartialAddress(TOut, IDLoc, Sym))
3297 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3298 MCOperand::createExpr(LoExpr), IDLoc, STI);
3303 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3305 const MCSubtargetInfo *STI) {
3306 MipsTargetStreamer &TOut = getTargetStreamer();
3308 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3309 "unexpected number of operands");
3311 MCOperand Offset = Inst.getOperand(0);
3312 if (Offset.isExpr()) {
3314 Inst.setOpcode(Mips::BEQ_MM);
3315 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3316 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3317 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3319 assert(Offset.isImm() && "expected immediate operand kind");
3320 if (isInt<11>(Offset.getImm())) {
3321 // If offset fits into 11 bits then this instruction becomes microMIPS
3322 // 16-bit unconditional branch instruction.
3323 if (inMicroMipsMode())
3324 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3326 if (!isInt<17>(Offset.getImm()))
3327 return Error(IDLoc, "branch target out of range");
3328 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3329 return Error(IDLoc, "branch to misaligned address");
3331 Inst.setOpcode(Mips::BEQ_MM);
3332 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3333 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3334 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3337 Out.EmitInstruction(Inst, *STI);
3339 // If .set reorder is active and branch instruction has a delay slot,
3340 // emit a NOP after it.
3341 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3342 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3343 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3348 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3349 const MCSubtargetInfo *STI) {
3350 MipsTargetStreamer &TOut = getTargetStreamer();
3351 const MCOperand &DstRegOp = Inst.getOperand(0);
3352 assert(DstRegOp.isReg() && "expected register operand kind");
3354 const MCOperand &ImmOp = Inst.getOperand(1);
3355 assert(ImmOp.isImm() && "expected immediate operand kind");
3357 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3358 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3359 "expected immediate or expression operand");
3361 bool IsLikely = false;
3363 unsigned OpCode = 0;
3364 switch(Inst.getOpcode()) {
3371 case Mips::BEQLImmMacro:
3372 OpCode = Mips::BEQL;
3375 case Mips::BNELImmMacro:
3376 OpCode = Mips::BNEL;
3380 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3384 int64_t ImmValue = ImmOp.getImm();
3385 if (ImmValue == 0) {
3387 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3388 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3389 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3391 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3394 warnIfNoMacro(IDLoc);
3396 unsigned ATReg = getATReg(IDLoc);
3400 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3405 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3406 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3407 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3409 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3414 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3415 const MCSubtargetInfo *STI, bool IsLoad,
3418 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3421 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3424 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3425 const MCSubtargetInfo *STI, bool IsImmOpnd) {
3426 MipsTargetStreamer &TOut = getTargetStreamer();
3428 unsigned DstReg = Inst.getOperand(0).getReg();
3429 unsigned BaseReg = Inst.getOperand(1).getReg();
3431 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3432 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3433 unsigned DstRegClassID =
3434 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3435 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3436 (DstRegClassID == Mips::GPR64RegClassID);
3439 // Try to use DstReg as the temporary.
3440 if (IsGPR && (BaseReg != DstReg)) {
3441 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3442 Inst.getOperand(2).getImm(), DstReg, IDLoc,
3447 // At this point we need AT to perform the expansions and we exit if it is
3449 unsigned ATReg = getATReg(IDLoc);
3453 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3454 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
3458 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3459 MCOperand LoOperand = MCOperand::createExpr(
3460 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3461 MCOperand HiOperand = MCOperand::createExpr(
3462 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3464 // Try to use DstReg as the temporary.
3465 if (IsGPR && (BaseReg != DstReg)) {
3466 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3467 LoOperand, DstReg, IDLoc, STI);
3471 // At this point we need AT to perform the expansions and we exit if it is
3473 unsigned ATReg = getATReg(IDLoc);
3477 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3478 LoOperand, ATReg, IDLoc, STI);
3481 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3482 const MCSubtargetInfo *STI,
3484 MipsTargetStreamer &TOut = getTargetStreamer();
3486 unsigned SrcReg = Inst.getOperand(0).getReg();
3487 unsigned BaseReg = Inst.getOperand(1).getReg();
3490 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
3491 Inst.getOperand(2).getImm(),
3492 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
3496 unsigned ATReg = getATReg(IDLoc);
3500 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3501 MCOperand LoOperand = MCOperand::createExpr(
3502 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3503 MCOperand HiOperand = MCOperand::createExpr(
3504 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3505 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
3506 LoOperand, ATReg, IDLoc, STI);
3509 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3511 const MCSubtargetInfo *STI) {
3512 unsigned OpNum = Inst.getNumOperands();
3513 unsigned Opcode = Inst.getOpcode();
3514 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3516 assert(Inst.getOperand(OpNum - 1).isImm() &&
3517 Inst.getOperand(OpNum - 2).isReg() &&
3518 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3520 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3521 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3522 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3523 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3524 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3525 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3526 // It can be implemented as SWM16 or LWM16 instruction.
3527 if (inMicroMipsMode() && hasMips32r6())
3528 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3530 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3533 Inst.setOpcode(NewOpcode);
3534 Out.EmitInstruction(Inst, *STI);
3538 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3540 const MCSubtargetInfo *STI) {
3541 MipsTargetStreamer &TOut = getTargetStreamer();
3542 bool EmittedNoMacroWarning = false;
3543 unsigned PseudoOpcode = Inst.getOpcode();
3544 unsigned SrcReg = Inst.getOperand(0).getReg();
3545 const MCOperand &TrgOp = Inst.getOperand(1);
3546 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3548 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3549 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3553 TrgReg = TrgOp.getReg();
3554 else if (TrgOp.isImm()) {
3555 warnIfNoMacro(IDLoc);
3556 EmittedNoMacroWarning = true;
3558 TrgReg = getATReg(IDLoc);
3562 switch(PseudoOpcode) {
3564 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3565 case Mips::BLTImmMacro:
3566 PseudoOpcode = Mips::BLT;
3568 case Mips::BLEImmMacro:
3569 PseudoOpcode = Mips::BLE;
3571 case Mips::BGEImmMacro:
3572 PseudoOpcode = Mips::BGE;
3574 case Mips::BGTImmMacro:
3575 PseudoOpcode = Mips::BGT;
3577 case Mips::BLTUImmMacro:
3578 PseudoOpcode = Mips::BLTU;
3580 case Mips::BLEUImmMacro:
3581 PseudoOpcode = Mips::BLEU;
3583 case Mips::BGEUImmMacro:
3584 PseudoOpcode = Mips::BGEU;
3586 case Mips::BGTUImmMacro:
3587 PseudoOpcode = Mips::BGTU;
3589 case Mips::BLTLImmMacro:
3590 PseudoOpcode = Mips::BLTL;
3592 case Mips::BLELImmMacro:
3593 PseudoOpcode = Mips::BLEL;
3595 case Mips::BGELImmMacro:
3596 PseudoOpcode = Mips::BGEL;
3598 case Mips::BGTLImmMacro:
3599 PseudoOpcode = Mips::BGTL;
3601 case Mips::BLTULImmMacro:
3602 PseudoOpcode = Mips::BLTUL;
3604 case Mips::BLEULImmMacro:
3605 PseudoOpcode = Mips::BLEUL;
3607 case Mips::BGEULImmMacro:
3608 PseudoOpcode = Mips::BGEUL;
3610 case Mips::BGTULImmMacro:
3611 PseudoOpcode = Mips::BGTUL;
3615 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3616 false, IDLoc, Out, STI))
3620 switch (PseudoOpcode) {
3625 AcceptsEquality = false;
3626 ReverseOrderSLT = false;
3627 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3628 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3629 ZeroSrcOpcode = Mips::BGTZ;
3630 ZeroTrgOpcode = Mips::BLTZ;
3636 AcceptsEquality = true;
3637 ReverseOrderSLT = true;
3638 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3639 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3640 ZeroSrcOpcode = Mips::BGEZ;
3641 ZeroTrgOpcode = Mips::BLEZ;
3647 AcceptsEquality = true;
3648 ReverseOrderSLT = false;
3649 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3650 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3651 ZeroSrcOpcode = Mips::BLEZ;
3652 ZeroTrgOpcode = Mips::BGEZ;
3658 AcceptsEquality = false;
3659 ReverseOrderSLT = true;
3660 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3661 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3662 ZeroSrcOpcode = Mips::BLTZ;
3663 ZeroTrgOpcode = Mips::BGTZ;
3666 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3669 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3670 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3671 if (IsSrcRegZero && IsTrgRegZero) {
3672 // FIXME: All of these Opcode-specific if's are needed for compatibility
3673 // with GAS' behaviour. However, they may not generate the most efficient
3674 // code in some circumstances.
3675 if (PseudoOpcode == Mips::BLT) {
3676 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3680 if (PseudoOpcode == Mips::BLE) {
3681 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3683 Warning(IDLoc, "branch is always taken");
3686 if (PseudoOpcode == Mips::BGE) {
3687 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3689 Warning(IDLoc, "branch is always taken");
3692 if (PseudoOpcode == Mips::BGT) {
3693 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3697 if (PseudoOpcode == Mips::BGTU) {
3698 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3699 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3702 if (AcceptsEquality) {
3703 // If both registers are $0 and the pseudo-branch accepts equality, it
3704 // will always be taken, so we emit an unconditional branch.
3705 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3706 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3707 Warning(IDLoc, "branch is always taken");
3710 // If both registers are $0 and the pseudo-branch does not accept
3711 // equality, it will never be taken, so we don't have to emit anything.
3714 if (IsSrcRegZero || IsTrgRegZero) {
3715 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3716 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3717 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3718 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3719 // the pseudo-branch will never be taken, so we don't emit anything.
3720 // This only applies to unsigned pseudo-branches.
3723 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3724 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3725 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3726 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3727 // the pseudo-branch will always be taken, so we emit an unconditional
3729 // This only applies to unsigned pseudo-branches.
3730 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3731 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3732 Warning(IDLoc, "branch is always taken");
3736 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3737 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3738 // the pseudo-branch will be taken only when the non-zero register is
3739 // different from 0, so we emit a BNEZ.
3741 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3742 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3743 // the pseudo-branch will be taken only when the non-zero register is
3744 // equal to 0, so we emit a BEQZ.
3746 // Because only BLEU and BGEU branch on equality, we can use the
3747 // AcceptsEquality variable to decide when to emit the BEQZ.
3748 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3749 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3750 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3753 // If we have a signed pseudo-branch and one of the registers is $0,
3754 // we can use an appropriate compare-to-zero branch. We select which one
3755 // to use in the switch statement above.
3756 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3757 IsSrcRegZero ? TrgReg : SrcReg,
3758 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3762 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3763 // expansions. If it is not available, we return.
3764 unsigned ATRegNum = getATReg(IDLoc);
3768 if (!EmittedNoMacroWarning)
3769 warnIfNoMacro(IDLoc);
3771 // SLT fits well with 2 of our 4 pseudo-branches:
3772 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3773 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3774 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3775 // This is accomplished by using a BNEZ with the result of the SLT.
3777 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3778 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3779 // Because only BGE and BLE branch on equality, we can use the
3780 // AcceptsEquality variable to decide when to emit the BEQZ.
3781 // Note that the order of the SLT arguments doesn't change between
3784 // The same applies to the unsigned variants, except that SLTu is used
3786 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3787 ReverseOrderSLT ? TrgReg : SrcReg,
3788 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3790 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3791 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3792 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3797 // Expand a integer division macro.
3799 // Notably we don't have to emit a warning when encountering $rt as the $zero
3800 // register, or 0 as an immediate. processInstruction() has already done that.
3802 // The destination register can only be $zero when expanding (S)DivIMacro or
3805 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3806 const MCSubtargetInfo *STI, const bool IsMips64,
3807 const bool Signed) {
3808 MipsTargetStreamer &TOut = getTargetStreamer();
3810 warnIfNoMacro(IDLoc);
3812 const MCOperand &RdRegOp = Inst.getOperand(0);
3813 assert(RdRegOp.isReg() && "expected register operand kind");
3814 unsigned RdReg = RdRegOp.getReg();
3816 const MCOperand &RsRegOp = Inst.getOperand(1);
3817 assert(RsRegOp.isReg() && "expected register operand kind");
3818 unsigned RsReg = RsRegOp.getReg();
3823 const MCOperand &RtOp = Inst.getOperand(2);
3824 assert((RtOp.isReg() || RtOp.isImm()) &&
3825 "expected register or immediate operand kind");
3827 RtReg = RtOp.getReg();
3829 ImmValue = RtOp.getImm();
3836 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3837 ZeroReg = Mips::ZERO_64;
3840 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3841 ZeroReg = Mips::ZERO;
3845 bool UseTraps = useTraps();
3848 unsigned ATReg = getATReg(IDLoc);
3852 if (ImmValue == 0) {
3854 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3856 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3860 if (ImmValue == 1) {
3861 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3863 } else if (Signed && ImmValue == -1) {
3864 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3867 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
3868 false, Inst.getLoc(), Out, STI))
3870 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
3871 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3877 // If the macro expansion of (d)div(u) would always trap or break, insert
3878 // the trap/break and exit. This gives a different result to GAS. GAS has
3879 // an inconsistency/missed optimization in that not all cases are handled
3880 // equivalently. As the observed behaviour is the same, we're ok.
3881 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3883 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3886 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3890 // Temporary label for first branch traget
3891 MCContext &Context = TOut.getStreamer().getContext();
3896 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3898 // Branch to the li instruction.
3899 BrTarget = Context.createTempSymbol();
3900 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
3901 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
3904 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3907 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3911 TOut.getStreamer().EmitLabel(BrTarget);
3913 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3917 unsigned ATReg = getATReg(IDLoc);
3922 TOut.getStreamer().EmitLabel(BrTarget);
3924 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3926 // Temporary label for the second branch target.
3927 MCSymbol *BrTargetEnd = Context.createTempSymbol();
3928 MCOperand LabelOpEnd =
3929 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
3931 // Branch to the mflo instruction.
3932 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
3935 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3936 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3938 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3942 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3944 // Branch to the mflo instruction.
3945 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
3946 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3947 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3950 TOut.getStreamer().EmitLabel(BrTargetEnd);
3951 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3955 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3956 SMLoc IDLoc, MCStreamer &Out,
3957 const MCSubtargetInfo *STI) {
3958 MipsTargetStreamer &TOut = getTargetStreamer();
3960 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3961 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
3962 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
3964 unsigned FirstReg = Inst.getOperand(0).getReg();
3965 unsigned SecondReg = Inst.getOperand(1).getReg();
3966 unsigned ThirdReg = Inst.getOperand(2).getReg();
3968 if (hasMips1() && !hasMips2()) {
3969 unsigned ATReg = getATReg(IDLoc);
3972 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3973 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3974 TOut.emitNop(IDLoc, STI);
3975 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3976 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3977 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3978 TOut.emitNop(IDLoc, STI);
3979 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3981 FirstReg, SecondReg, IDLoc, STI);
3982 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3983 TOut.emitNop(IDLoc, STI);
3987 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3989 FirstReg, SecondReg, IDLoc, STI);
3994 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3995 MCStreamer &Out, const MCSubtargetInfo *STI) {
3996 if (hasMips32r6() || hasMips64r6()) {
3997 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4000 const MCOperand &DstRegOp = Inst.getOperand(0);
4001 assert(DstRegOp.isReg() && "expected register operand kind");
4002 const MCOperand &SrcRegOp = Inst.getOperand(1);
4003 assert(SrcRegOp.isReg() && "expected register operand kind");
4004 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4005 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4007 MipsTargetStreamer &TOut = getTargetStreamer();
4008 unsigned DstReg = DstRegOp.getReg();
4009 unsigned SrcReg = SrcRegOp.getReg();
4010 int64_t OffsetValue = OffsetImmOp.getImm();
4012 // NOTE: We always need AT for ULHU, as it is always used as the source
4013 // register for one of the LBu's.
4014 warnIfNoMacro(IDLoc);
4015 unsigned ATReg = getATReg(IDLoc);
4019 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4020 if (IsLargeOffset) {
4021 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4026 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4027 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4029 std::swap(FirstOffset, SecondOffset);
4031 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4032 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4034 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4035 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4037 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4038 FirstOffset, IDLoc, STI);
4039 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4040 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4041 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4046 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4047 const MCSubtargetInfo *STI) {
4048 if (hasMips32r6() || hasMips64r6()) {
4049 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4052 const MCOperand &DstRegOp = Inst.getOperand(0);
4053 assert(DstRegOp.isReg() && "expected register operand kind");
4054 const MCOperand &SrcRegOp = Inst.getOperand(1);
4055 assert(SrcRegOp.isReg() && "expected register operand kind");
4056 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4057 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4059 MipsTargetStreamer &TOut = getTargetStreamer();
4060 unsigned DstReg = DstRegOp.getReg();
4061 unsigned SrcReg = SrcRegOp.getReg();
4062 int64_t OffsetValue = OffsetImmOp.getImm();
4064 warnIfNoMacro(IDLoc);
4065 unsigned ATReg = getATReg(IDLoc);
4069 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4070 if (IsLargeOffset) {
4071 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4076 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4077 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4079 std::swap(FirstOffset, SecondOffset);
4081 if (IsLargeOffset) {
4082 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4083 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4084 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4085 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4086 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4087 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4089 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4090 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4091 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4097 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4098 const MCSubtargetInfo *STI) {
4099 if (hasMips32r6() || hasMips64r6()) {
4100 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4103 const MCOperand &DstRegOp = Inst.getOperand(0);
4104 assert(DstRegOp.isReg() && "expected register operand kind");
4105 const MCOperand &SrcRegOp = Inst.getOperand(1);
4106 assert(SrcRegOp.isReg() && "expected register operand kind");
4107 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4108 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4110 MipsTargetStreamer &TOut = getTargetStreamer();
4111 unsigned DstReg = DstRegOp.getReg();
4112 unsigned SrcReg = SrcRegOp.getReg();
4113 int64_t OffsetValue = OffsetImmOp.getImm();
4115 // Compute left/right load/store offsets.
4116 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4117 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4118 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4120 std::swap(LxlOffset, LxrOffset);
4122 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4123 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4124 unsigned TmpReg = SrcReg;
4125 if (IsLargeOffset || DoMove) {
4126 warnIfNoMacro(IDLoc);
4127 TmpReg = getATReg(IDLoc);
4132 if (IsLargeOffset) {
4133 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4139 std::swap(DstReg, TmpReg);
4141 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4142 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4143 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4144 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4147 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4152 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4154 const MCSubtargetInfo *STI) {
4155 MipsTargetStreamer &TOut = getTargetStreamer();
4157 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4158 assert(Inst.getOperand(0).isReg() &&
4159 Inst.getOperand(1).isReg() &&
4160 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4162 unsigned ATReg = Mips::NoRegister;
4163 unsigned FinalDstReg = Mips::NoRegister;
4164 unsigned DstReg = Inst.getOperand(0).getReg();
4165 unsigned SrcReg = Inst.getOperand(1).getReg();
4166 int64_t ImmValue = Inst.getOperand(2).getImm();
4168 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4170 unsigned FinalOpcode = Inst.getOpcode();
4172 if (DstReg == SrcReg) {
4173 ATReg = getATReg(Inst.getLoc());
4176 FinalDstReg = DstReg;
4180 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
4181 switch (FinalOpcode) {
4183 llvm_unreachable("unimplemented expansion");
4185 FinalOpcode = Mips::ADD;
4188 FinalOpcode = Mips::ADDu;
4191 FinalOpcode = Mips::AND;
4194 FinalOpcode = Mips::NOR;
4197 FinalOpcode = Mips::OR;
4200 FinalOpcode = Mips::SLT;
4203 FinalOpcode = Mips::SLTu;
4206 FinalOpcode = Mips::XOR;
4209 FinalOpcode = Mips::ADD_MM;
4211 case Mips::ADDiu_MM:
4212 FinalOpcode = Mips::ADDu_MM;
4215 FinalOpcode = Mips::AND_MM;
4218 FinalOpcode = Mips::OR_MM;
4221 FinalOpcode = Mips::SLT_MM;
4223 case Mips::SLTiu_MM:
4224 FinalOpcode = Mips::SLTu_MM;
4227 FinalOpcode = Mips::XOR_MM;
4230 FinalOpcode = Mips::AND64;
4232 case Mips::NORImm64:
4233 FinalOpcode = Mips::NOR64;
4236 FinalOpcode = Mips::OR64;
4238 case Mips::SLTImm64:
4239 FinalOpcode = Mips::SLT64;
4241 case Mips::SLTUImm64:
4242 FinalOpcode = Mips::SLTu64;
4245 FinalOpcode = Mips::XOR64;
4249 if (FinalDstReg == Mips::NoRegister)
4250 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4252 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4258 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4259 const MCSubtargetInfo *STI) {
4260 MipsTargetStreamer &TOut = getTargetStreamer();
4261 unsigned ATReg = Mips::NoRegister;
4262 unsigned DReg = Inst.getOperand(0).getReg();
4263 unsigned SReg = Inst.getOperand(1).getReg();
4264 unsigned TReg = Inst.getOperand(2).getReg();
4265 unsigned TmpReg = DReg;
4267 unsigned FirstShift = Mips::NOP;
4268 unsigned SecondShift = Mips::NOP;
4270 if (hasMips32r2()) {
4272 TmpReg = getATReg(Inst.getLoc());
4277 if (Inst.getOpcode() == Mips::ROL) {
4278 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4279 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4283 if (Inst.getOpcode() == Mips::ROR) {
4284 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4292 switch (Inst.getOpcode()) {
4294 llvm_unreachable("unexpected instruction opcode");
4296 FirstShift = Mips::SRLV;
4297 SecondShift = Mips::SLLV;
4300 FirstShift = Mips::SLLV;
4301 SecondShift = Mips::SRLV;
4305 ATReg = getATReg(Inst.getLoc());
4309 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4310 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4311 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4312 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4320 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4322 const MCSubtargetInfo *STI) {
4323 MipsTargetStreamer &TOut = getTargetStreamer();
4324 unsigned ATReg = Mips::NoRegister;
4325 unsigned DReg = Inst.getOperand(0).getReg();
4326 unsigned SReg = Inst.getOperand(1).getReg();
4327 int64_t ImmValue = Inst.getOperand(2).getImm();
4329 unsigned FirstShift = Mips::NOP;
4330 unsigned SecondShift = Mips::NOP;
4332 if (hasMips32r2()) {
4333 if (Inst.getOpcode() == Mips::ROLImm) {
4334 uint64_t MaxShift = 32;
4335 uint64_t ShiftValue = ImmValue;
4337 ShiftValue = MaxShift - ImmValue;
4338 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4342 if (Inst.getOpcode() == Mips::RORImm) {
4343 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4351 if (ImmValue == 0) {
4352 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4356 switch (Inst.getOpcode()) {
4358 llvm_unreachable("unexpected instruction opcode");
4360 FirstShift = Mips::SLL;
4361 SecondShift = Mips::SRL;
4364 FirstShift = Mips::SRL;
4365 SecondShift = Mips::SLL;
4369 ATReg = getATReg(Inst.getLoc());
4373 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4374 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4375 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4383 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4384 const MCSubtargetInfo *STI) {
4385 MipsTargetStreamer &TOut = getTargetStreamer();
4386 unsigned ATReg = Mips::NoRegister;
4387 unsigned DReg = Inst.getOperand(0).getReg();
4388 unsigned SReg = Inst.getOperand(1).getReg();
4389 unsigned TReg = Inst.getOperand(2).getReg();
4390 unsigned TmpReg = DReg;
4392 unsigned FirstShift = Mips::NOP;
4393 unsigned SecondShift = Mips::NOP;
4395 if (hasMips64r2()) {
4396 if (TmpReg == SReg) {
4397 TmpReg = getATReg(Inst.getLoc());
4402 if (Inst.getOpcode() == Mips::DROL) {
4403 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4404 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4408 if (Inst.getOpcode() == Mips::DROR) {
4409 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4417 switch (Inst.getOpcode()) {
4419 llvm_unreachable("unexpected instruction opcode");
4421 FirstShift = Mips::DSRLV;
4422 SecondShift = Mips::DSLLV;
4425 FirstShift = Mips::DSLLV;
4426 SecondShift = Mips::DSRLV;
4430 ATReg = getATReg(Inst.getLoc());
4434 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4435 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4436 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4437 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4445 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4447 const MCSubtargetInfo *STI) {
4448 MipsTargetStreamer &TOut = getTargetStreamer();
4449 unsigned ATReg = Mips::NoRegister;
4450 unsigned DReg = Inst.getOperand(0).getReg();
4451 unsigned SReg = Inst.getOperand(1).getReg();
4452 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4454 unsigned FirstShift = Mips::NOP;
4455 unsigned SecondShift = Mips::NOP;
4459 if (hasMips64r2()) {
4460 unsigned FinalOpcode = Mips::NOP;
4462 FinalOpcode = Mips::DROTR;
4463 else if (ImmValue % 32 == 0)
4464 FinalOpcode = Mips::DROTR32;
4465 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4466 if (Inst.getOpcode() == Mips::DROLImm)
4467 FinalOpcode = Mips::DROTR32;
4469 FinalOpcode = Mips::DROTR;
4470 } else if (ImmValue >= 33) {
4471 if (Inst.getOpcode() == Mips::DROLImm)
4472 FinalOpcode = Mips::DROTR;
4474 FinalOpcode = Mips::DROTR32;
4477 uint64_t ShiftValue = ImmValue % 32;
4478 if (Inst.getOpcode() == Mips::DROLImm)
4479 ShiftValue = (32 - ImmValue % 32) % 32;
4481 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4487 if (ImmValue == 0) {
4488 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4492 switch (Inst.getOpcode()) {
4494 llvm_unreachable("unexpected instruction opcode");
4496 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4497 FirstShift = Mips::DSLL;
4498 SecondShift = Mips::DSRL32;
4500 if (ImmValue == 32) {
4501 FirstShift = Mips::DSLL32;
4502 SecondShift = Mips::DSRL32;
4504 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4505 FirstShift = Mips::DSLL32;
4506 SecondShift = Mips::DSRL;
4510 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4511 FirstShift = Mips::DSRL;
4512 SecondShift = Mips::DSLL32;
4514 if (ImmValue == 32) {
4515 FirstShift = Mips::DSRL32;
4516 SecondShift = Mips::DSLL32;
4518 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4519 FirstShift = Mips::DSRL32;
4520 SecondShift = Mips::DSLL;
4525 ATReg = getATReg(Inst.getLoc());
4529 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4530 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4531 Inst.getLoc(), STI);
4532 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4540 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4541 const MCSubtargetInfo *STI) {
4542 MipsTargetStreamer &TOut = getTargetStreamer();
4543 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4544 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4546 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4547 if (FirstRegOp != SecondRegOp)
4548 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4550 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4551 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4556 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4557 const MCSubtargetInfo *STI) {
4558 MipsTargetStreamer &TOut = getTargetStreamer();
4559 unsigned ATReg = Mips::NoRegister;
4560 unsigned DstReg = Inst.getOperand(0).getReg();
4561 unsigned SrcReg = Inst.getOperand(1).getReg();
4562 int32_t ImmValue = Inst.getOperand(2).getImm();
4564 ATReg = getATReg(IDLoc);
4568 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, STI);
4570 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4571 SrcReg, ATReg, IDLoc, STI);
4573 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4578 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4579 const MCSubtargetInfo *STI) {
4580 MipsTargetStreamer &TOut = getTargetStreamer();
4581 unsigned ATReg = Mips::NoRegister;
4582 unsigned DstReg = Inst.getOperand(0).getReg();
4583 unsigned SrcReg = Inst.getOperand(1).getReg();
4584 unsigned TmpReg = Inst.getOperand(2).getReg();
4586 ATReg = getATReg(Inst.getLoc());
4590 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4591 SrcReg, TmpReg, IDLoc, STI);
4593 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4595 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4596 DstReg, DstReg, 0x1F, IDLoc, STI);
4598 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4601 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4603 MCContext & Context = TOut.getStreamer().getContext();
4604 MCSymbol * BrTarget = Context.createTempSymbol();
4606 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4608 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4609 if (AssemblerOptions.back()->isReorder())
4610 TOut.emitNop(IDLoc, STI);
4611 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4613 TOut.getStreamer().EmitLabel(BrTarget);
4615 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4620 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4621 const MCSubtargetInfo *STI) {
4622 MipsTargetStreamer &TOut = getTargetStreamer();
4623 unsigned ATReg = Mips::NoRegister;
4624 unsigned DstReg = Inst.getOperand(0).getReg();
4625 unsigned SrcReg = Inst.getOperand(1).getReg();
4626 unsigned TmpReg = Inst.getOperand(2).getReg();
4628 ATReg = getATReg(IDLoc);
4632 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4633 SrcReg, TmpReg, IDLoc, STI);
4635 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4636 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4638 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4640 MCContext & Context = TOut.getStreamer().getContext();
4641 MCSymbol * BrTarget = Context.createTempSymbol();
4643 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4645 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4646 if (AssemblerOptions.back()->isReorder())
4647 TOut.emitNop(IDLoc, STI);
4648 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4650 TOut.getStreamer().EmitLabel(BrTarget);
4656 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4657 const MCSubtargetInfo *STI) {
4658 MipsTargetStreamer &TOut = getTargetStreamer();
4659 unsigned DstReg = Inst.getOperand(0).getReg();
4660 unsigned SrcReg = Inst.getOperand(1).getReg();
4661 unsigned TmpReg = Inst.getOperand(2).getReg();
4663 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4664 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4669 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4670 // lw $<reg+1>>, offset+4($reg2)'
4671 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4672 // sw $<reg+1>>, offset+4($reg2)'
4674 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4676 const MCSubtargetInfo *STI,
4681 warnIfNoMacro(IDLoc);
4683 MipsTargetStreamer &TOut = getTargetStreamer();
4684 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4685 unsigned FirstReg = Inst.getOperand(0).getReg();
4686 unsigned SecondReg = nextReg(FirstReg);
4687 unsigned BaseReg = Inst.getOperand(1).getReg();
4691 warnIfRegIndexIsAT(FirstReg, IDLoc);
4693 assert(Inst.getOperand(2).isImm() &&
4694 "Offset for load macro is not immediate!");
4696 MCOperand &FirstOffset = Inst.getOperand(2);
4697 signed NextOffset = FirstOffset.getImm() + 4;
4698 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4700 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4703 // For loads, clobber the base register with the second load instead of the
4704 // first if the BaseReg == FirstReg.
4705 if (FirstReg != BaseReg || !IsLoad) {
4706 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4707 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4709 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4710 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4716 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4717 const MCSubtargetInfo *STI) {
4719 warnIfNoMacro(IDLoc);
4720 MipsTargetStreamer &TOut = getTargetStreamer();
4722 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4723 Inst.getOperand(2).getReg() != Mips::ZERO) {
4724 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4725 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4727 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4728 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4733 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4734 Reg = Inst.getOperand(2).getReg();
4736 Reg = Inst.getOperand(1).getReg();
4738 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4742 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4743 const MCSubtargetInfo *STI) {
4744 warnIfNoMacro(IDLoc);
4745 MipsTargetStreamer &TOut = getTargetStreamer();
4748 int64_t Imm = Inst.getOperand(2).getImm();
4749 unsigned Reg = Inst.getOperand(1).getReg();
4752 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4753 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4757 if (Reg == Mips::ZERO) {
4758 Warning(IDLoc, "comparison is always false");
4759 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4760 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4764 if (Imm > -0x8000 && Imm < 0) {
4766 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4771 if (!isUInt<16>(Imm)) {
4772 unsigned ATReg = getATReg(IDLoc);
4776 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4780 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4781 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4782 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4783 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4787 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4789 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4790 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4795 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
4796 const OperandVector &Operands) {
4797 switch (Inst.getOpcode()) {
4799 return Match_Success;
4802 case Mips::DATI_MM64R6:
4803 case Mips::DAHI_MM64R6:
4804 if (static_cast<MipsOperand &>(*Operands[1])
4805 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4806 return Match_Success;
4807 return Match_RequiresSameSrcAndDst;
4811 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4812 switch (Inst.getOpcode()) {
4813 // As described by the MIPSR6 spec, daui must not use the zero operand for
4814 // its source operand.
4816 case Mips::DAUI_MM64R6:
4817 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4818 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4819 return Match_RequiresNoZeroRegister;
4820 return Match_Success;
4821 // As described by the Mips32r2 spec, the registers Rd and Rs for
4822 // jalr.hb must be different.
4823 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
4824 // and registers Rd and Base for microMIPS lwp instruction
4826 case Mips::JALRC_HB_MMR6:
4827 case Mips::JALRC_MMR6:
4828 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4829 return Match_RequiresDifferentSrcAndDst;
4830 return Match_Success;
4832 case Mips::LWP_MMR6:
4833 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
4834 return Match_RequiresDifferentSrcAndDst;
4835 return Match_Success;
4837 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
4838 return Match_NonZeroOperandForSync;
4839 return Match_Success;
4840 // As described the MIPSR6 spec, the compact branches that compare registers
4842 // a) Not use the zero register.
4843 // b) Not use the same register twice.
4844 // c) rs < rt for bnec, beqc.
4845 // NB: For this case, the encoding will swap the operands as their
4846 // ordering doesn't matter. GAS performs this transformation too.
4847 // Hence, that constraint does not have to be enforced.
4849 // The compact branches that branch iff the signed addition of two registers
4850 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
4851 // operand swapping. They do not have restriction of using the zero register.
4852 case Mips::BLEZC: case Mips::BLEZC_MMR6:
4853 case Mips::BGEZC: case Mips::BGEZC_MMR6:
4854 case Mips::BGTZC: case Mips::BGTZC_MMR6:
4855 case Mips::BLTZC: case Mips::BLTZC_MMR6:
4856 case Mips::BEQZC: case Mips::BEQZC_MMR6:
4857 case Mips::BNEZC: case Mips::BNEZC_MMR6:
4864 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4865 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4866 return Match_RequiresNoZeroRegister;
4867 return Match_Success;
4868 case Mips::BGEC: case Mips::BGEC_MMR6:
4869 case Mips::BLTC: case Mips::BLTC_MMR6:
4870 case Mips::BGEUC: case Mips::BGEUC_MMR6:
4871 case Mips::BLTUC: case Mips::BLTUC_MMR6:
4872 case Mips::BEQC: case Mips::BEQC_MMR6:
4873 case Mips::BNEC: case Mips::BNEC_MMR6:
4880 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4881 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4882 return Match_RequiresNoZeroRegister;
4883 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4884 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4885 return Match_RequiresNoZeroRegister;
4886 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4887 return Match_RequiresDifferentOperands;
4888 return Match_Success;
4891 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
4892 if ((TSFlags & MipsII::HasFCCRegOperand) &&
4893 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
4894 return Match_NoFCCRegisterForCurrentISA;
4896 return Match_Success;
4900 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
4901 uint64_t ErrorInfo) {
4902 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
4903 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4904 if (ErrorLoc == SMLoc())
4911 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4912 OperandVector &Operands,
4914 uint64_t &ErrorInfo,
4915 bool MatchingInlineAsm) {
4917 unsigned MatchResult =
4918 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
4920 switch (MatchResult) {
4922 if (processInstruction(Inst, IDLoc, Out, STI))
4925 case Match_MissingFeature:
4926 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4928 case Match_InvalidOperand: {
4929 SMLoc ErrorLoc = IDLoc;
4930 if (ErrorInfo != ~0ULL) {
4931 if (ErrorInfo >= Operands.size())
4932 return Error(IDLoc, "too few operands for instruction");
4934 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4935 if (ErrorLoc == SMLoc())
4939 return Error(ErrorLoc, "invalid operand for instruction");
4941 case Match_NonZeroOperandForSync:
4942 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
4943 case Match_MnemonicFail:
4944 return Error(IDLoc, "invalid instruction");
4945 case Match_RequiresDifferentSrcAndDst:
4946 return Error(IDLoc, "source and destination must be different");
4947 case Match_RequiresDifferentOperands:
4948 return Error(IDLoc, "registers must be different");
4949 case Match_RequiresNoZeroRegister:
4950 return Error(IDLoc, "invalid operand ($zero) for instruction");
4951 case Match_RequiresSameSrcAndDst:
4952 return Error(IDLoc, "source and destination must match");
4953 case Match_NoFCCRegisterForCurrentISA:
4954 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4955 "non-zero fcc register doesn't exist in current ISA level");
4957 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
4959 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4960 "expected 1-bit unsigned immediate");
4962 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4963 "expected 2-bit unsigned immediate");
4965 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4966 "expected immediate in range 1 .. 4");
4968 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4969 "expected 3-bit unsigned immediate");
4971 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4972 "expected 4-bit unsigned immediate");
4974 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4975 "expected 4-bit signed immediate");
4977 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4978 "expected 5-bit unsigned immediate");
4980 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4981 "expected 5-bit signed immediate");
4983 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4984 "expected immediate in range 1 .. 32");
4985 case Match_UImm5_32:
4986 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4987 "expected immediate in range 32 .. 63");
4988 case Match_UImm5_33:
4989 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4990 "expected immediate in range 33 .. 64");
4991 case Match_UImm5_0_Report_UImm6:
4992 // This is used on UImm5 operands that have a corresponding UImm5_32
4993 // operand to avoid confusing the user.
4994 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4995 "expected 6-bit unsigned immediate");
4996 case Match_UImm5_Lsl2:
4997 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4998 "expected both 7-bit unsigned immediate and multiple of 4");
4999 case Match_UImmRange2_64:
5000 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5001 "expected immediate in range 2 .. 64");
5003 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5004 "expected 6-bit unsigned immediate");
5005 case Match_UImm6_Lsl2:
5006 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5007 "expected both 8-bit unsigned immediate and multiple of 4");
5009 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5010 "expected 6-bit signed immediate");
5012 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5013 "expected 7-bit unsigned immediate");
5014 case Match_UImm7_N1:
5015 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5016 "expected immediate in range -1 .. 126");
5017 case Match_SImm7_Lsl2:
5018 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5019 "expected both 9-bit signed immediate and multiple of 4");
5021 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5022 "expected 8-bit unsigned immediate");
5023 case Match_UImm10_0:
5024 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5025 "expected 10-bit unsigned immediate");
5026 case Match_SImm10_0:
5027 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5028 "expected 10-bit signed immediate");
5029 case Match_SImm11_0:
5030 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5031 "expected 11-bit signed immediate");
5033 case Match_UImm16_Relaxed:
5034 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5035 "expected 16-bit unsigned immediate");
5037 case Match_SImm16_Relaxed:
5038 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5039 "expected 16-bit signed immediate");
5040 case Match_SImm19_Lsl2:
5041 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5042 "expected both 19-bit signed immediate and multiple of 4");
5043 case Match_UImm20_0:
5044 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5045 "expected 20-bit unsigned immediate");
5046 case Match_UImm26_0:
5047 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5048 "expected 26-bit unsigned immediate");
5050 case Match_SImm32_Relaxed:
5051 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5052 "expected 32-bit signed immediate");
5053 case Match_UImm32_Coerced:
5054 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5055 "expected 32-bit immediate");
5056 case Match_MemSImm9:
5057 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5058 "expected memory with 9-bit signed offset");
5059 case Match_MemSImm10:
5060 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5061 "expected memory with 10-bit signed offset");
5062 case Match_MemSImm10Lsl1:
5063 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5064 "expected memory with 11-bit signed offset and multiple of 2");
5065 case Match_MemSImm10Lsl2:
5066 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5067 "expected memory with 12-bit signed offset and multiple of 4");
5068 case Match_MemSImm10Lsl3:
5069 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5070 "expected memory with 13-bit signed offset and multiple of 8");
5071 case Match_MemSImm11:
5072 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5073 "expected memory with 11-bit signed offset");
5074 case Match_MemSImm12:
5075 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5076 "expected memory with 12-bit signed offset");
5077 case Match_MemSImm16:
5078 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5079 "expected memory with 16-bit signed offset");
5082 llvm_unreachable("Implement any new match types added!");
5085 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5086 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5087 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5088 ") without \".set noat\"");
5091 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5092 if (!AssemblerOptions.back()->isMacro())
5093 Warning(Loc, "macro instruction expanded into multiple instructions");
5097 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5098 SMRange Range, bool ShowColors) {
5099 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5100 Range, SMFixIt(Range, FixMsg),
5104 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5107 CC = StringSwitch<unsigned>(Name)
5143 if (!(isABI_N32() || isABI_N64()))
5146 if (12 <= CC && CC <= 15) {
5147 // Name is one of t4-t7
5148 AsmToken RegTok = getLexer().peekTok();
5149 SMRange RegRange = RegTok.getLocRange();
5151 StringRef FixedName = StringSwitch<StringRef>(Name)
5157 assert(FixedName != "" && "Register name is not one of t4-t7.");
5159 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5160 "Did you mean $" + FixedName + "?", RegRange);
5163 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5164 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5165 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5166 if (8 <= CC && CC <= 11)
5170 CC = StringSwitch<unsigned>(Name)
5182 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5185 CC = StringSwitch<unsigned>(Name)
5186 .Case("hwr_cpunum", 0)
5187 .Case("hwr_synci_step", 1)
5189 .Case("hwr_ccres", 3)
5190 .Case("hwr_ulr", 29)
5196 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5197 if (Name[0] == 'f') {
5198 StringRef NumString = Name.substr(1);
5200 if (NumString.getAsInteger(10, IntVal))
5201 return -1; // This is not an integer.
5202 if (IntVal > 31) // Maximum index for fpu register.
5209 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5210 if (Name.startswith("fcc")) {
5211 StringRef NumString = Name.substr(3);
5213 if (NumString.getAsInteger(10, IntVal))
5214 return -1; // This is not an integer.
5215 if (IntVal > 7) // There are only 8 fcc registers.
5222 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5223 if (Name.startswith("ac")) {
5224 StringRef NumString = Name.substr(2);
5226 if (NumString.getAsInteger(10, IntVal))
5227 return -1; // This is not an integer.
5228 if (IntVal > 3) // There are only 3 acc registers.
5235 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5238 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5247 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5250 CC = StringSwitch<unsigned>(Name)
5253 .Case("msaaccess", 2)
5255 .Case("msamodify", 4)
5256 .Case("msarequest", 5)
5258 .Case("msaunmap", 7)
5264 bool MipsAsmParser::canUseATReg() {
5265 return AssemblerOptions.back()->getATRegIndex() != 0;
5268 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5269 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5271 reportParseError(Loc,
5272 "pseudo-instruction requires $at, which is not available");
5275 unsigned AT = getReg(
5276 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5280 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5281 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5284 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5285 MCAsmParser &Parser = getParser();
5286 DEBUG(dbgs() << "parseOperand\n");
5288 // Check if the current operand has a custom associated parser, if so, try to
5289 // custom parse the operand, or fallback to the general approach.
5290 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5291 if (ResTy == MatchOperand_Success)
5293 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5294 // there was a match, but an error occurred, in which case, just return that
5295 // the operand parsing failed.
5296 if (ResTy == MatchOperand_ParseFail)
5299 DEBUG(dbgs() << ".. Generic Parser\n");
5301 switch (getLexer().getKind()) {
5302 case AsmToken::Dollar: {
5303 // Parse the register.
5304 SMLoc S = Parser.getTok().getLoc();
5306 // Almost all registers have been parsed by custom parsers. There is only
5307 // one exception to this. $zero (and it's alias $0) will reach this point
5308 // for div, divu, and similar instructions because it is not an operand
5309 // to the instruction definition but an explicit register. Special case
5310 // this situation for now.
5311 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5314 // Maybe it is a symbol reference.
5315 StringRef Identifier;
5316 if (Parser.parseIdentifier(Identifier))
5319 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5320 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5321 // Otherwise create a symbol reference.
5323 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5325 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5329 DEBUG(dbgs() << ".. generic integer expression\n");
5332 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5333 if (getParser().parseExpression(Expr))
5336 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5338 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5341 } // switch(getLexer().getKind())
5345 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5346 switch (Expr->getKind()) {
5347 case MCExpr::Constant:
5349 case MCExpr::SymbolRef:
5350 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5351 case MCExpr::Binary:
5352 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
5353 if (!isEvaluated(BE->getLHS()))
5355 return isEvaluated(BE->getRHS());
5358 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5359 case MCExpr::Target:
5365 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5367 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5368 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5369 if (ResTy == MatchOperand_Success) {
5370 assert(Operands.size() == 1);
5371 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5372 StartLoc = Operand.getStartLoc();
5373 EndLoc = Operand.getEndLoc();
5375 // AFAIK, we only support numeric registers and named GPR's in CFI
5377 // Don't worry about eating tokens before failing. Using an unrecognised
5378 // register is a parse error.
5379 if (Operand.isGPRAsmReg()) {
5380 // Resolve to GPR32 or GPR64 appropriately.
5381 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5384 return (RegNo == (unsigned)-1);
5387 assert(Operands.size() == 0);
5388 return (RegNo == (unsigned)-1);
5391 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5395 return getParser().parseParenExprOfDepth(0, Res, S);
5396 return getParser().parseExpression(Res);
5399 OperandMatchResultTy
5400 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5401 MCAsmParser &Parser = getParser();
5402 DEBUG(dbgs() << "parseMemOperand\n");
5403 const MCExpr *IdVal = nullptr;
5405 bool isParenExpr = false;
5406 OperandMatchResultTy Res = MatchOperand_NoMatch;
5407 // First operand is the offset.
5408 S = Parser.getTok().getLoc();
5410 if (getLexer().getKind() == AsmToken::LParen) {
5415 if (getLexer().getKind() != AsmToken::Dollar) {
5416 if (parseMemOffset(IdVal, isParenExpr))
5417 return MatchOperand_ParseFail;
5419 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5420 if (Tok.isNot(AsmToken::LParen)) {
5421 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5422 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5424 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5425 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5426 return MatchOperand_Success;
5428 if (Tok.is(AsmToken::EndOfStatement)) {
5430 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5432 // Zero register assumed, add a memory operand with ZERO as its base.
5433 // "Base" will be managed by k_Memory.
5434 auto Base = MipsOperand::createGPRReg(
5435 0, "0", getContext().getRegisterInfo(), S, E, *this);
5437 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5438 return MatchOperand_Success;
5440 MCBinaryExpr::Opcode Opcode;
5441 // GAS and LLVM treat comparison operators different. GAS will generate -1
5442 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5443 // highly unlikely to be found in a memory offset expression, we don't
5445 switch (Tok.getKind()) {
5446 case AsmToken::Plus:
5447 Opcode = MCBinaryExpr::Add;
5450 case AsmToken::Minus:
5451 Opcode = MCBinaryExpr::Sub;
5454 case AsmToken::Star:
5455 Opcode = MCBinaryExpr::Mul;
5458 case AsmToken::Pipe:
5459 Opcode = MCBinaryExpr::Or;
5463 Opcode = MCBinaryExpr::And;
5466 case AsmToken::LessLess:
5467 Opcode = MCBinaryExpr::Shl;
5470 case AsmToken::GreaterGreater:
5471 Opcode = MCBinaryExpr::LShr;
5474 case AsmToken::Caret:
5475 Opcode = MCBinaryExpr::Xor;
5478 case AsmToken::Slash:
5479 Opcode = MCBinaryExpr::Div;
5482 case AsmToken::Percent:
5483 Opcode = MCBinaryExpr::Mod;
5487 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5488 return MatchOperand_ParseFail;
5490 const MCExpr * NextExpr;
5491 if (getParser().parseExpression(NextExpr))
5492 return MatchOperand_ParseFail;
5493 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5496 Parser.Lex(); // Eat the '(' token.
5499 Res = parseAnyRegister(Operands);
5500 if (Res != MatchOperand_Success)
5503 if (Parser.getTok().isNot(AsmToken::RParen)) {
5504 Error(Parser.getTok().getLoc(), "')' expected");
5505 return MatchOperand_ParseFail;
5508 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5510 Parser.Lex(); // Eat the ')' token.
5513 IdVal = MCConstantExpr::create(0, getContext());
5515 // Replace the register operand with the memory operand.
5516 std::unique_ptr<MipsOperand> op(
5517 static_cast<MipsOperand *>(Operands.back().release()));
5518 // Remove the register from the operands.
5519 // "op" will be managed by k_Memory.
5520 Operands.pop_back();
5521 // Add the memory operand.
5522 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5524 if (IdVal->evaluateAsAbsolute(Imm))
5525 IdVal = MCConstantExpr::create(Imm, getContext());
5526 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5527 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5531 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5532 return MatchOperand_Success;
5535 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5536 MCAsmParser &Parser = getParser();
5537 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5539 SMLoc S = Parser.getTok().getLoc();
5541 if (Sym->isVariable())
5542 Expr = Sym->getVariableValue();
5545 if (Expr->getKind() == MCExpr::SymbolRef) {
5546 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5547 StringRef DefSymbol = Ref->getSymbol().getName();
5548 if (DefSymbol.startswith("$")) {
5549 OperandMatchResultTy ResTy =
5550 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5551 if (ResTy == MatchOperand_Success) {
5554 } else if (ResTy == MatchOperand_ParseFail)
5555 llvm_unreachable("Should never ParseFail");
5563 OperandMatchResultTy
5564 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
5565 StringRef Identifier,
5567 int Index = matchCPURegisterName(Identifier);
5569 Operands.push_back(MipsOperand::createGPRReg(
5570 Index, Identifier, getContext().getRegisterInfo(), S,
5571 getLexer().getLoc(), *this));
5572 return MatchOperand_Success;
5575 Index = matchHWRegsRegisterName(Identifier);
5577 Operands.push_back(MipsOperand::createHWRegsReg(
5578 Index, Identifier, getContext().getRegisterInfo(), S,
5579 getLexer().getLoc(), *this));
5580 return MatchOperand_Success;
5583 Index = matchFPURegisterName(Identifier);
5585 Operands.push_back(MipsOperand::createFGRReg(
5586 Index, Identifier, getContext().getRegisterInfo(), S,
5587 getLexer().getLoc(), *this));
5588 return MatchOperand_Success;
5591 Index = matchFCCRegisterName(Identifier);
5593 Operands.push_back(MipsOperand::createFCCReg(
5594 Index, Identifier, getContext().getRegisterInfo(), S,
5595 getLexer().getLoc(), *this));
5596 return MatchOperand_Success;
5599 Index = matchACRegisterName(Identifier);
5601 Operands.push_back(MipsOperand::createACCReg(
5602 Index, Identifier, getContext().getRegisterInfo(), S,
5603 getLexer().getLoc(), *this));
5604 return MatchOperand_Success;
5607 Index = matchMSA128RegisterName(Identifier);
5609 Operands.push_back(MipsOperand::createMSA128Reg(
5610 Index, Identifier, getContext().getRegisterInfo(), S,
5611 getLexer().getLoc(), *this));
5612 return MatchOperand_Success;
5615 Index = matchMSA128CtrlRegisterName(Identifier);
5617 Operands.push_back(MipsOperand::createMSACtrlReg(
5618 Index, Identifier, getContext().getRegisterInfo(), S,
5619 getLexer().getLoc(), *this));
5620 return MatchOperand_Success;
5623 return MatchOperand_NoMatch;
5626 OperandMatchResultTy
5627 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
5628 MCAsmParser &Parser = getParser();
5629 auto Token = Parser.getLexer().peekTok(false);
5631 if (Token.is(AsmToken::Identifier)) {
5632 DEBUG(dbgs() << ".. identifier\n");
5633 StringRef Identifier = Token.getIdentifier();
5634 OperandMatchResultTy ResTy =
5635 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
5637 } else if (Token.is(AsmToken::Integer)) {
5638 DEBUG(dbgs() << ".. integer\n");
5639 Operands.push_back(MipsOperand::createNumericReg(
5640 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
5641 Token.getLoc(), *this));
5642 return MatchOperand_Success;
5645 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
5647 return MatchOperand_NoMatch;
5650 OperandMatchResultTy
5651 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
5652 MCAsmParser &Parser = getParser();
5653 DEBUG(dbgs() << "parseAnyRegister\n");
5655 auto Token = Parser.getTok();
5657 SMLoc S = Token.getLoc();
5659 if (Token.isNot(AsmToken::Dollar)) {
5660 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
5661 if (Token.is(AsmToken::Identifier)) {
5662 if (searchSymbolAlias(Operands))
5663 return MatchOperand_Success;
5665 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
5666 return MatchOperand_NoMatch;
5668 DEBUG(dbgs() << ".. $\n");
5670 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
5671 if (ResTy == MatchOperand_Success) {
5673 Parser.Lex(); // identifier
5678 OperandMatchResultTy
5679 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
5680 MCAsmParser &Parser = getParser();
5681 DEBUG(dbgs() << "parseJumpTarget\n");
5683 SMLoc S = getLexer().getLoc();
5685 // Registers are a valid target and have priority over symbols.
5686 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5687 if (ResTy != MatchOperand_NoMatch)
5690 // Integers and expressions are acceptable
5691 const MCExpr *Expr = nullptr;
5692 if (Parser.parseExpression(Expr)) {
5693 // We have no way of knowing if a symbol was consumed so we must ParseFail
5694 return MatchOperand_ParseFail;
5697 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
5698 return MatchOperand_Success;
5701 OperandMatchResultTy
5702 MipsAsmParser::parseInvNum(OperandVector &Operands) {
5703 MCAsmParser &Parser = getParser();
5704 const MCExpr *IdVal;
5705 // If the first token is '$' we may have register operand.
5706 if (Parser.getTok().is(AsmToken::Dollar))
5707 return MatchOperand_NoMatch;
5708 SMLoc S = Parser.getTok().getLoc();
5709 if (getParser().parseExpression(IdVal))
5710 return MatchOperand_ParseFail;
5711 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
5712 assert(MCE && "Unexpected MCExpr type.");
5713 int64_t Val = MCE->getValue();
5714 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5715 Operands.push_back(MipsOperand::CreateImm(
5716 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
5717 return MatchOperand_Success;
5720 OperandMatchResultTy
5721 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
5722 MCAsmParser &Parser = getParser();
5723 SmallVector<unsigned, 10> Regs;
5725 unsigned PrevReg = Mips::NoRegister;
5726 bool RegRange = false;
5727 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5729 if (Parser.getTok().isNot(AsmToken::Dollar))
5730 return MatchOperand_ParseFail;
5732 SMLoc S = Parser.getTok().getLoc();
5733 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
5734 SMLoc E = getLexer().getLoc();
5735 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
5736 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
5738 // Remove last register operand because registers from register range
5739 // should be inserted first.
5740 if ((isGP64bit() && RegNo == Mips::RA_64) ||
5741 (!isGP64bit() && RegNo == Mips::RA)) {
5742 Regs.push_back(RegNo);
5744 unsigned TmpReg = PrevReg + 1;
5745 while (TmpReg <= RegNo) {
5746 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
5747 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
5749 Error(E, "invalid register operand");
5750 return MatchOperand_ParseFail;
5754 Regs.push_back(TmpReg++);
5760 if ((PrevReg == Mips::NoRegister) &&
5761 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5762 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5763 Error(E, "$16 or $31 expected");
5764 return MatchOperand_ParseFail;
5765 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5766 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5768 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5769 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5771 Error(E, "invalid register operand");
5772 return MatchOperand_ParseFail;
5773 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5774 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5775 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5777 Error(E, "consecutive register numbers expected");
5778 return MatchOperand_ParseFail;
5781 Regs.push_back(RegNo);
5784 if (Parser.getTok().is(AsmToken::Minus))
5787 if (!Parser.getTok().isNot(AsmToken::Minus) &&
5788 !Parser.getTok().isNot(AsmToken::Comma)) {
5789 Error(E, "',' or '-' expected");
5790 return MatchOperand_ParseFail;
5793 Lex(); // Consume comma or minus
5794 if (Parser.getTok().isNot(AsmToken::Dollar))
5800 SMLoc E = Parser.getTok().getLoc();
5801 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5802 parseMemOperand(Operands);
5803 return MatchOperand_Success;
5806 OperandMatchResultTy
5807 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
5808 MCAsmParser &Parser = getParser();
5810 SMLoc S = Parser.getTok().getLoc();
5811 if (parseAnyRegister(Operands) != MatchOperand_Success)
5812 return MatchOperand_ParseFail;
5814 SMLoc E = Parser.getTok().getLoc();
5815 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
5817 Operands.pop_back();
5818 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
5819 return MatchOperand_Success;
5822 OperandMatchResultTy
5823 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
5824 MCAsmParser &Parser = getParser();
5825 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5826 SmallVector<unsigned, 10> Regs;
5828 if (Parser.getTok().isNot(AsmToken::Dollar))
5829 return MatchOperand_ParseFail;
5831 SMLoc S = Parser.getTok().getLoc();
5833 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5834 return MatchOperand_ParseFail;
5836 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5837 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5838 Regs.push_back(RegNo);
5840 SMLoc E = Parser.getTok().getLoc();
5841 if (Parser.getTok().isNot(AsmToken::Comma)) {
5842 Error(E, "',' expected");
5843 return MatchOperand_ParseFail;
5849 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5850 return MatchOperand_ParseFail;
5852 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5853 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5854 Regs.push_back(RegNo);
5856 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5858 return MatchOperand_Success;
5861 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
5863 /// ::= '(', register, ')'
5864 /// handle it before we iterate so we don't get tripped up by the lack of
5866 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
5867 MCAsmParser &Parser = getParser();
5868 if (getLexer().is(AsmToken::LParen)) {
5870 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
5872 if (parseOperand(Operands, Name)) {
5873 SMLoc Loc = getLexer().getLoc();
5874 return Error(Loc, "unexpected token in argument list");
5876 if (Parser.getTok().isNot(AsmToken::RParen)) {
5877 SMLoc Loc = getLexer().getLoc();
5878 return Error(Loc, "unexpected token, expected ')'");
5881 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
5887 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
5888 /// either one of these.
5889 /// ::= '[', register, ']'
5890 /// ::= '[', integer, ']'
5891 /// handle it before we iterate so we don't get tripped up by the lack of
5893 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
5894 OperandVector &Operands) {
5895 MCAsmParser &Parser = getParser();
5896 if (getLexer().is(AsmToken::LBrac)) {
5898 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
5900 if (parseOperand(Operands, Name)) {
5901 SMLoc Loc = getLexer().getLoc();
5902 return Error(Loc, "unexpected token in argument list");
5904 if (Parser.getTok().isNot(AsmToken::RBrac)) {
5905 SMLoc Loc = getLexer().getLoc();
5906 return Error(Loc, "unexpected token, expected ']'");
5909 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
5915 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
5916 SMLoc NameLoc, OperandVector &Operands) {
5917 MCAsmParser &Parser = getParser();
5918 DEBUG(dbgs() << "ParseInstruction\n");
5920 // We have reached first instruction, module directive are now forbidden.
5921 getTargetStreamer().forbidModuleDirective();
5923 // Check if we have valid mnemonic
5924 if (!mnemonicIsValid(Name, 0)) {
5925 return Error(NameLoc, "unknown instruction");
5927 // First operand in MCInst is instruction mnemonic.
5928 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
5930 // Read the remaining operands.
5931 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5932 // Read the first operand.
5933 if (parseOperand(Operands, Name)) {
5934 SMLoc Loc = getLexer().getLoc();
5935 return Error(Loc, "unexpected token in argument list");
5937 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
5939 // AFAIK, parenthesis suffixes are never on the first operand
5941 while (getLexer().is(AsmToken::Comma)) {
5942 Parser.Lex(); // Eat the comma.
5943 // Parse and remember the operand.
5944 if (parseOperand(Operands, Name)) {
5945 SMLoc Loc = getLexer().getLoc();
5946 return Error(Loc, "unexpected token in argument list");
5948 // Parse bracket and parenthesis suffixes before we iterate
5949 if (getLexer().is(AsmToken::LBrac)) {
5950 if (parseBracketSuffix(Name, Operands))
5952 } else if (getLexer().is(AsmToken::LParen) &&
5953 parseParenSuffix(Name, Operands))
5957 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5958 SMLoc Loc = getLexer().getLoc();
5959 return Error(Loc, "unexpected token in argument list");
5961 Parser.Lex(); // Consume the EndOfStatement.
5965 // FIXME: Given that these have the same name, these should both be
5966 // consistent on affecting the Parser.
5967 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
5968 SMLoc Loc = getLexer().getLoc();
5969 return Error(Loc, ErrorMsg);
5972 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
5973 return Error(Loc, ErrorMsg);
5976 bool MipsAsmParser::parseSetNoAtDirective() {
5977 MCAsmParser &Parser = getParser();
5978 // Line should look like: ".set noat".
5980 // Set the $at register to $0.
5981 AssemblerOptions.back()->setATRegIndex(0);
5983 Parser.Lex(); // Eat "noat".
5985 // If this is not the end of the statement, report an error.
5986 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5987 reportParseError("unexpected token, expected end of statement");
5991 getTargetStreamer().emitDirectiveSetNoAt();
5992 Parser.Lex(); // Consume the EndOfStatement.
5996 bool MipsAsmParser::parseSetAtDirective() {
5997 // Line can be: ".set at", which sets $at to $1
5998 // or ".set at=$reg", which sets $at to $reg.
5999 MCAsmParser &Parser = getParser();
6000 Parser.Lex(); // Eat "at".
6002 if (getLexer().is(AsmToken::EndOfStatement)) {
6003 // No register was specified, so we set $at to $1.
6004 AssemblerOptions.back()->setATRegIndex(1);
6006 getTargetStreamer().emitDirectiveSetAt();
6007 Parser.Lex(); // Consume the EndOfStatement.
6011 if (getLexer().isNot(AsmToken::Equal)) {
6012 reportParseError("unexpected token, expected equals sign");
6015 Parser.Lex(); // Eat "=".
6017 if (getLexer().isNot(AsmToken::Dollar)) {
6018 if (getLexer().is(AsmToken::EndOfStatement)) {
6019 reportParseError("no register specified");
6022 reportParseError("unexpected token, expected dollar sign '$'");
6026 Parser.Lex(); // Eat "$".
6028 // Find out what "reg" is.
6030 const AsmToken &Reg = Parser.getTok();
6031 if (Reg.is(AsmToken::Identifier)) {
6032 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6033 } else if (Reg.is(AsmToken::Integer)) {
6034 AtRegNo = Reg.getIntVal();
6036 reportParseError("unexpected token, expected identifier or integer");
6040 // Check if $reg is a valid register. If it is, set $at to $reg.
6041 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6042 reportParseError("invalid register");
6045 Parser.Lex(); // Eat "reg".
6047 // If this is not the end of the statement, report an error.
6048 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6049 reportParseError("unexpected token, expected end of statement");
6053 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6055 Parser.Lex(); // Consume the EndOfStatement.
6059 bool MipsAsmParser::parseSetReorderDirective() {
6060 MCAsmParser &Parser = getParser();
6062 // If this is not the end of the statement, report an error.
6063 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6064 reportParseError("unexpected token, expected end of statement");
6067 AssemblerOptions.back()->setReorder();
6068 getTargetStreamer().emitDirectiveSetReorder();
6069 Parser.Lex(); // Consume the EndOfStatement.
6073 bool MipsAsmParser::parseSetNoReorderDirective() {
6074 MCAsmParser &Parser = getParser();
6076 // If this is not the end of the statement, report an error.
6077 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6078 reportParseError("unexpected token, expected end of statement");
6081 AssemblerOptions.back()->setNoReorder();
6082 getTargetStreamer().emitDirectiveSetNoReorder();
6083 Parser.Lex(); // Consume the EndOfStatement.
6087 bool MipsAsmParser::parseSetMacroDirective() {
6088 MCAsmParser &Parser = getParser();
6090 // If this is not the end of the statement, report an error.
6091 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6092 reportParseError("unexpected token, expected end of statement");
6095 AssemblerOptions.back()->setMacro();
6096 getTargetStreamer().emitDirectiveSetMacro();
6097 Parser.Lex(); // Consume the EndOfStatement.
6101 bool MipsAsmParser::parseSetNoMacroDirective() {
6102 MCAsmParser &Parser = getParser();
6104 // If this is not the end of the statement, report an error.
6105 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6106 reportParseError("unexpected token, expected end of statement");
6109 if (AssemblerOptions.back()->isReorder()) {
6110 reportParseError("`noreorder' must be set before `nomacro'");
6113 AssemblerOptions.back()->setNoMacro();
6114 getTargetStreamer().emitDirectiveSetNoMacro();
6115 Parser.Lex(); // Consume the EndOfStatement.
6119 bool MipsAsmParser::parseSetMsaDirective() {
6120 MCAsmParser &Parser = getParser();
6123 // If this is not the end of the statement, report an error.
6124 if (getLexer().isNot(AsmToken::EndOfStatement))
6125 return reportParseError("unexpected token, expected end of statement");
6127 setFeatureBits(Mips::FeatureMSA, "msa");
6128 getTargetStreamer().emitDirectiveSetMsa();
6132 bool MipsAsmParser::parseSetNoMsaDirective() {
6133 MCAsmParser &Parser = getParser();
6136 // If this is not the end of the statement, report an error.
6137 if (getLexer().isNot(AsmToken::EndOfStatement))
6138 return reportParseError("unexpected token, expected end of statement");
6140 clearFeatureBits(Mips::FeatureMSA, "msa");
6141 getTargetStreamer().emitDirectiveSetNoMsa();
6145 bool MipsAsmParser::parseSetNoDspDirective() {
6146 MCAsmParser &Parser = getParser();
6147 Parser.Lex(); // Eat "nodsp".
6149 // If this is not the end of the statement, report an error.
6150 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6151 reportParseError("unexpected token, expected end of statement");
6155 clearFeatureBits(Mips::FeatureDSP, "dsp");
6156 getTargetStreamer().emitDirectiveSetNoDsp();
6160 bool MipsAsmParser::parseSetMips16Directive() {
6161 MCAsmParser &Parser = getParser();
6162 Parser.Lex(); // Eat "mips16".
6164 // If this is not the end of the statement, report an error.
6165 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6166 reportParseError("unexpected token, expected end of statement");
6170 setFeatureBits(Mips::FeatureMips16, "mips16");
6171 getTargetStreamer().emitDirectiveSetMips16();
6172 Parser.Lex(); // Consume the EndOfStatement.
6176 bool MipsAsmParser::parseSetNoMips16Directive() {
6177 MCAsmParser &Parser = getParser();
6178 Parser.Lex(); // Eat "nomips16".
6180 // If this is not the end of the statement, report an error.
6181 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6182 reportParseError("unexpected token, expected end of statement");
6186 clearFeatureBits(Mips::FeatureMips16, "mips16");
6187 getTargetStreamer().emitDirectiveSetNoMips16();
6188 Parser.Lex(); // Consume the EndOfStatement.
6192 bool MipsAsmParser::parseSetFpDirective() {
6193 MCAsmParser &Parser = getParser();
6194 MipsABIFlagsSection::FpABIKind FpAbiVal;
6195 // Line can be: .set fp=32
6198 Parser.Lex(); // Eat fp token
6199 AsmToken Tok = Parser.getTok();
6200 if (Tok.isNot(AsmToken::Equal)) {
6201 reportParseError("unexpected token, expected equals sign '='");
6204 Parser.Lex(); // Eat '=' token.
6205 Tok = Parser.getTok();
6207 if (!parseFpABIValue(FpAbiVal, ".set"))
6210 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6211 reportParseError("unexpected token, expected end of statement");
6214 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6215 Parser.Lex(); // Consume the EndOfStatement.
6219 bool MipsAsmParser::parseSetOddSPRegDirective() {
6220 MCAsmParser &Parser = getParser();
6222 Parser.Lex(); // Eat "oddspreg".
6223 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6224 reportParseError("unexpected token, expected end of statement");
6228 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6229 getTargetStreamer().emitDirectiveSetOddSPReg();
6233 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6234 MCAsmParser &Parser = getParser();
6236 Parser.Lex(); // Eat "nooddspreg".
6237 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6238 reportParseError("unexpected token, expected end of statement");
6242 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6243 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6247 bool MipsAsmParser::parseSetPopDirective() {
6248 MCAsmParser &Parser = getParser();
6249 SMLoc Loc = getLexer().getLoc();
6252 if (getLexer().isNot(AsmToken::EndOfStatement))
6253 return reportParseError("unexpected token, expected end of statement");
6255 // Always keep an element on the options "stack" to prevent the user
6256 // from changing the initial options. This is how we remember them.
6257 if (AssemblerOptions.size() == 2)
6258 return reportParseError(Loc, ".set pop with no .set push");
6260 MCSubtargetInfo &STI = copySTI();
6261 AssemblerOptions.pop_back();
6262 setAvailableFeatures(
6263 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6264 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6266 getTargetStreamer().emitDirectiveSetPop();
6270 bool MipsAsmParser::parseSetPushDirective() {
6271 MCAsmParser &Parser = getParser();
6273 if (getLexer().isNot(AsmToken::EndOfStatement))
6274 return reportParseError("unexpected token, expected end of statement");
6276 // Create a copy of the current assembler options environment and push it.
6277 AssemblerOptions.push_back(
6278 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6280 getTargetStreamer().emitDirectiveSetPush();
6284 bool MipsAsmParser::parseSetSoftFloatDirective() {
6285 MCAsmParser &Parser = getParser();
6287 if (getLexer().isNot(AsmToken::EndOfStatement))
6288 return reportParseError("unexpected token, expected end of statement");
6290 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6291 getTargetStreamer().emitDirectiveSetSoftFloat();
6295 bool MipsAsmParser::parseSetHardFloatDirective() {
6296 MCAsmParser &Parser = getParser();
6298 if (getLexer().isNot(AsmToken::EndOfStatement))
6299 return reportParseError("unexpected token, expected end of statement");
6301 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6302 getTargetStreamer().emitDirectiveSetHardFloat();
6306 bool MipsAsmParser::parseSetAssignment() {
6308 const MCExpr *Value;
6309 MCAsmParser &Parser = getParser();
6311 if (Parser.parseIdentifier(Name))
6312 reportParseError("expected identifier after .set");
6314 if (getLexer().isNot(AsmToken::Comma))
6315 return reportParseError("unexpected token, expected comma");
6318 if (Parser.parseExpression(Value))
6319 return reportParseError("expected valid expression after comma");
6321 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6322 Sym->setVariableValue(Value);
6327 bool MipsAsmParser::parseSetMips0Directive() {
6328 MCAsmParser &Parser = getParser();
6330 if (getLexer().isNot(AsmToken::EndOfStatement))
6331 return reportParseError("unexpected token, expected end of statement");
6333 // Reset assembler options to their initial values.
6334 MCSubtargetInfo &STI = copySTI();
6335 setAvailableFeatures(
6336 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6337 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6338 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6340 getTargetStreamer().emitDirectiveSetMips0();
6344 bool MipsAsmParser::parseSetArchDirective() {
6345 MCAsmParser &Parser = getParser();
6347 if (getLexer().isNot(AsmToken::Equal))
6348 return reportParseError("unexpected token, expected equals sign");
6352 if (Parser.parseIdentifier(Arch))
6353 return reportParseError("expected arch identifier");
6355 StringRef ArchFeatureName =
6356 StringSwitch<StringRef>(Arch)
6357 .Case("mips1", "mips1")
6358 .Case("mips2", "mips2")
6359 .Case("mips3", "mips3")
6360 .Case("mips4", "mips4")
6361 .Case("mips5", "mips5")
6362 .Case("mips32", "mips32")
6363 .Case("mips32r2", "mips32r2")
6364 .Case("mips32r3", "mips32r3")
6365 .Case("mips32r5", "mips32r5")
6366 .Case("mips32r6", "mips32r6")
6367 .Case("mips64", "mips64")
6368 .Case("mips64r2", "mips64r2")
6369 .Case("mips64r3", "mips64r3")
6370 .Case("mips64r5", "mips64r5")
6371 .Case("mips64r6", "mips64r6")
6372 .Case("octeon", "cnmips")
6373 .Case("r4000", "mips3") // This is an implementation of Mips3.
6376 if (ArchFeatureName.empty())
6377 return reportParseError("unsupported architecture");
6379 selectArch(ArchFeatureName);
6380 getTargetStreamer().emitDirectiveSetArch(Arch);
6384 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6385 MCAsmParser &Parser = getParser();
6387 if (getLexer().isNot(AsmToken::EndOfStatement))
6388 return reportParseError("unexpected token, expected end of statement");
6392 llvm_unreachable("Unimplemented feature");
6393 case Mips::FeatureDSP:
6394 setFeatureBits(Mips::FeatureDSP, "dsp");
6395 getTargetStreamer().emitDirectiveSetDsp();
6397 case Mips::FeatureMicroMips:
6398 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6399 getTargetStreamer().emitDirectiveSetMicroMips();
6401 case Mips::FeatureMips1:
6402 selectArch("mips1");
6403 getTargetStreamer().emitDirectiveSetMips1();
6405 case Mips::FeatureMips2:
6406 selectArch("mips2");
6407 getTargetStreamer().emitDirectiveSetMips2();
6409 case Mips::FeatureMips3:
6410 selectArch("mips3");
6411 getTargetStreamer().emitDirectiveSetMips3();
6413 case Mips::FeatureMips4:
6414 selectArch("mips4");
6415 getTargetStreamer().emitDirectiveSetMips4();
6417 case Mips::FeatureMips5:
6418 selectArch("mips5");
6419 getTargetStreamer().emitDirectiveSetMips5();
6421 case Mips::FeatureMips32:
6422 selectArch("mips32");
6423 getTargetStreamer().emitDirectiveSetMips32();
6425 case Mips::FeatureMips32r2:
6426 selectArch("mips32r2");
6427 getTargetStreamer().emitDirectiveSetMips32R2();
6429 case Mips::FeatureMips32r3:
6430 selectArch("mips32r3");
6431 getTargetStreamer().emitDirectiveSetMips32R3();
6433 case Mips::FeatureMips32r5:
6434 selectArch("mips32r5");
6435 getTargetStreamer().emitDirectiveSetMips32R5();
6437 case Mips::FeatureMips32r6:
6438 selectArch("mips32r6");
6439 getTargetStreamer().emitDirectiveSetMips32R6();
6441 case Mips::FeatureMips64:
6442 selectArch("mips64");
6443 getTargetStreamer().emitDirectiveSetMips64();
6445 case Mips::FeatureMips64r2:
6446 selectArch("mips64r2");
6447 getTargetStreamer().emitDirectiveSetMips64R2();
6449 case Mips::FeatureMips64r3:
6450 selectArch("mips64r3");
6451 getTargetStreamer().emitDirectiveSetMips64R3();
6453 case Mips::FeatureMips64r5:
6454 selectArch("mips64r5");
6455 getTargetStreamer().emitDirectiveSetMips64R5();
6457 case Mips::FeatureMips64r6:
6458 selectArch("mips64r6");
6459 getTargetStreamer().emitDirectiveSetMips64R6();
6465 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6466 MCAsmParser &Parser = getParser();
6467 if (getLexer().isNot(AsmToken::Comma)) {
6468 SMLoc Loc = getLexer().getLoc();
6469 return Error(Loc, ErrorStr);
6472 Parser.Lex(); // Eat the comma.
6476 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
6477 // In this class, it is only used for .cprestore.
6478 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
6479 // MipsTargetELFStreamer and MipsAsmParser.
6480 bool MipsAsmParser::isPicAndNotNxxAbi() {
6481 return inPicMode() && !(isABI_N32() || isABI_N64());
6484 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
6485 if (AssemblerOptions.back()->isReorder())
6486 Warning(Loc, ".cpload should be inside a noreorder section");
6488 if (inMips16Mode()) {
6489 reportParseError(".cpload is not supported in Mips16 mode");
6493 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
6494 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
6495 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6496 reportParseError("expected register containing function address");
6500 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
6501 if (!RegOpnd.isGPRAsmReg()) {
6502 reportParseError(RegOpnd.getStartLoc(), "invalid register");
6506 // If this is not the end of the statement, report an error.
6507 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6508 reportParseError("unexpected token, expected end of statement");
6512 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
6516 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
6517 MCAsmParser &Parser = getParser();
6519 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
6520 // is used in non-PIC mode.
6522 if (inMips16Mode()) {
6523 reportParseError(".cprestore is not supported in Mips16 mode");
6527 // Get the stack offset value.
6528 const MCExpr *StackOffset;
6529 int64_t StackOffsetVal;
6530 if (Parser.parseExpression(StackOffset)) {
6531 reportParseError("expected stack offset value");
6535 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
6536 reportParseError("stack offset is not an absolute expression");
6540 if (StackOffsetVal < 0) {
6541 Warning(Loc, ".cprestore with negative stack offset has no effect");
6542 IsCpRestoreSet = false;
6544 IsCpRestoreSet = true;
6545 CpRestoreOffset = StackOffsetVal;
6548 // If this is not the end of the statement, report an error.
6549 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6550 reportParseError("unexpected token, expected end of statement");
6554 if (!getTargetStreamer().emitDirectiveCpRestore(
6555 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
6557 Parser.Lex(); // Consume the EndOfStatement.
6561 bool MipsAsmParser::parseDirectiveCPSetup() {
6562 MCAsmParser &Parser = getParser();
6565 bool SaveIsReg = true;
6567 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6568 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6569 if (ResTy == MatchOperand_NoMatch) {
6570 reportParseError("expected register containing function address");
6574 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6575 if (!FuncRegOpnd.isGPRAsmReg()) {
6576 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
6580 FuncReg = FuncRegOpnd.getGPR32Reg();
6583 if (!eatComma("unexpected token, expected comma"))
6586 ResTy = parseAnyRegister(TmpReg);
6587 if (ResTy == MatchOperand_NoMatch) {
6588 const MCExpr *OffsetExpr;
6590 SMLoc ExprLoc = getLexer().getLoc();
6592 if (Parser.parseExpression(OffsetExpr) ||
6593 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
6594 reportParseError(ExprLoc, "expected save register or stack offset");
6601 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6602 if (!SaveOpnd.isGPRAsmReg()) {
6603 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
6606 Save = SaveOpnd.getGPR32Reg();
6609 if (!eatComma("unexpected token, expected comma"))
6613 if (Parser.parseExpression(Expr)) {
6614 reportParseError("expected expression");
6618 if (Expr->getKind() != MCExpr::SymbolRef) {
6619 reportParseError("expected symbol");
6622 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6624 CpSaveLocation = Save;
6625 CpSaveLocationIsRegister = SaveIsReg;
6627 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
6632 bool MipsAsmParser::parseDirectiveCPReturn() {
6633 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
6634 CpSaveLocationIsRegister);
6638 bool MipsAsmParser::parseDirectiveNaN() {
6639 MCAsmParser &Parser = getParser();
6640 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6641 const AsmToken &Tok = Parser.getTok();
6643 if (Tok.getString() == "2008") {
6645 getTargetStreamer().emitDirectiveNaN2008();
6647 } else if (Tok.getString() == "legacy") {
6649 getTargetStreamer().emitDirectiveNaNLegacy();
6653 // If we don't recognize the option passed to the .nan
6654 // directive (e.g. no option or unknown option), emit an error.
6655 reportParseError("invalid option in .nan directive");
6659 bool MipsAsmParser::parseDirectiveSet() {
6660 MCAsmParser &Parser = getParser();
6661 // Get the next token.
6662 const AsmToken &Tok = Parser.getTok();
6664 if (Tok.getString() == "noat") {
6665 return parseSetNoAtDirective();
6666 } else if (Tok.getString() == "at") {
6667 return parseSetAtDirective();
6668 } else if (Tok.getString() == "arch") {
6669 return parseSetArchDirective();
6670 } else if (Tok.getString() == "bopt") {
6671 Warning(Tok.getLoc(), "'bopt' feature is unsupported");
6674 } else if (Tok.getString() == "nobopt") {
6675 // We're already running in nobopt mode, so nothing to do.
6678 } else if (Tok.getString() == "fp") {
6679 return parseSetFpDirective();
6680 } else if (Tok.getString() == "oddspreg") {
6681 return parseSetOddSPRegDirective();
6682 } else if (Tok.getString() == "nooddspreg") {
6683 return parseSetNoOddSPRegDirective();
6684 } else if (Tok.getString() == "pop") {
6685 return parseSetPopDirective();
6686 } else if (Tok.getString() == "push") {
6687 return parseSetPushDirective();
6688 } else if (Tok.getString() == "reorder") {
6689 return parseSetReorderDirective();
6690 } else if (Tok.getString() == "noreorder") {
6691 return parseSetNoReorderDirective();
6692 } else if (Tok.getString() == "macro") {
6693 return parseSetMacroDirective();
6694 } else if (Tok.getString() == "nomacro") {
6695 return parseSetNoMacroDirective();
6696 } else if (Tok.getString() == "mips16") {
6697 return parseSetMips16Directive();
6698 } else if (Tok.getString() == "nomips16") {
6699 return parseSetNoMips16Directive();
6700 } else if (Tok.getString() == "nomicromips") {
6701 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
6702 getTargetStreamer().emitDirectiveSetNoMicroMips();
6703 Parser.eatToEndOfStatement();
6705 } else if (Tok.getString() == "micromips") {
6706 return parseSetFeature(Mips::FeatureMicroMips);
6707 } else if (Tok.getString() == "mips0") {
6708 return parseSetMips0Directive();
6709 } else if (Tok.getString() == "mips1") {
6710 return parseSetFeature(Mips::FeatureMips1);
6711 } else if (Tok.getString() == "mips2") {
6712 return parseSetFeature(Mips::FeatureMips2);
6713 } else if (Tok.getString() == "mips3") {
6714 return parseSetFeature(Mips::FeatureMips3);
6715 } else if (Tok.getString() == "mips4") {
6716 return parseSetFeature(Mips::FeatureMips4);
6717 } else if (Tok.getString() == "mips5") {
6718 return parseSetFeature(Mips::FeatureMips5);
6719 } else if (Tok.getString() == "mips32") {
6720 return parseSetFeature(Mips::FeatureMips32);
6721 } else if (Tok.getString() == "mips32r2") {
6722 return parseSetFeature(Mips::FeatureMips32r2);
6723 } else if (Tok.getString() == "mips32r3") {
6724 return parseSetFeature(Mips::FeatureMips32r3);
6725 } else if (Tok.getString() == "mips32r5") {
6726 return parseSetFeature(Mips::FeatureMips32r5);
6727 } else if (Tok.getString() == "mips32r6") {
6728 return parseSetFeature(Mips::FeatureMips32r6);
6729 } else if (Tok.getString() == "mips64") {
6730 return parseSetFeature(Mips::FeatureMips64);
6731 } else if (Tok.getString() == "mips64r2") {
6732 return parseSetFeature(Mips::FeatureMips64r2);
6733 } else if (Tok.getString() == "mips64r3") {
6734 return parseSetFeature(Mips::FeatureMips64r3);
6735 } else if (Tok.getString() == "mips64r5") {
6736 return parseSetFeature(Mips::FeatureMips64r5);
6737 } else if (Tok.getString() == "mips64r6") {
6738 return parseSetFeature(Mips::FeatureMips64r6);
6739 } else if (Tok.getString() == "dsp") {
6740 return parseSetFeature(Mips::FeatureDSP);
6741 } else if (Tok.getString() == "nodsp") {
6742 return parseSetNoDspDirective();
6743 } else if (Tok.getString() == "msa") {
6744 return parseSetMsaDirective();
6745 } else if (Tok.getString() == "nomsa") {
6746 return parseSetNoMsaDirective();
6747 } else if (Tok.getString() == "softfloat") {
6748 return parseSetSoftFloatDirective();
6749 } else if (Tok.getString() == "hardfloat") {
6750 return parseSetHardFloatDirective();
6752 // It is just an identifier, look for an assignment.
6753 parseSetAssignment();
6760 /// parseDataDirective
6761 /// ::= .word [ expression (, expression)* ]
6762 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
6763 MCAsmParser &Parser = getParser();
6764 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6766 const MCExpr *Value;
6767 if (getParser().parseExpression(Value))
6770 getParser().getStreamer().EmitValue(Value, Size);
6772 if (getLexer().is(AsmToken::EndOfStatement))
6775 if (getLexer().isNot(AsmToken::Comma))
6776 return Error(L, "unexpected token, expected comma");
6785 /// parseDirectiveGpWord
6786 /// ::= .gpword local_sym
6787 bool MipsAsmParser::parseDirectiveGpWord() {
6788 MCAsmParser &Parser = getParser();
6789 const MCExpr *Value;
6790 // EmitGPRel32Value requires an expression, so we are using base class
6791 // method to evaluate the expression.
6792 if (getParser().parseExpression(Value))
6794 getParser().getStreamer().EmitGPRel32Value(Value);
6796 if (getLexer().isNot(AsmToken::EndOfStatement))
6797 return Error(getLexer().getLoc(),
6798 "unexpected token, expected end of statement");
6799 Parser.Lex(); // Eat EndOfStatement token.
6803 /// parseDirectiveGpDWord
6804 /// ::= .gpdword local_sym
6805 bool MipsAsmParser::parseDirectiveGpDWord() {
6806 MCAsmParser &Parser = getParser();
6807 const MCExpr *Value;
6808 // EmitGPRel64Value requires an expression, so we are using base class
6809 // method to evaluate the expression.
6810 if (getParser().parseExpression(Value))
6812 getParser().getStreamer().EmitGPRel64Value(Value);
6814 if (getLexer().isNot(AsmToken::EndOfStatement))
6815 return Error(getLexer().getLoc(),
6816 "unexpected token, expected end of statement");
6817 Parser.Lex(); // Eat EndOfStatement token.
6821 /// parseDirectiveDtpRelWord
6822 /// ::= .dtprelword tls_sym
6823 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6824 MCAsmParser &Parser = getParser();
6825 const MCExpr *Value;
6826 // EmitDTPRel32Value requires an expression, so we are using base class
6827 // method to evaluate the expression.
6828 if (getParser().parseExpression(Value))
6830 getParser().getStreamer().EmitDTPRel32Value(Value);
6832 if (getLexer().isNot(AsmToken::EndOfStatement))
6833 return Error(getLexer().getLoc(),
6834 "unexpected token, expected end of statement");
6835 Parser.Lex(); // Eat EndOfStatement token.
6839 /// parseDirectiveDtpRelDWord
6840 /// ::= .dtpreldword tls_sym
6841 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6842 MCAsmParser &Parser = getParser();
6843 const MCExpr *Value;
6844 // EmitDTPRel64Value requires an expression, so we are using base class
6845 // method to evaluate the expression.
6846 if (getParser().parseExpression(Value))
6848 getParser().getStreamer().EmitDTPRel64Value(Value);
6850 if (getLexer().isNot(AsmToken::EndOfStatement))
6851 return Error(getLexer().getLoc(),
6852 "unexpected token, expected end of statement");
6853 Parser.Lex(); // Eat EndOfStatement token.
6857 /// parseDirectiveTpRelWord
6858 /// ::= .tprelword tls_sym
6859 bool MipsAsmParser::parseDirectiveTpRelWord() {
6860 MCAsmParser &Parser = getParser();
6861 const MCExpr *Value;
6862 // EmitTPRel32Value requires an expression, so we are using base class
6863 // method to evaluate the expression.
6864 if (getParser().parseExpression(Value))
6866 getParser().getStreamer().EmitTPRel32Value(Value);
6868 if (getLexer().isNot(AsmToken::EndOfStatement))
6869 return Error(getLexer().getLoc(),
6870 "unexpected token, expected end of statement");
6871 Parser.Lex(); // Eat EndOfStatement token.
6875 /// parseDirectiveTpRelDWord
6876 /// ::= .tpreldword tls_sym
6877 bool MipsAsmParser::parseDirectiveTpRelDWord() {
6878 MCAsmParser &Parser = getParser();
6879 const MCExpr *Value;
6880 // EmitTPRel64Value requires an expression, so we are using base class
6881 // method to evaluate the expression.
6882 if (getParser().parseExpression(Value))
6884 getParser().getStreamer().EmitTPRel64Value(Value);
6886 if (getLexer().isNot(AsmToken::EndOfStatement))
6887 return Error(getLexer().getLoc(),
6888 "unexpected token, expected end of statement");
6889 Parser.Lex(); // Eat EndOfStatement token.
6893 bool MipsAsmParser::parseDirectiveOption() {
6894 MCAsmParser &Parser = getParser();
6895 // Get the option token.
6896 AsmToken Tok = Parser.getTok();
6897 // At the moment only identifiers are supported.
6898 if (Tok.isNot(AsmToken::Identifier)) {
6899 return Error(Parser.getTok().getLoc(),
6900 "unexpected token, expected identifier");
6903 StringRef Option = Tok.getIdentifier();
6905 if (Option == "pic0") {
6906 // MipsAsmParser needs to know if the current PIC mode changes.
6907 IsPicEnabled = false;
6909 getTargetStreamer().emitDirectiveOptionPic0();
6911 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6912 return Error(Parser.getTok().getLoc(),
6913 "unexpected token, expected end of statement");
6918 if (Option == "pic2") {
6919 // MipsAsmParser needs to know if the current PIC mode changes.
6920 IsPicEnabled = true;
6922 getTargetStreamer().emitDirectiveOptionPic2();
6924 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6925 return Error(Parser.getTok().getLoc(),
6926 "unexpected token, expected end of statement");
6932 Warning(Parser.getTok().getLoc(),
6933 "unknown option, expected 'pic0' or 'pic2'");
6934 Parser.eatToEndOfStatement();
6938 /// parseInsnDirective
6940 bool MipsAsmParser::parseInsnDirective() {
6941 // If this is not the end of the statement, report an error.
6942 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6943 reportParseError("unexpected token, expected end of statement");
6947 // The actual label marking happens in
6948 // MipsELFStreamer::createPendingLabelRelocs().
6949 getTargetStreamer().emitDirectiveInsn();
6951 getParser().Lex(); // Eat EndOfStatement token.
6955 /// parseSSectionDirective
6958 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
6959 // If this is not the end of the statement, report an error.
6960 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6961 reportParseError("unexpected token, expected end of statement");
6965 MCSection *ELFSection = getContext().getELFSection(
6966 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
6967 getParser().getStreamer().SwitchSection(ELFSection);
6969 getParser().Lex(); // Eat EndOfStatement token.
6973 /// parseDirectiveModule
6974 /// ::= .module oddspreg
6975 /// ::= .module nooddspreg
6976 /// ::= .module fp=value
6977 /// ::= .module softfloat
6978 /// ::= .module hardfloat
6979 bool MipsAsmParser::parseDirectiveModule() {
6980 MCAsmParser &Parser = getParser();
6981 MCAsmLexer &Lexer = getLexer();
6982 SMLoc L = Lexer.getLoc();
6984 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
6985 // TODO : get a better message.
6986 reportParseError(".module directive must appear before any code");
6991 if (Parser.parseIdentifier(Option)) {
6992 reportParseError("expected .module option identifier");
6996 if (Option == "oddspreg") {
6997 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6999 // Synchronize the abiflags information with the FeatureBits information we
7001 getTargetStreamer().updateABIInfo(*this);
7003 // If printing assembly, use the recently updated abiflags information.
7004 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7005 // emitted at the end).
7006 getTargetStreamer().emitDirectiveModuleOddSPReg();
7008 // If this is not the end of the statement, report an error.
7009 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7010 reportParseError("unexpected token, expected end of statement");
7014 return false; // parseDirectiveModule has finished successfully.
7015 } else if (Option == "nooddspreg") {
7017 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7020 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7022 // Synchronize the abiflags information with the FeatureBits information we
7024 getTargetStreamer().updateABIInfo(*this);
7026 // If printing assembly, use the recently updated abiflags information.
7027 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7028 // emitted at the end).
7029 getTargetStreamer().emitDirectiveModuleOddSPReg();
7031 // If this is not the end of the statement, report an error.
7032 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7033 reportParseError("unexpected token, expected end of statement");
7037 return false; // parseDirectiveModule has finished successfully.
7038 } else if (Option == "fp") {
7039 return parseDirectiveModuleFP();
7040 } else if (Option == "softfloat") {
7041 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7043 // Synchronize the ABI Flags information with the FeatureBits information we
7045 getTargetStreamer().updateABIInfo(*this);
7047 // If printing assembly, use the recently updated ABI Flags information.
7048 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7050 getTargetStreamer().emitDirectiveModuleSoftFloat();
7052 // If this is not the end of the statement, report an error.
7053 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7054 reportParseError("unexpected token, expected end of statement");
7058 return false; // parseDirectiveModule has finished successfully.
7059 } else if (Option == "hardfloat") {
7060 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7062 // Synchronize the ABI Flags information with the FeatureBits information we
7064 getTargetStreamer().updateABIInfo(*this);
7066 // If printing assembly, use the recently updated ABI Flags information.
7067 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7069 getTargetStreamer().emitDirectiveModuleHardFloat();
7071 // If this is not the end of the statement, report an error.
7072 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7073 reportParseError("unexpected token, expected end of statement");
7077 return false; // parseDirectiveModule has finished successfully.
7079 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7083 /// parseDirectiveModuleFP
7087 bool MipsAsmParser::parseDirectiveModuleFP() {
7088 MCAsmParser &Parser = getParser();
7089 MCAsmLexer &Lexer = getLexer();
7091 if (Lexer.isNot(AsmToken::Equal)) {
7092 reportParseError("unexpected token, expected equals sign '='");
7095 Parser.Lex(); // Eat '=' token.
7097 MipsABIFlagsSection::FpABIKind FpABI;
7098 if (!parseFpABIValue(FpABI, ".module"))
7101 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7102 reportParseError("unexpected token, expected end of statement");
7106 // Synchronize the abiflags information with the FeatureBits information we
7108 getTargetStreamer().updateABIInfo(*this);
7110 // If printing assembly, use the recently updated abiflags information.
7111 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7112 // emitted at the end).
7113 getTargetStreamer().emitDirectiveModuleFP();
7115 Parser.Lex(); // Consume the EndOfStatement.
7119 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7120 StringRef Directive) {
7121 MCAsmParser &Parser = getParser();
7122 MCAsmLexer &Lexer = getLexer();
7123 bool ModuleLevelOptions = Directive == ".module";
7125 if (Lexer.is(AsmToken::Identifier)) {
7126 StringRef Value = Parser.getTok().getString();
7129 if (Value != "xx") {
7130 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7135 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7139 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7140 if (ModuleLevelOptions) {
7141 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7142 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7144 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7145 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7150 if (Lexer.is(AsmToken::Integer)) {
7151 unsigned Value = Parser.getTok().getIntVal();
7154 if (Value != 32 && Value != 64) {
7155 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7161 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7165 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7166 if (ModuleLevelOptions) {
7167 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7168 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7170 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7171 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7174 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7175 if (ModuleLevelOptions) {
7176 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7177 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7179 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7180 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7190 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7191 // This returns false if this function recognizes the directive
7192 // regardless of whether it is successfully handles or reports an
7193 // error. Otherwise it returns true to give the generic parser a
7194 // chance at recognizing it.
7196 MCAsmParser &Parser = getParser();
7197 StringRef IDVal = DirectiveID.getString();
7199 if (IDVal == ".cpload") {
7200 parseDirectiveCpLoad(DirectiveID.getLoc());
7203 if (IDVal == ".cprestore") {
7204 parseDirectiveCpRestore(DirectiveID.getLoc());
7207 if (IDVal == ".dword") {
7208 parseDataDirective(8, DirectiveID.getLoc());
7211 if (IDVal == ".ent") {
7212 StringRef SymbolName;
7214 if (Parser.parseIdentifier(SymbolName)) {
7215 reportParseError("expected identifier after .ent");
7219 // There's an undocumented extension that allows an integer to
7220 // follow the name of the procedure which AFAICS is ignored by GAS.
7221 // Example: .ent foo,2
7222 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7223 if (getLexer().isNot(AsmToken::Comma)) {
7224 // Even though we accept this undocumented extension for compatibility
7225 // reasons, the additional integer argument does not actually change
7226 // the behaviour of the '.ent' directive, so we would like to discourage
7227 // its use. We do this by not referring to the extended version in
7228 // error messages which are not directly related to its use.
7229 reportParseError("unexpected token, expected end of statement");
7232 Parser.Lex(); // Eat the comma.
7233 const MCExpr *DummyNumber;
7234 int64_t DummyNumberVal;
7235 // If the user was explicitly trying to use the extended version,
7236 // we still give helpful extension-related error messages.
7237 if (Parser.parseExpression(DummyNumber)) {
7238 reportParseError("expected number after comma");
7241 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7242 reportParseError("expected an absolute expression after comma");
7247 // If this is not the end of the statement, report an error.
7248 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7249 reportParseError("unexpected token, expected end of statement");
7253 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7255 getTargetStreamer().emitDirectiveEnt(*Sym);
7257 IsCpRestoreSet = false;
7261 if (IDVal == ".end") {
7262 StringRef SymbolName;
7264 if (Parser.parseIdentifier(SymbolName)) {
7265 reportParseError("expected identifier after .end");
7269 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7270 reportParseError("unexpected token, expected end of statement");
7274 if (CurrentFn == nullptr) {
7275 reportParseError(".end used without .ent");
7279 if ((SymbolName != CurrentFn->getName())) {
7280 reportParseError(".end symbol does not match .ent symbol");
7284 getTargetStreamer().emitDirectiveEnd(SymbolName);
7285 CurrentFn = nullptr;
7286 IsCpRestoreSet = false;
7290 if (IDVal == ".frame") {
7291 // .frame $stack_reg, frame_size_in_bytes, $return_reg
7292 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7293 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7294 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7295 reportParseError("expected stack register");
7299 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7300 if (!StackRegOpnd.isGPRAsmReg()) {
7301 reportParseError(StackRegOpnd.getStartLoc(),
7302 "expected general purpose register");
7305 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7307 if (Parser.getTok().is(AsmToken::Comma))
7310 reportParseError("unexpected token, expected comma");
7314 // Parse the frame size.
7315 const MCExpr *FrameSize;
7316 int64_t FrameSizeVal;
7318 if (Parser.parseExpression(FrameSize)) {
7319 reportParseError("expected frame size value");
7323 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
7324 reportParseError("frame size not an absolute expression");
7328 if (Parser.getTok().is(AsmToken::Comma))
7331 reportParseError("unexpected token, expected comma");
7335 // Parse the return register.
7337 ResTy = parseAnyRegister(TmpReg);
7338 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7339 reportParseError("expected return register");
7343 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7344 if (!ReturnRegOpnd.isGPRAsmReg()) {
7345 reportParseError(ReturnRegOpnd.getStartLoc(),
7346 "expected general purpose register");
7350 // If this is not the end of the statement, report an error.
7351 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7352 reportParseError("unexpected token, expected end of statement");
7356 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
7357 ReturnRegOpnd.getGPR32Reg());
7358 IsCpRestoreSet = false;
7362 if (IDVal == ".set") {
7363 parseDirectiveSet();
7367 if (IDVal == ".mask" || IDVal == ".fmask") {
7368 // .mask bitmask, frame_offset
7369 // bitmask: One bit for each register used.
7370 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
7371 // first register is expected to be saved.
7373 // .mask 0x80000000, -4
7374 // .fmask 0x80000000, -4
7377 // Parse the bitmask
7378 const MCExpr *BitMask;
7381 if (Parser.parseExpression(BitMask)) {
7382 reportParseError("expected bitmask value");
7386 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
7387 reportParseError("bitmask not an absolute expression");
7391 if (Parser.getTok().is(AsmToken::Comma))
7394 reportParseError("unexpected token, expected comma");
7398 // Parse the frame_offset
7399 const MCExpr *FrameOffset;
7400 int64_t FrameOffsetVal;
7402 if (Parser.parseExpression(FrameOffset)) {
7403 reportParseError("expected frame offset value");
7407 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
7408 reportParseError("frame offset not an absolute expression");
7412 // If this is not the end of the statement, report an error.
7413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7414 reportParseError("unexpected token, expected end of statement");
7418 if (IDVal == ".mask")
7419 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
7421 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
7425 if (IDVal == ".nan")
7426 return parseDirectiveNaN();
7428 if (IDVal == ".gpword") {
7429 parseDirectiveGpWord();
7433 if (IDVal == ".gpdword") {
7434 parseDirectiveGpDWord();
7438 if (IDVal == ".dtprelword") {
7439 parseDirectiveDtpRelWord();
7443 if (IDVal == ".dtpreldword") {
7444 parseDirectiveDtpRelDWord();
7448 if (IDVal == ".tprelword") {
7449 parseDirectiveTpRelWord();
7453 if (IDVal == ".tpreldword") {
7454 parseDirectiveTpRelDWord();
7458 if (IDVal == ".word") {
7459 parseDataDirective(4, DirectiveID.getLoc());
7463 if (IDVal == ".hword") {
7464 parseDataDirective(2, DirectiveID.getLoc());
7468 if (IDVal == ".option") {
7469 parseDirectiveOption();
7473 if (IDVal == ".abicalls") {
7474 getTargetStreamer().emitDirectiveAbiCalls();
7475 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7476 Error(Parser.getTok().getLoc(),
7477 "unexpected token, expected end of statement");
7482 if (IDVal == ".cpsetup") {
7483 parseDirectiveCPSetup();
7486 if (IDVal == ".cpreturn") {
7487 parseDirectiveCPReturn();
7490 if (IDVal == ".module") {
7491 parseDirectiveModule();
7494 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
7495 parseInternalDirectiveReallowModule();
7498 if (IDVal == ".insn") {
7499 parseInsnDirective();
7502 if (IDVal == ".sbss") {
7503 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
7506 if (IDVal == ".sdata") {
7507 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
7514 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
7515 // If this is not the end of the statement, report an error.
7516 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7517 reportParseError("unexpected token, expected end of statement");
7521 getTargetStreamer().reallowModuleDirective();
7523 getParser().Lex(); // Eat EndOfStatement token.
7527 extern "C" void LLVMInitializeMipsAsmParser() {
7528 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
7529 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
7530 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
7531 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
7534 #define GET_REGISTER_MATCHER
7535 #define GET_MATCHER_IMPLEMENTATION
7536 #include "MipsGenAsmMatcher.inc"
7538 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
7539 // Find the appropriate table for this asm variant.
7540 const MatchEntry *Start, *End;
7541 switch (VariantID) {
7542 default: llvm_unreachable("invalid variant!");
7543 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
7545 // Search the table.
7546 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
7547 return MnemonicRange.first != MnemonicRange.second;