1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIFlagsSection.h"
11 #include "MCTargetDesc/MipsABIInfo.h"
12 #include "MCTargetDesc/MipsBaseInfo.h"
13 #include "MCTargetDesc/MipsMCExpr.h"
14 #include "MCTargetDesc/MipsMCTargetDesc.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCAsmParser.h"
31 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/SubtargetFeature.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/Compiler.h"
43 #include "llvm/Support/Debug.h"
44 #include "llvm/Support/ErrorHandling.h"
45 #include "llvm/Support/MathExtras.h"
46 #include "llvm/Support/SMLoc.h"
47 #include "llvm/Support/SourceMgr.h"
48 #include "llvm/Support/TargetRegistry.h"
49 #include "llvm/Support/raw_ostream.h"
59 #define DEBUG_TYPE "mips-asm-parser"
65 } // end namespace llvm
69 class MipsAssemblerOptions {
71 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
73 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
74 ATReg = Opts->getATRegIndex();
75 Reorder = Opts->isReorder();
76 Macro = Opts->isMacro();
77 Features = Opts->getFeatures();
80 unsigned getATRegIndex() const { return ATReg; }
81 bool setATRegIndex(unsigned Reg) {
89 bool isReorder() const { return Reorder; }
90 void setReorder() { Reorder = true; }
91 void setNoReorder() { Reorder = false; }
93 bool isMacro() const { return Macro; }
94 void setMacro() { Macro = true; }
95 void setNoMacro() { Macro = false; }
97 const FeatureBitset &getFeatures() const { return Features; }
98 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
100 // Set of features that are either architecture features or referenced
101 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
102 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
103 // The reason we need this mask is explained in the selectArch function.
104 // FIXME: Ideally we would like TableGen to generate this information.
105 static const FeatureBitset AllArchRelatedMask;
111 FeatureBitset Features;
114 } // end anonymous namespace
116 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
117 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
118 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
119 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
120 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
121 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
122 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
123 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
124 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
129 class MipsAsmParser : public MCTargetAsmParser {
130 MipsTargetStreamer &getTargetStreamer() {
131 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
132 return static_cast<MipsTargetStreamer &>(TS);
136 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
137 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
138 // nullptr, which indicates that no function is currently
139 // selected. This usually happens after an '.end func'
145 unsigned CpSaveLocation;
146 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
147 bool CpSaveLocationIsRegister;
149 // Print a warning along with its fix-it message at the given range.
150 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
151 SMRange Range, bool ShowColors = true);
153 #define GET_ASSEMBLER_HEADER
154 #include "MipsGenAsmMatcher.inc"
157 checkEarlyTargetMatchPredicate(MCInst &Inst,
158 const OperandVector &Operands) override;
159 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
161 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
162 OperandVector &Operands, MCStreamer &Out,
164 bool MatchingInlineAsm) override;
166 /// Parse a register as used in CFI directives
167 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
169 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
171 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
173 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
175 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
176 SMLoc NameLoc, OperandVector &Operands) override;
178 bool ParseDirective(AsmToken DirectiveID) override;
180 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
182 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
183 StringRef Identifier, SMLoc S);
184 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
186 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
187 OperandMatchResultTy parseImm(OperandVector &Operands);
188 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
189 OperandMatchResultTy parseInvNum(OperandVector &Operands);
190 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
191 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
192 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
194 bool searchSymbolAlias(OperandVector &Operands);
196 bool parseOperand(OperandVector &, StringRef Mnemonic);
198 enum MacroExpanderResultTy {
204 // Expands assembly pseudo instructions.
205 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
207 const MCSubtargetInfo *STI);
209 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
210 const MCSubtargetInfo *STI);
212 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
213 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
214 MCStreamer &Out, const MCSubtargetInfo *STI);
216 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
217 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
218 MCStreamer &Out, const MCSubtargetInfo *STI);
220 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
222 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
223 MCStreamer &Out, const MCSubtargetInfo *STI);
225 bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
226 SMLoc IDLoc, MCStreamer &Out,
227 const MCSubtargetInfo *STI);
229 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
230 const MCOperand &Offset, bool Is32BitAddress,
231 SMLoc IDLoc, MCStreamer &Out,
232 const MCSubtargetInfo *STI);
234 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
235 const MCSubtargetInfo *STI);
237 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
238 const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
240 void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI, bool IsImmOpnd);
243 void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI, bool IsImmOpnd);
246 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI);
249 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
250 const MCSubtargetInfo *STI);
252 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
255 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
258 bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI, const bool IsMips64,
262 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
263 MCStreamer &Out, const MCSubtargetInfo *STI);
265 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
268 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
271 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
274 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
275 MCStreamer &Out, const MCSubtargetInfo *STI);
276 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI);
278 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
279 const MCSubtargetInfo *STI);
280 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
281 const MCSubtargetInfo *STI);
283 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
284 const MCSubtargetInfo *STI);
286 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
287 const MCSubtargetInfo *STI);
289 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
290 const MCSubtargetInfo *STI);
292 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
295 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
298 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI, bool IsLoad);
301 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI);
304 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI);
307 bool reportParseError(Twine ErrorMsg);
308 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
310 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
312 bool isEvaluated(const MCExpr *Expr);
313 bool parseSetMips0Directive();
314 bool parseSetArchDirective();
315 bool parseSetFeature(uint64_t Feature);
316 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
317 bool parseDirectiveCpLoad(SMLoc Loc);
318 bool parseDirectiveCpRestore(SMLoc Loc);
319 bool parseDirectiveCPSetup();
320 bool parseDirectiveCPReturn();
321 bool parseDirectiveNaN();
322 bool parseDirectiveSet();
323 bool parseDirectiveOption();
324 bool parseInsnDirective();
325 bool parseRSectionDirective(StringRef Section);
326 bool parseSSectionDirective(StringRef Section, unsigned Type);
328 bool parseSetAtDirective();
329 bool parseSetNoAtDirective();
330 bool parseSetMacroDirective();
331 bool parseSetNoMacroDirective();
332 bool parseSetMsaDirective();
333 bool parseSetNoMsaDirective();
334 bool parseSetNoDspDirective();
335 bool parseSetReorderDirective();
336 bool parseSetNoReorderDirective();
337 bool parseSetMips16Directive();
338 bool parseSetNoMips16Directive();
339 bool parseSetFpDirective();
340 bool parseSetOddSPRegDirective();
341 bool parseSetNoOddSPRegDirective();
342 bool parseSetPopDirective();
343 bool parseSetPushDirective();
344 bool parseSetSoftFloatDirective();
345 bool parseSetHardFloatDirective();
346 bool parseSetMtDirective();
347 bool parseSetNoMtDirective();
349 bool parseSetAssignment();
351 bool parseDataDirective(unsigned Size, SMLoc L);
352 bool parseDirectiveGpWord();
353 bool parseDirectiveGpDWord();
354 bool parseDirectiveDtpRelWord();
355 bool parseDirectiveDtpRelDWord();
356 bool parseDirectiveTpRelWord();
357 bool parseDirectiveTpRelDWord();
358 bool parseDirectiveModule();
359 bool parseDirectiveModuleFP();
360 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
361 StringRef Directive);
363 bool parseInternalDirectiveReallowModule();
365 bool eatComma(StringRef ErrorStr);
367 int matchCPURegisterName(StringRef Symbol);
369 int matchHWRegsRegisterName(StringRef Symbol);
371 int matchFPURegisterName(StringRef Name);
373 int matchFCCRegisterName(StringRef Name);
375 int matchACRegisterName(StringRef Name);
377 int matchMSA128RegisterName(StringRef Name);
379 int matchMSA128CtrlRegisterName(StringRef Name);
381 unsigned getReg(int RC, int RegNo);
383 /// Returns the internal register number for the current AT. Also checks if
384 /// the current AT is unavailable (set to $0) and gives an error if it is.
385 /// This should be used in pseudo-instruction expansions which need AT.
386 unsigned getATReg(SMLoc Loc);
390 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
391 const MCSubtargetInfo *STI);
393 // Helper function that checks if the value of a vector index is within the
394 // boundaries of accepted values for each RegisterKind
395 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
396 bool validateMSAIndex(int Val, int RegKind);
398 // Selects a new architecture by updating the FeatureBits with the necessary
399 // info including implied dependencies.
400 // Internally, it clears all the feature bits related to *any* architecture
401 // and selects the new one using the ToggleFeature functionality of the
402 // MCSubtargetInfo object that handles implied dependencies. The reason we
403 // clear all the arch related bits manually is because ToggleFeature only
404 // clears the features that imply the feature being cleared and not the
405 // features implied by the feature being cleared. This is easier to see
407 // --------------------------------------------------
408 // | Feature | Implies |
409 // | -------------------------------------------------|
410 // | FeatureMips1 | None |
411 // | FeatureMips2 | FeatureMips1 |
412 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
413 // | FeatureMips4 | FeatureMips3 |
415 // --------------------------------------------------
417 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
418 // FeatureMipsGP64 | FeatureMips1)
419 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
420 void selectArch(StringRef ArchFeature) {
421 MCSubtargetInfo &STI = copySTI();
422 FeatureBitset FeatureBits = STI.getFeatureBits();
423 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
424 STI.setFeatureBits(FeatureBits);
425 setAvailableFeatures(
426 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
427 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
430 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
431 if (!(getSTI().getFeatureBits()[Feature])) {
432 MCSubtargetInfo &STI = copySTI();
433 setAvailableFeatures(
434 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
435 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
439 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
440 if (getSTI().getFeatureBits()[Feature]) {
441 MCSubtargetInfo &STI = copySTI();
442 setAvailableFeatures(
443 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
444 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
448 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
449 setFeatureBits(Feature, FeatureString);
450 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
453 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
454 clearFeatureBits(Feature, FeatureString);
455 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
459 enum MipsMatchResultTy {
460 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
461 Match_RequiresDifferentOperands,
462 Match_RequiresNoZeroRegister,
463 Match_RequiresSameSrcAndDst,
464 Match_NoFCCRegisterForCurrentISA,
465 Match_NonZeroOperandForSync,
466 #define GET_OPERAND_DIAGNOSTIC_TYPES
467 #include "MipsGenAsmMatcher.inc"
468 #undef GET_OPERAND_DIAGNOSTIC_TYPES
471 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
472 const MCInstrInfo &MII, const MCTargetOptions &Options)
473 : MCTargetAsmParser(Options, sti),
474 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
475 sti.getCPU(), Options)) {
476 MCAsmParserExtension::Initialize(parser);
478 parser.addAliasForDirective(".asciiz", ".asciz");
480 // Initialize the set of available features.
481 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
483 // Remember the initial assembler options. The user can not modify these.
484 AssemblerOptions.push_back(
485 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
487 // Create an assembler options environment for the user to modify.
488 AssemblerOptions.push_back(
489 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
491 getTargetStreamer().updateABIInfo(*this);
493 if (!isABI_O32() && !useOddSPReg() != 0)
494 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
498 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
500 IsCpRestoreSet = false;
501 CpRestoreOffset = -1;
503 const Triple &TheTriple = sti.getTargetTriple();
504 if ((TheTriple.getArch() == Triple::mips) ||
505 (TheTriple.getArch() == Triple::mips64))
506 IsLittleEndian = false;
508 IsLittleEndian = true;
511 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
512 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
514 bool isGP64bit() const {
515 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
518 bool isFP64bit() const {
519 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
522 const MipsABIInfo &getABI() const { return ABI; }
523 bool isABI_N32() const { return ABI.IsN32(); }
524 bool isABI_N64() const { return ABI.IsN64(); }
525 bool isABI_O32() const { return ABI.IsO32(); }
526 bool isABI_FPXX() const {
527 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
530 bool useOddSPReg() const {
531 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
534 bool inMicroMipsMode() const {
535 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
538 bool hasMips1() const {
539 return getSTI().getFeatureBits()[Mips::FeatureMips1];
542 bool hasMips2() const {
543 return getSTI().getFeatureBits()[Mips::FeatureMips2];
546 bool hasMips3() const {
547 return getSTI().getFeatureBits()[Mips::FeatureMips3];
550 bool hasMips4() const {
551 return getSTI().getFeatureBits()[Mips::FeatureMips4];
554 bool hasMips5() const {
555 return getSTI().getFeatureBits()[Mips::FeatureMips5];
558 bool hasMips32() const {
559 return getSTI().getFeatureBits()[Mips::FeatureMips32];
562 bool hasMips64() const {
563 return getSTI().getFeatureBits()[Mips::FeatureMips64];
566 bool hasMips32r2() const {
567 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
570 bool hasMips64r2() const {
571 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
574 bool hasMips32r3() const {
575 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
578 bool hasMips64r3() const {
579 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
582 bool hasMips32r5() const {
583 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
586 bool hasMips64r5() const {
587 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
590 bool hasMips32r6() const {
591 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
594 bool hasMips64r6() const {
595 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
598 bool hasDSP() const {
599 return getSTI().getFeatureBits()[Mips::FeatureDSP];
602 bool hasDSPR2() const {
603 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
606 bool hasDSPR3() const {
607 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
610 bool hasMSA() const {
611 return getSTI().getFeatureBits()[Mips::FeatureMSA];
614 bool hasCnMips() const {
615 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
622 bool inMips16Mode() const {
623 return getSTI().getFeatureBits()[Mips::FeatureMips16];
626 bool useTraps() const {
627 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
630 bool useSoftFloat() const {
631 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
634 return getSTI().getFeatureBits()[Mips::FeatureMT];
637 /// Warn if RegIndex is the same as the current AT.
638 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
640 void warnIfNoMacro(SMLoc Loc);
642 bool isLittle() const { return IsLittleEndian; }
644 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
645 AsmToken::TokenKind OperatorToken,
646 MCContext &Ctx) override {
647 switch(OperatorToken) {
649 llvm_unreachable("Unknown token");
651 case AsmToken::PercentCall16:
652 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
653 case AsmToken::PercentCall_Hi:
654 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
655 case AsmToken::PercentCall_Lo:
656 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
657 case AsmToken::PercentDtprel_Hi:
658 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
659 case AsmToken::PercentDtprel_Lo:
660 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
661 case AsmToken::PercentGot:
662 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
663 case AsmToken::PercentGot_Disp:
664 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
665 case AsmToken::PercentGot_Hi:
666 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
667 case AsmToken::PercentGot_Lo:
668 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
669 case AsmToken::PercentGot_Ofst:
670 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
671 case AsmToken::PercentGot_Page:
672 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
673 case AsmToken::PercentGottprel:
674 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
675 case AsmToken::PercentGp_Rel:
676 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
677 case AsmToken::PercentHi:
678 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
679 case AsmToken::PercentHigher:
680 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
681 case AsmToken::PercentHighest:
682 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
683 case AsmToken::PercentLo:
684 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
685 case AsmToken::PercentNeg:
686 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
687 case AsmToken::PercentPcrel_Hi:
688 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
689 case AsmToken::PercentPcrel_Lo:
690 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
691 case AsmToken::PercentTlsgd:
692 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
693 case AsmToken::PercentTlsldm:
694 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
695 case AsmToken::PercentTprel_Hi:
696 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
697 case AsmToken::PercentTprel_Lo:
698 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
703 /// MipsOperand - Instances of this class represent a parsed Mips machine
705 class MipsOperand : public MCParsedAsmOperand {
707 /// Broad categories of register classes
708 /// The exact class is finalized by the render method.
710 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
711 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
713 RegKind_FCC = 4, /// FCC
714 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
715 RegKind_MSACtrl = 16, /// MSA control registers
716 RegKind_COP2 = 32, /// COP2
717 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
719 RegKind_CCR = 128, /// CCR
720 RegKind_HWRegs = 256, /// HWRegs
721 RegKind_COP3 = 512, /// COP3
722 RegKind_COP0 = 1024, /// COP0
723 /// Potentially any (e.g. $1)
724 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
725 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
726 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
731 k_Immediate, /// An immediate (possibly involving symbol references)
732 k_Memory, /// Base + Offset Memory Address
733 k_RegisterIndex, /// A register index in one or more RegKind.
734 k_Token, /// A simple token
735 k_RegList, /// A physical register list
736 k_RegPair /// A pair of physical register
740 MipsOperand(KindTy K, MipsAsmParser &Parser)
741 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
743 ~MipsOperand() override {
752 case k_RegisterIndex:
760 /// For diagnostics, and checking the assembler temporary
761 MipsAsmParser &AsmParser;
769 unsigned Index; /// Index into the register class
770 RegKind Kind; /// Bitfield of the kinds it could possibly be
771 struct Token Tok; /// The input token this operand originated from.
772 const MCRegisterInfo *RegInfo;
785 SmallVector<unsigned, 10> *List;
790 struct RegIdxOp RegIdx;
793 struct RegListOp RegList;
796 SMLoc StartLoc, EndLoc;
798 /// Internal constructor for register kinds
799 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
801 const MCRegisterInfo *RegInfo,
803 MipsAsmParser &Parser) {
804 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
805 Op->RegIdx.Index = Index;
806 Op->RegIdx.RegInfo = RegInfo;
807 Op->RegIdx.Kind = RegKind;
808 Op->RegIdx.Tok.Data = Str.data();
809 Op->RegIdx.Tok.Length = Str.size();
816 /// Coerce the register to GPR32 and return the real register for the current
818 unsigned getGPR32Reg() const {
819 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
820 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
821 unsigned ClassID = Mips::GPR32RegClassID;
822 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
825 /// Coerce the register to GPR32 and return the real register for the current
827 unsigned getGPRMM16Reg() const {
828 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
829 unsigned ClassID = Mips::GPR32RegClassID;
830 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
833 /// Coerce the register to GPR64 and return the real register for the current
835 unsigned getGPR64Reg() const {
836 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
837 unsigned ClassID = Mips::GPR64RegClassID;
838 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
842 /// Coerce the register to AFGR64 and return the real register for the current
844 unsigned getAFGR64Reg() const {
845 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
846 if (RegIdx.Index % 2 != 0)
847 AsmParser.Warning(StartLoc, "Float register should be even.");
848 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
849 .getRegister(RegIdx.Index / 2);
852 /// Coerce the register to FGR64 and return the real register for the current
854 unsigned getFGR64Reg() const {
855 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
856 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
857 .getRegister(RegIdx.Index);
860 /// Coerce the register to FGR32 and return the real register for the current
862 unsigned getFGR32Reg() const {
863 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
864 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
865 .getRegister(RegIdx.Index);
868 /// Coerce the register to FGRH32 and return the real register for the current
870 unsigned getFGRH32Reg() const {
871 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
872 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
873 .getRegister(RegIdx.Index);
876 /// Coerce the register to FCC and return the real register for the current
878 unsigned getFCCReg() const {
879 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
880 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
881 .getRegister(RegIdx.Index);
884 /// Coerce the register to MSA128 and return the real register for the current
886 unsigned getMSA128Reg() const {
887 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
888 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
890 unsigned ClassID = Mips::MSA128BRegClassID;
891 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
894 /// Coerce the register to MSACtrl and return the real register for the
896 unsigned getMSACtrlReg() const {
897 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
898 unsigned ClassID = Mips::MSACtrlRegClassID;
899 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
902 /// Coerce the register to COP0 and return the real register for the
904 unsigned getCOP0Reg() const {
905 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
906 unsigned ClassID = Mips::COP0RegClassID;
907 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
910 /// Coerce the register to COP2 and return the real register for the
912 unsigned getCOP2Reg() const {
913 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
914 unsigned ClassID = Mips::COP2RegClassID;
915 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
918 /// Coerce the register to COP3 and return the real register for the
920 unsigned getCOP3Reg() const {
921 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
922 unsigned ClassID = Mips::COP3RegClassID;
923 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
926 /// Coerce the register to ACC64DSP and return the real register for the
928 unsigned getACC64DSPReg() const {
929 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
930 unsigned ClassID = Mips::ACC64DSPRegClassID;
931 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
934 /// Coerce the register to HI32DSP and return the real register for the
936 unsigned getHI32DSPReg() const {
937 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
938 unsigned ClassID = Mips::HI32DSPRegClassID;
939 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
942 /// Coerce the register to LO32DSP and return the real register for the
944 unsigned getLO32DSPReg() const {
945 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
946 unsigned ClassID = Mips::LO32DSPRegClassID;
947 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
950 /// Coerce the register to CCR and return the real register for the
952 unsigned getCCRReg() const {
953 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
954 unsigned ClassID = Mips::CCRRegClassID;
955 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
958 /// Coerce the register to HWRegs and return the real register for the
960 unsigned getHWRegsReg() const {
961 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
962 unsigned ClassID = Mips::HWRegsRegClassID;
963 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
967 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
968 // Add as immediate when possible. Null MCExpr = 0.
970 Inst.addOperand(MCOperand::createImm(0));
971 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
972 Inst.addOperand(MCOperand::createImm(CE->getValue()));
974 Inst.addOperand(MCOperand::createExpr(Expr));
977 void addRegOperands(MCInst &Inst, unsigned N) const {
978 llvm_unreachable("Use a custom parser instead");
981 /// Render the operand to an MCInst as a GPR32
982 /// Asserts if the wrong number of operands are requested, or the operand
983 /// is not a k_RegisterIndex compatible with RegKind_GPR
984 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
985 assert(N == 1 && "Invalid number of operands!");
986 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
989 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
990 assert(N == 1 && "Invalid number of operands!");
991 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
994 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
995 assert(N == 1 && "Invalid number of operands!");
996 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
999 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1000 assert(N == 1 && "Invalid number of operands!");
1001 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1004 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1005 assert(N == 1 && "Invalid number of operands!");
1006 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1009 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1010 assert(N == 1 && "Invalid number of operands!");
1011 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1014 /// Render the operand to an MCInst as a GPR64
1015 /// Asserts if the wrong number of operands are requested, or the operand
1016 /// is not a k_RegisterIndex compatible with RegKind_GPR
1017 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1018 assert(N == 1 && "Invalid number of operands!");
1019 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1022 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1023 assert(N == 1 && "Invalid number of operands!");
1024 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1027 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1028 assert(N == 1 && "Invalid number of operands!");
1029 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1032 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1033 assert(N == 1 && "Invalid number of operands!");
1034 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1037 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1038 assert(N == 1 && "Invalid number of operands!");
1039 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1042 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1043 assert(N == 1 && "Invalid number of operands!");
1044 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1045 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1046 // FIXME: This should propagate failure up to parseStatement.
1047 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1048 AsmParser.getParser().printError(
1049 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1053 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1054 assert(N == 1 && "Invalid number of operands!");
1055 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1056 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1057 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1058 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1062 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1063 assert(N == 1 && "Invalid number of operands!");
1064 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1067 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1068 assert(N == 1 && "Invalid number of operands!");
1069 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1072 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1073 assert(N == 1 && "Invalid number of operands!");
1074 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1077 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1078 assert(N == 1 && "Invalid number of operands!");
1079 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1082 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1083 assert(N == 1 && "Invalid number of operands!");
1084 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1087 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1088 assert(N == 1 && "Invalid number of operands!");
1089 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1092 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1093 assert(N == 1 && "Invalid number of operands!");
1094 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1097 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1098 assert(N == 1 && "Invalid number of operands!");
1099 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1102 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1103 assert(N == 1 && "Invalid number of operands!");
1104 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1107 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1108 assert(N == 1 && "Invalid number of operands!");
1109 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1112 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1113 assert(N == 1 && "Invalid number of operands!");
1114 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1117 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1118 assert(N == 1 && "Invalid number of operands!");
1119 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1122 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1123 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1124 assert(N == 1 && "Invalid number of operands!");
1125 uint64_t Imm = getConstantImm() - Offset;
1126 Imm &= (1ULL << Bits) - 1;
1128 Imm += AdjustOffset;
1129 Inst.addOperand(MCOperand::createImm(Imm));
1132 template <unsigned Bits>
1133 void addSImmOperands(MCInst &Inst, unsigned N) const {
1134 if (isImm() && !isConstantImm()) {
1135 addExpr(Inst, getImm());
1138 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1141 template <unsigned Bits>
1142 void addUImmOperands(MCInst &Inst, unsigned N) const {
1143 if (isImm() && !isConstantImm()) {
1144 addExpr(Inst, getImm());
1147 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1150 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1151 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1152 assert(N == 1 && "Invalid number of operands!");
1153 int64_t Imm = getConstantImm() - Offset;
1154 Imm = SignExtend64<Bits>(Imm);
1156 Imm += AdjustOffset;
1157 Inst.addOperand(MCOperand::createImm(Imm));
1160 void addImmOperands(MCInst &Inst, unsigned N) const {
1161 assert(N == 1 && "Invalid number of operands!");
1162 const MCExpr *Expr = getImm();
1163 addExpr(Inst, Expr);
1166 void addMemOperands(MCInst &Inst, unsigned N) const {
1167 assert(N == 2 && "Invalid number of operands!");
1169 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1170 ? getMemBase()->getGPR64Reg()
1171 : getMemBase()->getGPR32Reg()));
1173 const MCExpr *Expr = getMemOff();
1174 addExpr(Inst, Expr);
1177 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1178 assert(N == 2 && "Invalid number of operands!");
1180 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1182 const MCExpr *Expr = getMemOff();
1183 addExpr(Inst, Expr);
1186 void addRegListOperands(MCInst &Inst, unsigned N) const {
1187 assert(N == 1 && "Invalid number of operands!");
1189 for (auto RegNo : getRegList())
1190 Inst.addOperand(MCOperand::createReg(RegNo));
1193 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1194 assert(N == 2 && "Invalid number of operands!");
1195 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1196 unsigned RegNo = getRegPair();
1197 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1198 Inst.addOperand(MCOperand::createReg(
1199 RegIdx.RegInfo->getRegClass(
1200 AsmParser.getABI().AreGprs64bit()
1201 ? Mips::GPR64RegClassID
1202 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1203 Inst.addOperand(MCOperand::createReg(
1204 RegIdx.RegInfo->getRegClass(
1205 AsmParser.getABI().AreGprs64bit()
1206 ? Mips::GPR64RegClassID
1207 : Mips::GPR32RegClassID).getRegister(RegNo)));
1210 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1211 assert(N == 2 && "Invalid number of operands!");
1212 for (auto RegNo : getRegList())
1213 Inst.addOperand(MCOperand::createReg(RegNo));
1216 bool isReg() const override {
1217 // As a special case until we sort out the definition of div/divu, accept
1218 // $0/$zero here so that MCK_ZERO works correctly.
1219 return isGPRAsmReg() && RegIdx.Index == 0;
1222 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1223 bool isImm() const override { return Kind == k_Immediate; }
1225 bool isConstantImm() const {
1227 return isImm() && getImm()->evaluateAsAbsolute(Res);
1230 bool isConstantImmz() const {
1231 return isConstantImm() && getConstantImm() == 0;
1234 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1235 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1238 template <unsigned Bits> bool isSImm() const {
1239 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1242 template <unsigned Bits> bool isUImm() const {
1243 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1246 template <unsigned Bits> bool isAnyImm() const {
1247 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1248 isUInt<Bits>(getConstantImm()))
1252 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1253 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1256 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1257 return isConstantImm() && getConstantImm() >= Bottom &&
1258 getConstantImm() <= Top;
1261 bool isToken() const override {
1262 // Note: It's not possible to pretend that other operand kinds are tokens.
1263 // The matcher emitter checks tokens first.
1264 return Kind == k_Token;
1267 bool isMem() const override { return Kind == k_Memory; }
1269 bool isConstantMemOff() const {
1270 return isMem() && isa<MCConstantExpr>(getMemOff());
1273 // Allow relocation operators.
1274 // FIXME: This predicate and others need to look through binary expressions
1275 // and determine whether a Value is a constant or not.
1276 template <unsigned Bits, unsigned ShiftAmount = 0>
1277 bool isMemWithSimmOffset() const {
1280 if (!getMemBase()->isGPRAsmReg())
1282 if (isa<MCTargetExpr>(getMemOff()) ||
1283 (isConstantMemOff() &&
1284 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1287 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1288 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1291 bool isMemWithGRPMM16Base() const {
1292 return isMem() && getMemBase()->isMM16AsmReg();
1295 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1296 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1297 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1300 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1301 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1302 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1303 && (getMemBase()->getGPR32Reg() == Mips::SP);
1306 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1307 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1308 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1309 && (getMemBase()->getGPR32Reg() == Mips::GP);
1312 template <unsigned Bits, unsigned ShiftLeftAmount>
1313 bool isScaledUImm() const {
1314 return isConstantImm() &&
1315 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1318 template <unsigned Bits, unsigned ShiftLeftAmount>
1319 bool isScaledSImm() const {
1320 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1322 // Operand can also be a symbol or symbol plus offset in case of relocations.
1323 if (Kind != k_Immediate)
1326 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1327 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1330 bool isRegList16() const {
1334 int Size = RegList.List->size();
1335 if (Size < 2 || Size > 5)
1338 unsigned R0 = RegList.List->front();
1339 unsigned R1 = RegList.List->back();
1340 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1341 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1344 int PrevReg = *RegList.List->begin();
1345 for (int i = 1; i < Size - 1; i++) {
1346 int Reg = (*(RegList.List))[i];
1347 if ( Reg != PrevReg + 1)
1355 bool isInvNum() const { return Kind == k_Immediate; }
1357 bool isLSAImm() const {
1358 if (!isConstantImm())
1360 int64_t Val = getConstantImm();
1361 return 1 <= Val && Val <= 4;
1364 bool isRegList() const { return Kind == k_RegList; }
1366 bool isMovePRegPair() const {
1367 if (Kind != k_RegList || RegList.List->size() != 2)
1370 unsigned R0 = RegList.List->front();
1371 unsigned R1 = RegList.List->back();
1373 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1374 (R0 == Mips::A1 && R1 == Mips::A3) ||
1375 (R0 == Mips::A2 && R1 == Mips::A3) ||
1376 (R0 == Mips::A0 && R1 == Mips::S5) ||
1377 (R0 == Mips::A0 && R1 == Mips::S6) ||
1378 (R0 == Mips::A0 && R1 == Mips::A1) ||
1379 (R0 == Mips::A0 && R1 == Mips::A2) ||
1380 (R0 == Mips::A0 && R1 == Mips::A3) ||
1381 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1382 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1383 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1384 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1385 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1386 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1387 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1388 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1394 StringRef getToken() const {
1395 assert(Kind == k_Token && "Invalid access!");
1396 return StringRef(Tok.Data, Tok.Length);
1399 bool isRegPair() const {
1400 return Kind == k_RegPair && RegIdx.Index <= 30;
1403 unsigned getReg() const override {
1404 // As a special case until we sort out the definition of div/divu, accept
1405 // $0/$zero here so that MCK_ZERO works correctly.
1406 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1407 RegIdx.Kind & RegKind_GPR)
1408 return getGPR32Reg(); // FIXME: GPR64 too
1410 llvm_unreachable("Invalid access!");
1414 const MCExpr *getImm() const {
1415 assert((Kind == k_Immediate) && "Invalid access!");
1419 int64_t getConstantImm() const {
1420 const MCExpr *Val = getImm();
1422 (void)Val->evaluateAsAbsolute(Value);
1426 MipsOperand *getMemBase() const {
1427 assert((Kind == k_Memory) && "Invalid access!");
1431 const MCExpr *getMemOff() const {
1432 assert((Kind == k_Memory) && "Invalid access!");
1436 int64_t getConstantMemOff() const {
1437 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1440 const SmallVectorImpl<unsigned> &getRegList() const {
1441 assert((Kind == k_RegList) && "Invalid access!");
1442 return *(RegList.List);
1445 unsigned getRegPair() const {
1446 assert((Kind == k_RegPair) && "Invalid access!");
1447 return RegIdx.Index;
1450 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1451 MipsAsmParser &Parser) {
1452 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1453 Op->Tok.Data = Str.data();
1454 Op->Tok.Length = Str.size();
1460 /// Create a numeric register (e.g. $1). The exact register remains
1461 /// unresolved until an instruction successfully matches
1462 static std::unique_ptr<MipsOperand>
1463 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1464 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1465 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1466 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1469 /// Create a register that is definitely a GPR.
1470 /// This is typically only used for named registers such as $gp.
1471 static std::unique_ptr<MipsOperand>
1472 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1473 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1474 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1477 /// Create a register that is definitely a FGR.
1478 /// This is typically only used for named registers such as $f0.
1479 static std::unique_ptr<MipsOperand>
1480 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1481 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1482 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1485 /// Create a register that is definitely a HWReg.
1486 /// This is typically only used for named registers such as $hwr_cpunum.
1487 static std::unique_ptr<MipsOperand>
1488 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1489 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1490 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1493 /// Create a register that is definitely an FCC.
1494 /// This is typically only used for named registers such as $fcc0.
1495 static std::unique_ptr<MipsOperand>
1496 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1497 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1498 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1501 /// Create a register that is definitely an ACC.
1502 /// This is typically only used for named registers such as $ac0.
1503 static std::unique_ptr<MipsOperand>
1504 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1505 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1506 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1509 /// Create a register that is definitely an MSA128.
1510 /// This is typically only used for named registers such as $w0.
1511 static std::unique_ptr<MipsOperand>
1512 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1513 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1514 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1517 /// Create a register that is definitely an MSACtrl.
1518 /// This is typically only used for named registers such as $msaaccess.
1519 static std::unique_ptr<MipsOperand>
1520 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1521 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1522 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1525 static std::unique_ptr<MipsOperand>
1526 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1527 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1534 static std::unique_ptr<MipsOperand>
1535 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1536 SMLoc E, MipsAsmParser &Parser) {
1537 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1538 Op->Mem.Base = Base.release();
1545 static std::unique_ptr<MipsOperand>
1546 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1547 MipsAsmParser &Parser) {
1548 assert(Regs.size() > 0 && "Empty list not allowed");
1550 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1551 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1552 Op->StartLoc = StartLoc;
1553 Op->EndLoc = EndLoc;
1557 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1559 MipsAsmParser &Parser) {
1560 auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
1561 Op->RegIdx.Index = MOP.RegIdx.Index;
1562 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1563 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1569 bool isGPRZeroAsmReg() const {
1570 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1573 bool isGPRNonZeroAsmReg() const {
1574 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1578 bool isGPRAsmReg() const {
1579 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1582 bool isMM16AsmReg() const {
1583 if (!(isRegIdx() && RegIdx.Kind))
1585 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1586 || RegIdx.Index == 16 || RegIdx.Index == 17);
1589 bool isMM16AsmRegZero() const {
1590 if (!(isRegIdx() && RegIdx.Kind))
1592 return (RegIdx.Index == 0 ||
1593 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1594 RegIdx.Index == 17);
1597 bool isMM16AsmRegMoveP() const {
1598 if (!(isRegIdx() && RegIdx.Kind))
1600 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1601 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1604 bool isFGRAsmReg() const {
1605 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1606 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1609 bool isStrictlyFGRAsmReg() const {
1610 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1611 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1614 bool isHWRegsAsmReg() const {
1615 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1618 bool isCCRAsmReg() const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1622 bool isFCCAsmReg() const {
1623 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1625 return RegIdx.Index <= 7;
1628 bool isACCAsmReg() const {
1629 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1632 bool isCOP0AsmReg() const {
1633 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1636 bool isCOP2AsmReg() const {
1637 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1640 bool isCOP3AsmReg() const {
1641 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1644 bool isMSA128AsmReg() const {
1645 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1648 bool isMSACtrlAsmReg() const {
1649 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1652 /// getStartLoc - Get the location of the first token of this operand.
1653 SMLoc getStartLoc() const override { return StartLoc; }
1654 /// getEndLoc - Get the location of the last token of this operand.
1655 SMLoc getEndLoc() const override { return EndLoc; }
1657 void print(raw_ostream &OS) const override {
1666 Mem.Base->print(OS);
1671 case k_RegisterIndex:
1672 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1673 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1680 for (auto Reg : (*RegList.List))
1685 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1690 bool isValidForTie(const MipsOperand &Other) const {
1691 if (Kind != Other.Kind)
1696 llvm_unreachable("Unexpected kind");
1698 case k_RegisterIndex: {
1699 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1700 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1701 return Token == OtherToken;
1705 }; // class MipsOperand
1707 } // end anonymous namespace
1711 extern const MCInstrDesc MipsInsts[];
1713 } // end namespace llvm
1715 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1716 return MipsInsts[Opcode];
1719 static bool hasShortDelaySlot(unsigned Opcode) {
1722 case Mips::JALRS_MM:
1723 case Mips::JALRS16_MM:
1724 case Mips::BGEZALS_MM:
1725 case Mips::BLTZALS_MM:
1732 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1733 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1734 return &SRExpr->getSymbol();
1737 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1738 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1739 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1750 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1751 return getSingleMCSymbol(UExpr->getSubExpr());
1756 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1757 if (isa<MCSymbolRefExpr>(Expr))
1760 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1761 return countMCSymbolRefExpr(BExpr->getLHS()) +
1762 countMCSymbolRefExpr(BExpr->getRHS());
1764 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1765 return countMCSymbolRefExpr(UExpr->getSubExpr());
1770 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1772 const MCSubtargetInfo *STI) {
1773 MipsTargetStreamer &TOut = getTargetStreamer();
1774 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1775 bool ExpandedJalSym = false;
1779 if (MCID.isBranch() || MCID.isCall()) {
1780 const unsigned Opcode = Inst.getOpcode();
1790 assert(hasCnMips() && "instruction only valid for octeon cpus");
1797 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1798 Offset = Inst.getOperand(2);
1799 if (!Offset.isImm())
1800 break; // We'll deal with this situation later on when applying fixups.
1801 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1802 return Error(IDLoc, "branch target out of range");
1803 if (OffsetToAlignment(Offset.getImm(),
1804 1LL << (inMicroMipsMode() ? 1 : 2)))
1805 return Error(IDLoc, "branch to misaligned address");
1819 case Mips::BGEZAL_MM:
1820 case Mips::BLTZAL_MM:
1823 case Mips::BC1EQZC_MMR6:
1824 case Mips::BC1NEZC_MMR6:
1825 case Mips::BC2EQZC_MMR6:
1826 case Mips::BC2NEZC_MMR6:
1827 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1828 Offset = Inst.getOperand(1);
1829 if (!Offset.isImm())
1830 break; // We'll deal with this situation later on when applying fixups.
1831 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1832 return Error(IDLoc, "branch target out of range");
1833 if (OffsetToAlignment(Offset.getImm(),
1834 1LL << (inMicroMipsMode() ? 1 : 2)))
1835 return Error(IDLoc, "branch to misaligned address");
1837 case Mips::BGEC: case Mips::BGEC_MMR6:
1838 case Mips::BLTC: case Mips::BLTC_MMR6:
1839 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1840 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1841 case Mips::BEQC: case Mips::BEQC_MMR6:
1842 case Mips::BNEC: case Mips::BNEC_MMR6:
1843 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1844 Offset = Inst.getOperand(2);
1845 if (!Offset.isImm())
1846 break; // We'll deal with this situation later on when applying fixups.
1847 if (!isIntN(18, Offset.getImm()))
1848 return Error(IDLoc, "branch target out of range");
1849 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1850 return Error(IDLoc, "branch to misaligned address");
1852 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1853 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1854 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1855 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1856 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1857 Offset = Inst.getOperand(1);
1858 if (!Offset.isImm())
1859 break; // We'll deal with this situation later on when applying fixups.
1860 if (!isIntN(18, Offset.getImm()))
1861 return Error(IDLoc, "branch target out of range");
1862 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1863 return Error(IDLoc, "branch to misaligned address");
1865 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1866 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1867 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1868 Offset = Inst.getOperand(1);
1869 if (!Offset.isImm())
1870 break; // We'll deal with this situation later on when applying fixups.
1871 if (!isIntN(23, Offset.getImm()))
1872 return Error(IDLoc, "branch target out of range");
1873 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1874 return Error(IDLoc, "branch to misaligned address");
1876 case Mips::BEQZ16_MM:
1877 case Mips::BEQZC16_MMR6:
1878 case Mips::BNEZ16_MM:
1879 case Mips::BNEZC16_MMR6:
1880 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1881 Offset = Inst.getOperand(1);
1882 if (!Offset.isImm())
1883 break; // We'll deal with this situation later on when applying fixups.
1884 if (!isInt<8>(Offset.getImm()))
1885 return Error(IDLoc, "branch target out of range");
1886 if (OffsetToAlignment(Offset.getImm(), 2LL))
1887 return Error(IDLoc, "branch to misaligned address");
1892 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1893 // We still accept it but it is a normal nop.
1894 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1895 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1896 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1901 const unsigned Opcode = Inst.getOpcode();
1913 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1914 // The offset is handled above
1915 Opnd = Inst.getOperand(1);
1917 return Error(IDLoc, "expected immediate operand kind");
1918 Imm = Opnd.getImm();
1919 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1920 Opcode == Mips::BBIT1 ? 63 : 31))
1921 return Error(IDLoc, "immediate operand value out of range");
1923 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1925 Inst.getOperand(1).setImm(Imm - 32);
1931 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1932 Opnd = Inst.getOperand(2);
1934 return Error(IDLoc, "expected immediate operand kind");
1935 Imm = Opnd.getImm();
1936 if (!isInt<10>(Imm))
1937 return Error(IDLoc, "immediate operand value out of range");
1942 // Warn on division by zero. We're checking here as all instructions get
1943 // processed here, not just the macros that need expansion.
1945 // The MIPS backend models most of the divison instructions and macros as
1946 // three operand instructions. The pre-R6 divide instructions however have
1947 // two operands and explicitly define HI/LO as part of the instruction,
1948 // not in the operands.
1949 unsigned FirstOp = 1;
1950 unsigned SecondOp = 2;
1951 switch (Inst.getOpcode()) {
1954 case Mips::SDivIMacro:
1955 case Mips::UDivIMacro:
1956 case Mips::DSDivIMacro:
1957 case Mips::DUDivIMacro:
1958 if (Inst.getOperand(2).getImm() == 0) {
1959 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1960 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1961 Warning(IDLoc, "dividing zero by zero");
1963 Warning(IDLoc, "division by zero");
1975 case Mips::SDivMacro:
1976 case Mips::DSDivMacro:
1977 case Mips::UDivMacro:
1978 case Mips::DUDivMacro:
1983 case Mips::DIVU_MMR6:
1984 case Mips::DDIVU_MM64R6:
1985 case Mips::DIV_MMR6:
1986 case Mips::DDIV_MM64R6:
1987 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1988 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1989 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1990 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1991 Warning(IDLoc, "dividing zero by zero");
1993 Warning(IDLoc, "division by zero");
1998 // For PIC code convert unconditional jump to unconditional branch.
1999 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2002 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2003 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2004 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2005 BInst.addOperand(Inst.getOperand(0));
2009 // This expansion is not in a function called by tryExpandInstruction()
2010 // because the pseudo-instruction doesn't have a distinct opcode.
2011 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2013 warnIfNoMacro(IDLoc);
2015 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2017 // We can do this expansion if there's only 1 symbol in the argument
2019 if (countMCSymbolRefExpr(JalExpr) > 1)
2020 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2022 // FIXME: This is checking the expression can be handled by the later stages
2023 // of the assembler. We ought to leave it to those later stages.
2024 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2026 // FIXME: Add support for label+offset operands (currently causes an error).
2027 // FIXME: Add support for forward-declared local symbols.
2028 // FIXME: Add expansion for when the LargeGOT option is enabled.
2029 if (JalSym->isInSection() || JalSym->isTemporary() ||
2030 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2032 // If it's a local symbol and the O32 ABI is being used, we expand to:
2034 // R_(MICRO)MIPS_GOT16 label
2035 // addiu $25, $25, 0
2036 // R_(MICRO)MIPS_LO16 label
2038 const MCExpr *Got16RelocExpr =
2039 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2040 const MCExpr *Lo16RelocExpr =
2041 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2043 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2044 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2045 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2046 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2047 } else if (isABI_N32() || isABI_N64()) {
2048 // If it's a local symbol and the N32/N64 ABIs are being used,
2050 // lw/ld $25, 0($gp)
2051 // R_(MICRO)MIPS_GOT_DISP label
2053 const MCExpr *GotDispRelocExpr =
2054 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2056 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2057 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2061 // If it's an external/weak symbol, we expand to:
2062 // lw/ld $25, 0($gp)
2063 // R_(MICRO)MIPS_CALL16 label
2065 const MCExpr *Call16RelocExpr =
2066 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2068 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2069 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2073 if (IsCpRestoreSet && inMicroMipsMode())
2074 JalrInst.setOpcode(Mips::JALRS_MM);
2076 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2077 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2078 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2080 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
2081 // This relocation is supposed to be an optimization hint for the linker
2082 // and is not necessary for correctness.
2085 ExpandedJalSym = true;
2088 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2089 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2090 // Check the offset of memory operand, if it is a symbol
2091 // reference or immediate we may have to expand instructions.
2092 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2093 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2094 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2095 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2096 MCOperand &Op = Inst.getOperand(i);
2098 int MemOffset = Op.getImm();
2099 if (MemOffset < -32768 || MemOffset > 32767) {
2100 // Offset can't exceed 16bit value.
2101 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
2102 return getParser().hasPendingError();
2104 } else if (Op.isExpr()) {
2105 const MCExpr *Expr = Op.getExpr();
2106 if (Expr->getKind() == MCExpr::SymbolRef) {
2107 const MCSymbolRefExpr *SR =
2108 static_cast<const MCSymbolRefExpr *>(Expr);
2109 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2111 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2112 return getParser().hasPendingError();
2114 } else if (!isEvaluated(Expr)) {
2115 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2116 return getParser().hasPendingError();
2123 if (inMicroMipsMode()) {
2124 if (MCID.mayLoad()) {
2125 // Try to create 16-bit GP relative load instruction.
2126 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2127 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2128 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2129 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2130 MCOperand &Op = Inst.getOperand(i);
2132 int MemOffset = Op.getImm();
2133 MCOperand &DstReg = Inst.getOperand(0);
2134 MCOperand &BaseReg = Inst.getOperand(1);
2135 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2136 getContext().getRegisterInfo()->getRegClass(
2137 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2138 (BaseReg.getReg() == Mips::GP ||
2139 BaseReg.getReg() == Mips::GP_64)) {
2141 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2150 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2155 switch (Inst.getOpcode()) {
2158 case Mips::ADDIUSP_MM:
2159 Opnd = Inst.getOperand(0);
2161 return Error(IDLoc, "expected immediate operand kind");
2162 Imm = Opnd.getImm();
2163 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2165 return Error(IDLoc, "immediate operand value out of range");
2167 case Mips::SLL16_MM:
2168 case Mips::SRL16_MM:
2169 Opnd = Inst.getOperand(2);
2171 return Error(IDLoc, "expected immediate operand kind");
2172 Imm = Opnd.getImm();
2173 if (Imm < 1 || Imm > 8)
2174 return Error(IDLoc, "immediate operand value out of range");
2177 Opnd = Inst.getOperand(1);
2179 return Error(IDLoc, "expected immediate operand kind");
2180 Imm = Opnd.getImm();
2181 if (Imm < -1 || Imm > 126)
2182 return Error(IDLoc, "immediate operand value out of range");
2184 case Mips::ADDIUR2_MM:
2185 Opnd = Inst.getOperand(2);
2187 return Error(IDLoc, "expected immediate operand kind");
2188 Imm = Opnd.getImm();
2189 if (!(Imm == 1 || Imm == -1 ||
2190 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2191 return Error(IDLoc, "immediate operand value out of range");
2193 case Mips::ANDI16_MM:
2194 Opnd = Inst.getOperand(2);
2196 return Error(IDLoc, "expected immediate operand kind");
2197 Imm = Opnd.getImm();
2198 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2199 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2200 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2201 return Error(IDLoc, "immediate operand value out of range");
2203 case Mips::LBU16_MM:
2204 Opnd = Inst.getOperand(2);
2206 return Error(IDLoc, "expected immediate operand kind");
2207 Imm = Opnd.getImm();
2208 if (Imm < -1 || Imm > 14)
2209 return Error(IDLoc, "immediate operand value out of range");
2212 case Mips::SB16_MMR6:
2213 Opnd = Inst.getOperand(2);
2215 return Error(IDLoc, "expected immediate operand kind");
2216 Imm = Opnd.getImm();
2217 if (Imm < 0 || Imm > 15)
2218 return Error(IDLoc, "immediate operand value out of range");
2220 case Mips::LHU16_MM:
2222 case Mips::SH16_MMR6:
2223 Opnd = Inst.getOperand(2);
2225 return Error(IDLoc, "expected immediate operand kind");
2226 Imm = Opnd.getImm();
2227 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2228 return Error(IDLoc, "immediate operand value out of range");
2232 case Mips::SW16_MMR6:
2233 Opnd = Inst.getOperand(2);
2235 return Error(IDLoc, "expected immediate operand kind");
2236 Imm = Opnd.getImm();
2237 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2238 return Error(IDLoc, "immediate operand value out of range");
2240 case Mips::ADDIUPC_MM:
2241 MCOperand Opnd = Inst.getOperand(1);
2243 return Error(IDLoc, "expected immediate operand kind");
2244 int Imm = Opnd.getImm();
2245 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2246 return Error(IDLoc, "immediate operand value out of range");
2251 bool FillDelaySlot =
2252 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2254 TOut.emitDirectiveSetNoReorder();
2256 MacroExpanderResultTy ExpandResult =
2257 tryExpandInstruction(Inst, IDLoc, Out, STI);
2258 switch (ExpandResult) {
2260 Out.EmitInstruction(Inst, *STI);
2268 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2269 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2270 if (inMicroMipsMode())
2271 TOut.setUsesMicroMips();
2273 // If this instruction has a delay slot and .set reorder is active,
2274 // emit a NOP after it.
2275 if (FillDelaySlot) {
2276 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2277 TOut.emitDirectiveSetReorder();
2280 if ((Inst.getOpcode() == Mips::JalOneReg ||
2281 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2282 isPicAndNotNxxAbi()) {
2283 if (IsCpRestoreSet) {
2284 // We need a NOP between the JALR and the LW:
2285 // If .set reorder has been used, we've already emitted a NOP.
2286 // If .set noreorder has been used, we need to emit a NOP at this point.
2287 if (!AssemblerOptions.back()->isReorder())
2288 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2291 // Load the $gp from the stack.
2292 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2294 Warning(IDLoc, "no .cprestore used in PIC mode");
2300 MipsAsmParser::MacroExpanderResultTy
2301 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2302 const MCSubtargetInfo *STI) {
2303 switch (Inst.getOpcode()) {
2305 return MER_NotAMacro;
2306 case Mips::LoadImm32:
2307 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2308 case Mips::LoadImm64:
2309 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2310 case Mips::LoadAddrImm32:
2311 case Mips::LoadAddrImm64:
2312 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2313 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2314 "expected immediate operand kind");
2316 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2318 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2322 case Mips::LoadAddrReg32:
2323 case Mips::LoadAddrReg64:
2324 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2325 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2326 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2327 "expected immediate operand kind");
2329 return expandLoadAddress(Inst.getOperand(0).getReg(),
2330 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2331 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2335 case Mips::B_MM_Pseudo:
2336 case Mips::B_MMR6_Pseudo:
2337 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2341 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2343 case Mips::JalOneReg:
2344 case Mips::JalTwoReg:
2345 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2348 case Mips::BEQLImmMacro:
2349 case Mips::BNELImmMacro:
2350 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2367 case Mips::BLTImmMacro:
2368 case Mips::BLEImmMacro:
2369 case Mips::BGEImmMacro:
2370 case Mips::BGTImmMacro:
2371 case Mips::BLTUImmMacro:
2372 case Mips::BLEUImmMacro:
2373 case Mips::BGEUImmMacro:
2374 case Mips::BGTUImmMacro:
2375 case Mips::BLTLImmMacro:
2376 case Mips::BLELImmMacro:
2377 case Mips::BGELImmMacro:
2378 case Mips::BGTLImmMacro:
2379 case Mips::BLTULImmMacro:
2380 case Mips::BLEULImmMacro:
2381 case Mips::BGEULImmMacro:
2382 case Mips::BGTULImmMacro:
2383 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2384 case Mips::SDivMacro:
2385 case Mips::SDivIMacro:
2386 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2388 case Mips::DSDivMacro:
2389 case Mips::DSDivIMacro:
2390 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2392 case Mips::UDivMacro:
2393 case Mips::UDivIMacro:
2394 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2396 case Mips::DUDivMacro:
2397 case Mips::DUDivIMacro:
2398 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2400 case Mips::PseudoTRUNC_W_S:
2401 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2403 case Mips::PseudoTRUNC_W_D32:
2404 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2406 case Mips::PseudoTRUNC_W_D:
2407 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2410 case Mips::LoadImmSingleGPR:
2411 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2414 case Mips::LoadImmSingleFGR:
2415 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2418 case Mips::LoadImmDoubleGPR:
2419 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2422 case Mips::LoadImmDoubleFGR:
2423 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2426 case Mips::LoadImmDoubleFGR_32:
2427 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2431 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2433 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2435 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2438 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2440 case Mips::NORImm64:
2441 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2442 case Mips::SLTImm64:
2443 if (isInt<16>(Inst.getOperand(2).getImm())) {
2444 Inst.setOpcode(Mips::SLTi64);
2445 return MER_NotAMacro;
2447 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::SLTUImm64:
2449 if (isInt<16>(Inst.getOperand(2).getImm())) {
2450 Inst.setOpcode(Mips::SLTiu64);
2451 return MER_NotAMacro;
2453 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2454 case Mips::ADDi: case Mips::ADDi_MM:
2455 case Mips::ADDiu: case Mips::ADDiu_MM:
2456 case Mips::SLTi: case Mips::SLTi_MM:
2457 case Mips::SLTiu: case Mips::SLTiu_MM:
2458 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2459 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2460 int64_t ImmValue = Inst.getOperand(2).getImm();
2461 if (isInt<16>(ImmValue))
2462 return MER_NotAMacro;
2463 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2466 return MER_NotAMacro;
2467 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2468 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2469 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2470 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2471 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2472 int64_t ImmValue = Inst.getOperand(2).getImm();
2473 if (isUInt<16>(ImmValue))
2474 return MER_NotAMacro;
2475 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2478 return MER_NotAMacro;
2481 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2487 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2491 case Mips::ABSMacro:
2492 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 case Mips::MULImmMacro:
2494 case Mips::DMULImmMacro:
2495 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2496 case Mips::MULOMacro:
2497 case Mips::DMULOMacro:
2498 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2499 case Mips::MULOUMacro:
2500 case Mips::DMULOUMacro:
2501 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2502 case Mips::DMULMacro:
2503 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2506 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2507 Inst.getOpcode() == Mips::LDMacro)
2510 case Mips::SEQMacro:
2511 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2512 case Mips::SEQIMacro:
2513 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2517 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2519 const MCSubtargetInfo *STI) {
2520 MipsTargetStreamer &TOut = getTargetStreamer();
2522 // Create a JALR instruction which is going to replace the pseudo-JAL.
2524 JalrInst.setLoc(IDLoc);
2525 const MCOperand FirstRegOp = Inst.getOperand(0);
2526 const unsigned Opcode = Inst.getOpcode();
2528 if (Opcode == Mips::JalOneReg) {
2529 // jal $rs => jalr $rs
2530 if (IsCpRestoreSet && inMicroMipsMode()) {
2531 JalrInst.setOpcode(Mips::JALRS16_MM);
2532 JalrInst.addOperand(FirstRegOp);
2533 } else if (inMicroMipsMode()) {
2534 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2535 JalrInst.addOperand(FirstRegOp);
2537 JalrInst.setOpcode(Mips::JALR);
2538 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2539 JalrInst.addOperand(FirstRegOp);
2541 } else if (Opcode == Mips::JalTwoReg) {
2542 // jal $rd, $rs => jalr $rd, $rs
2543 if (IsCpRestoreSet && inMicroMipsMode())
2544 JalrInst.setOpcode(Mips::JALRS_MM);
2546 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2547 JalrInst.addOperand(FirstRegOp);
2548 const MCOperand SecondRegOp = Inst.getOperand(1);
2549 JalrInst.addOperand(SecondRegOp);
2551 Out.EmitInstruction(JalrInst, *STI);
2553 // If .set reorder is active and branch instruction has a delay slot,
2554 // emit a NOP after it.
2555 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2556 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2557 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2563 /// Can the value be represented by a unsigned N-bit value and a shift left?
2564 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2565 unsigned BitNum = findFirstSet(x);
2567 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2570 /// Load (or add) an immediate into a register.
2572 /// @param ImmValue The immediate to load.
2573 /// @param DstReg The register that will hold the immediate.
2574 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2575 /// for a simple initialization.
2576 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2577 /// @param IsAddress True if the immediate represents an address. False if it
2579 /// @param IDLoc Location of the immediate in the source file.
2580 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2581 unsigned SrcReg, bool Is32BitImm,
2582 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2583 const MCSubtargetInfo *STI) {
2584 MipsTargetStreamer &TOut = getTargetStreamer();
2586 if (!Is32BitImm && !isGP64bit()) {
2587 Error(IDLoc, "instruction requires a 64-bit architecture");
2592 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2593 // Sign extend up to 64-bit so that the predicates match the hardware
2594 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2596 ImmValue = SignExtend64<32>(ImmValue);
2598 Error(IDLoc, "instruction requires a 32-bit immediate");
2603 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2604 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2606 bool UseSrcReg = false;
2607 if (SrcReg != Mips::NoRegister)
2610 unsigned TmpReg = DstReg;
2612 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2613 // At this point we need AT to perform the expansions and we exit if it is
2615 unsigned ATReg = getATReg(IDLoc);
2621 if (isInt<16>(ImmValue)) {
2625 // This doesn't quite follow the usual ABI expectations for N32 but matches
2626 // traditional assembler behaviour. N32 would normally use addiu for both
2627 // integers and addresses.
2628 if (IsAddress && !Is32BitImm) {
2629 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2633 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2637 if (isUInt<16>(ImmValue)) {
2638 unsigned TmpReg = DstReg;
2639 if (SrcReg == DstReg) {
2640 TmpReg = getATReg(IDLoc);
2645 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2647 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2651 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2652 warnIfNoMacro(IDLoc);
2654 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2655 uint16_t Bits15To0 = ImmValue & 0xffff;
2656 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2657 // Traditional behaviour seems to special case this particular value. It's
2658 // not clear why other masks are handled differently.
2659 if (ImmValue == 0xffffffff) {
2660 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2661 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2663 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2667 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2669 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2670 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2672 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2674 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2678 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2680 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2682 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2686 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2688 Error(IDLoc, "instruction requires a 32-bit immediate");
2692 // Traditionally, these immediates are shifted as little as possible and as
2693 // such we align the most significant bit to bit 15 of our temporary.
2694 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2695 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2696 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2697 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2698 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2699 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2702 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2707 warnIfNoMacro(IDLoc);
2709 // The remaining case is packed with a sequence of dsll and ori with zeros
2710 // being omitted and any neighbouring dsll's being coalesced.
2711 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2713 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2714 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2718 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2719 // skip it and defer the shift to the next chunk.
2720 unsigned ShiftCarriedForwards = 16;
2721 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2722 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2724 if (ImmChunk != 0) {
2725 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2726 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2727 ShiftCarriedForwards = 0;
2730 ShiftCarriedForwards += 16;
2732 ShiftCarriedForwards -= 16;
2734 // Finish any remaining shifts left by trailing zeros.
2735 if (ShiftCarriedForwards)
2736 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2739 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2744 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2745 MCStreamer &Out, const MCSubtargetInfo *STI) {
2746 const MCOperand &ImmOp = Inst.getOperand(1);
2747 assert(ImmOp.isImm() && "expected immediate operand kind");
2748 const MCOperand &DstRegOp = Inst.getOperand(0);
2749 assert(DstRegOp.isReg() && "expected register operand kind");
2751 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2752 Is32BitImm, false, IDLoc, Out, STI))
2758 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2759 const MCOperand &Offset,
2760 bool Is32BitAddress, SMLoc IDLoc,
2762 const MCSubtargetInfo *STI) {
2763 // la can't produce a usable address when addresses are 64-bit.
2764 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2765 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2766 // We currently can't do this because we depend on the equality
2767 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2768 Error(IDLoc, "la used to load 64-bit address");
2769 // Continue as if we had 'dla' instead.
2770 Is32BitAddress = false;
2774 // dla requires 64-bit addresses.
2775 if (!Is32BitAddress && !hasMips3()) {
2776 Error(IDLoc, "instruction requires a 64-bit architecture");
2780 if (!Offset.isImm())
2781 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2782 Is32BitAddress, IDLoc, Out, STI);
2784 if (!ABI.ArePtrs64bit()) {
2785 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2786 Is32BitAddress = true;
2789 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2793 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2794 unsigned DstReg, unsigned SrcReg,
2795 bool Is32BitSym, SMLoc IDLoc,
2797 const MCSubtargetInfo *STI) {
2798 // FIXME: These expansions do not respect -mxgot.
2799 MipsTargetStreamer &TOut = getTargetStreamer();
2800 bool UseSrcReg = SrcReg != Mips::NoRegister;
2801 warnIfNoMacro(IDLoc);
2803 if (inPicMode() && ABI.IsO32()) {
2805 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2806 Error(IDLoc, "expected relocatable expression");
2809 if (Res.getSymB() != nullptr) {
2810 Error(IDLoc, "expected relocatable expression with only one symbol");
2814 // The case where the result register is $25 is somewhat special. If the
2815 // symbol in the final relocation is external and not modified with a
2816 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2817 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2818 Res.getConstant() == 0 &&
2819 !(Res.getSymA()->getSymbol().isInSection() ||
2820 Res.getSymA()->getSymbol().isTemporary() ||
2821 (Res.getSymA()->getSymbol().isELF() &&
2822 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2824 const MCExpr *CallExpr =
2825 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2826 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2827 MCOperand::createExpr(CallExpr), IDLoc, STI);
2831 // The remaining cases are:
2832 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2833 // >addiu $tmp, $tmp, %lo(offset)
2834 // >addiu $rd, $tmp, $rs
2835 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2836 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2837 // >addiu $rd, $tmp, $rs
2838 // The addiu's marked with a '>' may be omitted if they are redundant. If
2839 // this happens then the last instruction must use $rd as the result
2841 const MipsMCExpr *GotExpr =
2842 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2843 const MCExpr *LoExpr = nullptr;
2844 if (Res.getSymA()->getSymbol().isInSection() ||
2845 Res.getSymA()->getSymbol().isTemporary())
2846 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2847 else if (Res.getConstant() != 0) {
2848 // External symbols fully resolve the symbol with just the %got(symbol)
2849 // but we must still account for any offset to the symbol for expressions
2851 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2854 unsigned TmpReg = DstReg;
2856 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2858 // If $rs is the same as $rd, we need to use AT.
2859 // If it is not available we exit.
2860 unsigned ATReg = getATReg(IDLoc);
2866 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2867 MCOperand::createExpr(GotExpr), IDLoc, STI);
2870 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2874 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2879 if (inPicMode() && ABI.ArePtrs64bit()) {
2881 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2882 Error(IDLoc, "expected relocatable expression");
2885 if (Res.getSymB() != nullptr) {
2886 Error(IDLoc, "expected relocatable expression with only one symbol");
2890 // The case where the result register is $25 is somewhat special. If the
2891 // symbol in the final relocation is external and not modified with a
2892 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2893 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2894 Res.getConstant() == 0 &&
2895 !(Res.getSymA()->getSymbol().isInSection() ||
2896 Res.getSymA()->getSymbol().isTemporary() ||
2897 (Res.getSymA()->getSymbol().isELF() &&
2898 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2900 const MCExpr *CallExpr =
2901 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2902 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2903 MCOperand::createExpr(CallExpr), IDLoc, STI);
2907 // The remaining cases are:
2908 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2909 // >daddiu $tmp, $tmp, offset
2910 // >daddu $rd, $tmp, $rs
2911 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2912 // this happens then the last instruction must use $rd as the result
2914 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2917 const MCExpr *LoExpr = nullptr;
2918 if (Res.getConstant() != 0) {
2919 // Symbols fully resolve with just the %got_disp(symbol) but we
2920 // must still account for any offset to the symbol for
2921 // expressions like symbol+8.
2922 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2924 // FIXME: Offsets greater than 16 bits are not yet implemented.
2925 // FIXME: The correct range is a 32-bit sign-extended number.
2926 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2927 Error(IDLoc, "macro instruction uses large offset, which is not "
2928 "currently supported");
2933 unsigned TmpReg = DstReg;
2935 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2937 // If $rs is the same as $rd, we need to use AT.
2938 // If it is not available we exit.
2939 unsigned ATReg = getATReg(IDLoc);
2945 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
2946 MCOperand::createExpr(GotExpr), IDLoc, STI);
2949 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2953 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2958 const MipsMCExpr *HiExpr =
2959 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2960 const MipsMCExpr *LoExpr =
2961 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2963 // This is the 64-bit symbol address expansion.
2964 if (ABI.ArePtrs64bit() && isGP64bit()) {
2965 // We need AT for the 64-bit expansion in the cases where the optional
2966 // source register is the destination register and for the superscalar
2969 // If it is not available we exit if the destination is the same as the
2972 const MipsMCExpr *HighestExpr =
2973 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2974 const MipsMCExpr *HigherExpr =
2975 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2978 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
2980 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
2981 unsigned ATReg = getATReg(IDLoc);
2983 // If $rs is the same as $rd:
2984 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2985 // daddiu $at, $at, %higher(sym)
2986 // dsll $at, $at, 16
2987 // daddiu $at, $at, %hi(sym)
2988 // dsll $at, $at, 16
2989 // daddiu $at, $at, %lo(sym)
2990 // daddu $rd, $at, $rd
2991 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2993 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2994 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2995 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2996 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2998 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2999 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3001 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3004 } else if (canUseATReg() && !RdRegIsRsReg) {
3005 unsigned ATReg = getATReg(IDLoc);
3007 // If the $rs is different from $rd or if $rs isn't specified and we
3008 // have $at available:
3009 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3010 // lui $at, %hi(sym)
3011 // daddiu $rd, $rd, %higher(sym)
3012 // daddiu $at, $at, %lo(sym)
3013 // dsll32 $rd, $rd, 0
3014 // daddu $rd, $rd, $at
3015 // (daddu $rd, $rd, $rs)
3017 // Which is preferred for superscalar issue.
3018 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3020 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3021 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3022 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3023 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3025 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3026 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3028 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3031 } else if (!canUseATReg() && !RdRegIsRsReg) {
3032 // Otherwise, synthesize the address in the destination register
3034 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3035 // daddiu $rd, $rd, %higher(sym)
3036 // dsll $rd, $rd, 16
3037 // daddiu $rd, $rd, %hi(sym)
3038 // dsll $rd, $rd, 16
3039 // daddiu $rd, $rd, %lo(sym)
3040 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3042 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3043 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3044 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3045 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3046 MCOperand::createExpr(HiExpr), IDLoc, STI);
3047 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3048 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3049 MCOperand::createExpr(LoExpr), IDLoc, STI);
3051 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3055 // We have a case where SrcReg == DstReg and we don't have $at
3056 // available. We can't expand this case, so error out appropriately.
3057 assert(SrcReg == DstReg && !canUseATReg() &&
3058 "Could have expanded dla but didn't?");
3059 reportParseError(IDLoc,
3060 "pseudo-instruction requires $at, which is not available");
3065 // And now, the 32-bit symbol address expansion:
3066 // If $rs is the same as $rd:
3067 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3068 // ori $at, $at, %lo(sym)
3069 // addu $rd, $at, $rd
3070 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3071 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3072 // ori $rd, $rd, %lo(sym)
3073 // (addu $rd, $rd, $rs)
3074 unsigned TmpReg = DstReg;
3076 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3077 // If $rs is the same as $rd, we need to use AT.
3078 // If it is not available we exit.
3079 unsigned ATReg = getATReg(IDLoc);
3085 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3086 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3090 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3093 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3098 // Each double-precision register DO-D15 overlaps with two of the single
3099 // precision registers F0-F31. As an example, all of the following hold true:
3100 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3101 static unsigned nextReg(unsigned Reg) {
3102 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3103 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3105 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3106 case Mips::ZERO: return Mips::AT;
3107 case Mips::AT: return Mips::V0;
3108 case Mips::V0: return Mips::V1;
3109 case Mips::V1: return Mips::A0;
3110 case Mips::A0: return Mips::A1;
3111 case Mips::A1: return Mips::A2;
3112 case Mips::A2: return Mips::A3;
3113 case Mips::A3: return Mips::T0;
3114 case Mips::T0: return Mips::T1;
3115 case Mips::T1: return Mips::T2;
3116 case Mips::T2: return Mips::T3;
3117 case Mips::T3: return Mips::T4;
3118 case Mips::T4: return Mips::T5;
3119 case Mips::T5: return Mips::T6;
3120 case Mips::T6: return Mips::T7;
3121 case Mips::T7: return Mips::S0;
3122 case Mips::S0: return Mips::S1;
3123 case Mips::S1: return Mips::S2;
3124 case Mips::S2: return Mips::S3;
3125 case Mips::S3: return Mips::S4;
3126 case Mips::S4: return Mips::S5;
3127 case Mips::S5: return Mips::S6;
3128 case Mips::S6: return Mips::S7;
3129 case Mips::S7: return Mips::T8;
3130 case Mips::T8: return Mips::T9;
3131 case Mips::T9: return Mips::K0;
3132 case Mips::K0: return Mips::K1;
3133 case Mips::K1: return Mips::GP;
3134 case Mips::GP: return Mips::SP;
3135 case Mips::SP: return Mips::FP;
3136 case Mips::FP: return Mips::RA;
3137 case Mips::RA: return Mips::ZERO;
3138 case Mips::D0: return Mips::F1;
3139 case Mips::D1: return Mips::F3;
3140 case Mips::D2: return Mips::F5;
3141 case Mips::D3: return Mips::F7;
3142 case Mips::D4: return Mips::F9;
3143 case Mips::D5: return Mips::F11;
3144 case Mips::D6: return Mips::F13;
3145 case Mips::D7: return Mips::F15;
3146 case Mips::D8: return Mips::F17;
3147 case Mips::D9: return Mips::F19;
3148 case Mips::D10: return Mips::F21;
3149 case Mips::D11: return Mips::F23;
3150 case Mips::D12: return Mips::F25;
3151 case Mips::D13: return Mips::F27;
3152 case Mips::D14: return Mips::F29;
3153 case Mips::D15: return Mips::F31;
3157 // FIXME: This method is too general. In principle we should compute the number
3158 // of instructions required to synthesize the immediate inline compared to
3159 // synthesizing the address inline and relying on non .text sections.
3160 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3161 // likely to yield a much larger benefit as we have to synthesize a 64bit
3162 // address to load a 64 bit value.
3163 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3165 unsigned ATReg = getATReg(IDLoc);
3170 const MCExpr *GotSym =
3171 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3172 const MipsMCExpr *GotExpr =
3173 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3175 if(isABI_O32() || isABI_N32()) {
3176 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3178 } else { //isABI_N64()
3179 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3182 } else { //!IsPicEnabled
3183 const MCExpr *HiSym =
3184 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3185 const MipsMCExpr *HiExpr =
3186 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3188 // FIXME: This is technically correct but gives a different result to gas,
3189 // but gas is incomplete there (it has a fixme noting it doesn't work with
3190 // 64-bit addresses).
3191 // FIXME: With -msym32 option, the address expansion for N64 should probably
3192 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3193 // symbol's value is considered sign extended.
3194 if(isABI_O32() || isABI_N32()) {
3195 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3196 } else { //isABI_N64()
3197 const MCExpr *HighestSym =
3198 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3199 const MipsMCExpr *HighestExpr =
3200 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3201 const MCExpr *HigherSym =
3202 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3203 const MipsMCExpr *HigherExpr =
3204 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3206 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3208 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3209 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3210 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3211 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3213 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3219 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3220 bool Is64FPU, SMLoc IDLoc,
3222 const MCSubtargetInfo *STI) {
3223 MipsTargetStreamer &TOut = getTargetStreamer();
3224 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3225 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3226 "Invalid instruction operand.");
3228 unsigned FirstReg = Inst.getOperand(0).getReg();
3229 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3231 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3232 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3233 // exponent field), convert it to double (e.g. 1 to 1.0)
3234 if ((HiImmOp64 & 0x7ff00000) == 0) {
3235 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3236 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3239 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3240 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3243 // Conversion of a double in an uint64_t to a float in a uint32_t,
3244 // retaining the bit pattern of a float.
3246 double doubleImm = BitsToDouble(ImmOp64);
3247 float tmp_float = static_cast<float>(doubleImm);
3248 ImmOp32 = FloatToBits(tmp_float);
3251 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3256 unsigned ATReg = getATReg(IDLoc);
3259 if (LoImmOp64 == 0) {
3260 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3263 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3267 MCSection *CS = getStreamer().getCurrentSectionOnly();
3268 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3269 // where appropriate.
3270 MCSection *ReadOnlySection = getContext().getELFSection(
3271 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3273 MCSymbol *Sym = getContext().createTempSymbol();
3274 const MCExpr *LoSym =
3275 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3276 const MipsMCExpr *LoExpr =
3277 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3279 getStreamer().SwitchSection(ReadOnlySection);
3280 getStreamer().EmitLabel(Sym, IDLoc);
3281 getStreamer().EmitIntValue(ImmOp32, 4);
3282 getStreamer().SwitchSection(CS);
3284 if(emitPartialAddress(TOut, IDLoc, Sym))
3286 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3287 MCOperand::createExpr(LoExpr), IDLoc, STI);
3293 unsigned ATReg = getATReg(IDLoc);
3298 if (LoImmOp64 == 0) {
3299 if(isABI_N32() || isABI_N64()) {
3300 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3305 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3309 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3316 MCSection *CS = getStreamer().getCurrentSectionOnly();
3317 MCSection *ReadOnlySection = getContext().getELFSection(
3318 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3320 MCSymbol *Sym = getContext().createTempSymbol();
3321 const MCExpr *LoSym =
3322 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3323 const MipsMCExpr *LoExpr =
3324 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3326 getStreamer().SwitchSection(ReadOnlySection);
3327 getStreamer().EmitLabel(Sym, IDLoc);
3328 getStreamer().EmitIntValue(HiImmOp64, 4);
3329 getStreamer().EmitIntValue(LoImmOp64, 4);
3330 getStreamer().SwitchSection(CS);
3332 if(emitPartialAddress(TOut, IDLoc, Sym))
3335 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3336 MCOperand::createExpr(LoExpr), IDLoc, STI);
3338 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3339 MCOperand::createExpr(LoExpr), IDLoc, STI);
3341 if(isABI_N32() || isABI_N64())
3342 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3344 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3345 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3348 } else { // if(!IsGPR && !IsSingle)
3349 if ((LoImmOp64 == 0) &&
3350 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3351 // FIXME: In the case where the constant is zero, we can load the
3352 // register directly from the zero register.
3353 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3356 if (isABI_N32() || isABI_N64())
3357 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3358 else if (hasMips32r2()) {
3359 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3360 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3362 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3363 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3368 MCSection *CS = getStreamer().getCurrentSectionOnly();
3369 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3370 // where appropriate.
3371 MCSection *ReadOnlySection = getContext().getELFSection(
3372 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3374 MCSymbol *Sym = getContext().createTempSymbol();
3375 const MCExpr *LoSym =
3376 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3377 const MipsMCExpr *LoExpr =
3378 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3380 getStreamer().SwitchSection(ReadOnlySection);
3381 getStreamer().EmitLabel(Sym, IDLoc);
3382 getStreamer().EmitIntValue(HiImmOp64, 4);
3383 getStreamer().EmitIntValue(LoImmOp64, 4);
3384 getStreamer().SwitchSection(CS);
3386 if(emitPartialAddress(TOut, IDLoc, Sym))
3388 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3389 MCOperand::createExpr(LoExpr), IDLoc, STI);
3394 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3396 const MCSubtargetInfo *STI) {
3397 MipsTargetStreamer &TOut = getTargetStreamer();
3399 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3400 "unexpected number of operands");
3402 MCOperand Offset = Inst.getOperand(0);
3403 if (Offset.isExpr()) {
3405 Inst.setOpcode(Mips::BEQ_MM);
3406 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3407 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3408 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3410 assert(Offset.isImm() && "expected immediate operand kind");
3411 if (isInt<11>(Offset.getImm())) {
3412 // If offset fits into 11 bits then this instruction becomes microMIPS
3413 // 16-bit unconditional branch instruction.
3414 if (inMicroMipsMode())
3415 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3417 if (!isInt<17>(Offset.getImm()))
3418 return Error(IDLoc, "branch target out of range");
3419 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3420 return Error(IDLoc, "branch to misaligned address");
3422 Inst.setOpcode(Mips::BEQ_MM);
3423 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3424 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3425 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3428 Out.EmitInstruction(Inst, *STI);
3430 // If .set reorder is active and branch instruction has a delay slot,
3431 // emit a NOP after it.
3432 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3433 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3434 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3439 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3440 const MCSubtargetInfo *STI) {
3441 MipsTargetStreamer &TOut = getTargetStreamer();
3442 const MCOperand &DstRegOp = Inst.getOperand(0);
3443 assert(DstRegOp.isReg() && "expected register operand kind");
3445 const MCOperand &ImmOp = Inst.getOperand(1);
3446 assert(ImmOp.isImm() && "expected immediate operand kind");
3448 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3449 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3450 "expected immediate or expression operand");
3452 bool IsLikely = false;
3454 unsigned OpCode = 0;
3455 switch(Inst.getOpcode()) {
3462 case Mips::BEQLImmMacro:
3463 OpCode = Mips::BEQL;
3466 case Mips::BNELImmMacro:
3467 OpCode = Mips::BNEL;
3471 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3475 int64_t ImmValue = ImmOp.getImm();
3476 if (ImmValue == 0) {
3478 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3479 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3480 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3482 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3485 warnIfNoMacro(IDLoc);
3487 unsigned ATReg = getATReg(IDLoc);
3491 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3496 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3497 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3498 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3500 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3505 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3506 const MCSubtargetInfo *STI, bool IsLoad,
3509 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3512 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3515 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3516 const MCSubtargetInfo *STI, bool IsImmOpnd) {
3517 MipsTargetStreamer &TOut = getTargetStreamer();
3519 unsigned DstReg = Inst.getOperand(0).getReg();
3520 unsigned BaseReg = Inst.getOperand(1).getReg();
3522 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3523 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3524 unsigned DstRegClassID =
3525 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3526 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3527 (DstRegClassID == Mips::GPR64RegClassID);
3530 // Try to use DstReg as the temporary.
3531 if (IsGPR && (BaseReg != DstReg)) {
3532 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3533 Inst.getOperand(2).getImm(), DstReg, IDLoc,
3538 // At this point we need AT to perform the expansions and we exit if it is
3540 unsigned ATReg = getATReg(IDLoc);
3544 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3545 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
3549 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3550 MCOperand LoOperand = MCOperand::createExpr(
3551 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3552 MCOperand HiOperand = MCOperand::createExpr(
3553 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3555 // Try to use DstReg as the temporary.
3556 if (IsGPR && (BaseReg != DstReg)) {
3557 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3558 LoOperand, DstReg, IDLoc, STI);
3562 // At this point we need AT to perform the expansions and we exit if it is
3564 unsigned ATReg = getATReg(IDLoc);
3568 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3569 LoOperand, ATReg, IDLoc, STI);
3572 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3573 const MCSubtargetInfo *STI,
3575 MipsTargetStreamer &TOut = getTargetStreamer();
3577 unsigned SrcReg = Inst.getOperand(0).getReg();
3578 unsigned BaseReg = Inst.getOperand(1).getReg();
3581 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
3582 Inst.getOperand(2).getImm(),
3583 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
3587 unsigned ATReg = getATReg(IDLoc);
3591 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3592 MCOperand LoOperand = MCOperand::createExpr(
3593 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3594 MCOperand HiOperand = MCOperand::createExpr(
3595 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3596 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
3597 LoOperand, ATReg, IDLoc, STI);
3600 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3602 const MCSubtargetInfo *STI) {
3603 unsigned OpNum = Inst.getNumOperands();
3604 unsigned Opcode = Inst.getOpcode();
3605 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3607 assert(Inst.getOperand(OpNum - 1).isImm() &&
3608 Inst.getOperand(OpNum - 2).isReg() &&
3609 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3611 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3612 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3613 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3614 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3615 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3616 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3617 // It can be implemented as SWM16 or LWM16 instruction.
3618 if (inMicroMipsMode() && hasMips32r6())
3619 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3621 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3624 Inst.setOpcode(NewOpcode);
3625 Out.EmitInstruction(Inst, *STI);
3629 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3631 const MCSubtargetInfo *STI) {
3632 MipsTargetStreamer &TOut = getTargetStreamer();
3633 bool EmittedNoMacroWarning = false;
3634 unsigned PseudoOpcode = Inst.getOpcode();
3635 unsigned SrcReg = Inst.getOperand(0).getReg();
3636 const MCOperand &TrgOp = Inst.getOperand(1);
3637 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3639 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3640 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3644 TrgReg = TrgOp.getReg();
3645 else if (TrgOp.isImm()) {
3646 warnIfNoMacro(IDLoc);
3647 EmittedNoMacroWarning = true;
3649 TrgReg = getATReg(IDLoc);
3653 switch(PseudoOpcode) {
3655 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3656 case Mips::BLTImmMacro:
3657 PseudoOpcode = Mips::BLT;
3659 case Mips::BLEImmMacro:
3660 PseudoOpcode = Mips::BLE;
3662 case Mips::BGEImmMacro:
3663 PseudoOpcode = Mips::BGE;
3665 case Mips::BGTImmMacro:
3666 PseudoOpcode = Mips::BGT;
3668 case Mips::BLTUImmMacro:
3669 PseudoOpcode = Mips::BLTU;
3671 case Mips::BLEUImmMacro:
3672 PseudoOpcode = Mips::BLEU;
3674 case Mips::BGEUImmMacro:
3675 PseudoOpcode = Mips::BGEU;
3677 case Mips::BGTUImmMacro:
3678 PseudoOpcode = Mips::BGTU;
3680 case Mips::BLTLImmMacro:
3681 PseudoOpcode = Mips::BLTL;
3683 case Mips::BLELImmMacro:
3684 PseudoOpcode = Mips::BLEL;
3686 case Mips::BGELImmMacro:
3687 PseudoOpcode = Mips::BGEL;
3689 case Mips::BGTLImmMacro:
3690 PseudoOpcode = Mips::BGTL;
3692 case Mips::BLTULImmMacro:
3693 PseudoOpcode = Mips::BLTUL;
3695 case Mips::BLEULImmMacro:
3696 PseudoOpcode = Mips::BLEUL;
3698 case Mips::BGEULImmMacro:
3699 PseudoOpcode = Mips::BGEUL;
3701 case Mips::BGTULImmMacro:
3702 PseudoOpcode = Mips::BGTUL;
3706 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3707 false, IDLoc, Out, STI))
3711 switch (PseudoOpcode) {
3716 AcceptsEquality = false;
3717 ReverseOrderSLT = false;
3718 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3719 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3720 ZeroSrcOpcode = Mips::BGTZ;
3721 ZeroTrgOpcode = Mips::BLTZ;
3727 AcceptsEquality = true;
3728 ReverseOrderSLT = true;
3729 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3730 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3731 ZeroSrcOpcode = Mips::BGEZ;
3732 ZeroTrgOpcode = Mips::BLEZ;
3738 AcceptsEquality = true;
3739 ReverseOrderSLT = false;
3740 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3741 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3742 ZeroSrcOpcode = Mips::BLEZ;
3743 ZeroTrgOpcode = Mips::BGEZ;
3749 AcceptsEquality = false;
3750 ReverseOrderSLT = true;
3751 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3752 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3753 ZeroSrcOpcode = Mips::BLTZ;
3754 ZeroTrgOpcode = Mips::BGTZ;
3757 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3760 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3761 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3762 if (IsSrcRegZero && IsTrgRegZero) {
3763 // FIXME: All of these Opcode-specific if's are needed for compatibility
3764 // with GAS' behaviour. However, they may not generate the most efficient
3765 // code in some circumstances.
3766 if (PseudoOpcode == Mips::BLT) {
3767 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3771 if (PseudoOpcode == Mips::BLE) {
3772 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3774 Warning(IDLoc, "branch is always taken");
3777 if (PseudoOpcode == Mips::BGE) {
3778 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3780 Warning(IDLoc, "branch is always taken");
3783 if (PseudoOpcode == Mips::BGT) {
3784 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3788 if (PseudoOpcode == Mips::BGTU) {
3789 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3790 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3793 if (AcceptsEquality) {
3794 // If both registers are $0 and the pseudo-branch accepts equality, it
3795 // will always be taken, so we emit an unconditional branch.
3796 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3797 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3798 Warning(IDLoc, "branch is always taken");
3801 // If both registers are $0 and the pseudo-branch does not accept
3802 // equality, it will never be taken, so we don't have to emit anything.
3805 if (IsSrcRegZero || IsTrgRegZero) {
3806 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3807 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3808 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3809 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3810 // the pseudo-branch will never be taken, so we don't emit anything.
3811 // This only applies to unsigned pseudo-branches.
3814 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3815 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3816 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3817 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3818 // the pseudo-branch will always be taken, so we emit an unconditional
3820 // This only applies to unsigned pseudo-branches.
3821 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3822 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3823 Warning(IDLoc, "branch is always taken");
3827 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3828 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3829 // the pseudo-branch will be taken only when the non-zero register is
3830 // different from 0, so we emit a BNEZ.
3832 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3833 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3834 // the pseudo-branch will be taken only when the non-zero register is
3835 // equal to 0, so we emit a BEQZ.
3837 // Because only BLEU and BGEU branch on equality, we can use the
3838 // AcceptsEquality variable to decide when to emit the BEQZ.
3839 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3840 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3841 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3844 // If we have a signed pseudo-branch and one of the registers is $0,
3845 // we can use an appropriate compare-to-zero branch. We select which one
3846 // to use in the switch statement above.
3847 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3848 IsSrcRegZero ? TrgReg : SrcReg,
3849 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3853 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3854 // expansions. If it is not available, we return.
3855 unsigned ATRegNum = getATReg(IDLoc);
3859 if (!EmittedNoMacroWarning)
3860 warnIfNoMacro(IDLoc);
3862 // SLT fits well with 2 of our 4 pseudo-branches:
3863 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3864 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3865 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3866 // This is accomplished by using a BNEZ with the result of the SLT.
3868 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3869 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3870 // Because only BGE and BLE branch on equality, we can use the
3871 // AcceptsEquality variable to decide when to emit the BEQZ.
3872 // Note that the order of the SLT arguments doesn't change between
3875 // The same applies to the unsigned variants, except that SLTu is used
3877 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3878 ReverseOrderSLT ? TrgReg : SrcReg,
3879 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3881 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3882 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3883 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3888 // Expand a integer division macro.
3890 // Notably we don't have to emit a warning when encountering $rt as the $zero
3891 // register, or 0 as an immediate. processInstruction() has already done that.
3893 // The destination register can only be $zero when expanding (S)DivIMacro or
3896 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3897 const MCSubtargetInfo *STI, const bool IsMips64,
3898 const bool Signed) {
3899 MipsTargetStreamer &TOut = getTargetStreamer();
3901 warnIfNoMacro(IDLoc);
3903 const MCOperand &RdRegOp = Inst.getOperand(0);
3904 assert(RdRegOp.isReg() && "expected register operand kind");
3905 unsigned RdReg = RdRegOp.getReg();
3907 const MCOperand &RsRegOp = Inst.getOperand(1);
3908 assert(RsRegOp.isReg() && "expected register operand kind");
3909 unsigned RsReg = RsRegOp.getReg();
3914 const MCOperand &RtOp = Inst.getOperand(2);
3915 assert((RtOp.isReg() || RtOp.isImm()) &&
3916 "expected register or immediate operand kind");
3918 RtReg = RtOp.getReg();
3920 ImmValue = RtOp.getImm();
3927 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3928 ZeroReg = Mips::ZERO_64;
3931 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3932 ZeroReg = Mips::ZERO;
3936 bool UseTraps = useTraps();
3939 unsigned ATReg = getATReg(IDLoc);
3943 if (ImmValue == 0) {
3945 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3947 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3951 if (ImmValue == 1) {
3952 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3954 } else if (Signed && ImmValue == -1) {
3955 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3958 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
3959 false, Inst.getLoc(), Out, STI))
3961 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
3962 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3968 // If the macro expansion of (d)div(u) would always trap or break, insert
3969 // the trap/break and exit. This gives a different result to GAS. GAS has
3970 // an inconsistency/missed optimization in that not all cases are handled
3971 // equivalently. As the observed behaviour is the same, we're ok.
3972 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3974 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3977 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3981 // Temporary label for first branch traget
3982 MCContext &Context = TOut.getStreamer().getContext();
3987 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3989 // Branch to the li instruction.
3990 BrTarget = Context.createTempSymbol();
3991 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
3992 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
3995 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3998 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4002 TOut.getStreamer().EmitLabel(BrTarget);
4004 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4008 unsigned ATReg = getATReg(IDLoc);
4013 TOut.getStreamer().EmitLabel(BrTarget);
4015 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4017 // Temporary label for the second branch target.
4018 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4019 MCOperand LabelOpEnd =
4020 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4022 // Branch to the mflo instruction.
4023 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4026 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4027 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
4029 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4033 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4035 // Branch to the mflo instruction.
4036 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4037 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
4038 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4041 TOut.getStreamer().EmitLabel(BrTargetEnd);
4042 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4046 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4047 SMLoc IDLoc, MCStreamer &Out,
4048 const MCSubtargetInfo *STI) {
4049 MipsTargetStreamer &TOut = getTargetStreamer();
4051 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4052 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4053 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4055 unsigned FirstReg = Inst.getOperand(0).getReg();
4056 unsigned SecondReg = Inst.getOperand(1).getReg();
4057 unsigned ThirdReg = Inst.getOperand(2).getReg();
4059 if (hasMips1() && !hasMips2()) {
4060 unsigned ATReg = getATReg(IDLoc);
4063 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4064 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4065 TOut.emitNop(IDLoc, STI);
4066 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4067 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4068 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4069 TOut.emitNop(IDLoc, STI);
4070 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4072 FirstReg, SecondReg, IDLoc, STI);
4073 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4074 TOut.emitNop(IDLoc, STI);
4078 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4080 FirstReg, SecondReg, IDLoc, STI);
4085 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4086 MCStreamer &Out, const MCSubtargetInfo *STI) {
4087 if (hasMips32r6() || hasMips64r6()) {
4088 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4091 const MCOperand &DstRegOp = Inst.getOperand(0);
4092 assert(DstRegOp.isReg() && "expected register operand kind");
4093 const MCOperand &SrcRegOp = Inst.getOperand(1);
4094 assert(SrcRegOp.isReg() && "expected register operand kind");
4095 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4096 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4098 MipsTargetStreamer &TOut = getTargetStreamer();
4099 unsigned DstReg = DstRegOp.getReg();
4100 unsigned SrcReg = SrcRegOp.getReg();
4101 int64_t OffsetValue = OffsetImmOp.getImm();
4103 // NOTE: We always need AT for ULHU, as it is always used as the source
4104 // register for one of the LBu's.
4105 warnIfNoMacro(IDLoc);
4106 unsigned ATReg = getATReg(IDLoc);
4110 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4111 if (IsLargeOffset) {
4112 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4117 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4118 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4120 std::swap(FirstOffset, SecondOffset);
4122 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4123 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4125 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4126 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4128 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4129 FirstOffset, IDLoc, STI);
4130 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4131 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4132 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4137 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4138 const MCSubtargetInfo *STI) {
4139 if (hasMips32r6() || hasMips64r6()) {
4140 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4143 const MCOperand &DstRegOp = Inst.getOperand(0);
4144 assert(DstRegOp.isReg() && "expected register operand kind");
4145 const MCOperand &SrcRegOp = Inst.getOperand(1);
4146 assert(SrcRegOp.isReg() && "expected register operand kind");
4147 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4148 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4150 MipsTargetStreamer &TOut = getTargetStreamer();
4151 unsigned DstReg = DstRegOp.getReg();
4152 unsigned SrcReg = SrcRegOp.getReg();
4153 int64_t OffsetValue = OffsetImmOp.getImm();
4155 warnIfNoMacro(IDLoc);
4156 unsigned ATReg = getATReg(IDLoc);
4160 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4161 if (IsLargeOffset) {
4162 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4167 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4168 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4170 std::swap(FirstOffset, SecondOffset);
4172 if (IsLargeOffset) {
4173 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4174 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4175 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4176 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4177 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4178 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4180 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4181 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4182 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4188 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4189 const MCSubtargetInfo *STI) {
4190 if (hasMips32r6() || hasMips64r6()) {
4191 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4194 const MCOperand &DstRegOp = Inst.getOperand(0);
4195 assert(DstRegOp.isReg() && "expected register operand kind");
4196 const MCOperand &SrcRegOp = Inst.getOperand(1);
4197 assert(SrcRegOp.isReg() && "expected register operand kind");
4198 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4199 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4201 MipsTargetStreamer &TOut = getTargetStreamer();
4202 unsigned DstReg = DstRegOp.getReg();
4203 unsigned SrcReg = SrcRegOp.getReg();
4204 int64_t OffsetValue = OffsetImmOp.getImm();
4206 // Compute left/right load/store offsets.
4207 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4208 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4209 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4211 std::swap(LxlOffset, LxrOffset);
4213 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4214 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4215 unsigned TmpReg = SrcReg;
4216 if (IsLargeOffset || DoMove) {
4217 warnIfNoMacro(IDLoc);
4218 TmpReg = getATReg(IDLoc);
4223 if (IsLargeOffset) {
4224 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4230 std::swap(DstReg, TmpReg);
4232 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4233 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4234 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4235 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4238 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4243 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4245 const MCSubtargetInfo *STI) {
4246 MipsTargetStreamer &TOut = getTargetStreamer();
4248 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4249 assert(Inst.getOperand(0).isReg() &&
4250 Inst.getOperand(1).isReg() &&
4251 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4253 unsigned ATReg = Mips::NoRegister;
4254 unsigned FinalDstReg = Mips::NoRegister;
4255 unsigned DstReg = Inst.getOperand(0).getReg();
4256 unsigned SrcReg = Inst.getOperand(1).getReg();
4257 int64_t ImmValue = Inst.getOperand(2).getImm();
4259 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4261 unsigned FinalOpcode = Inst.getOpcode();
4263 if (DstReg == SrcReg) {
4264 ATReg = getATReg(Inst.getLoc());
4267 FinalDstReg = DstReg;
4271 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
4272 switch (FinalOpcode) {
4274 llvm_unreachable("unimplemented expansion");
4276 FinalOpcode = Mips::ADD;
4279 FinalOpcode = Mips::ADDu;
4282 FinalOpcode = Mips::AND;
4285 FinalOpcode = Mips::NOR;
4288 FinalOpcode = Mips::OR;
4291 FinalOpcode = Mips::SLT;
4294 FinalOpcode = Mips::SLTu;
4297 FinalOpcode = Mips::XOR;
4300 FinalOpcode = Mips::ADD_MM;
4302 case Mips::ADDiu_MM:
4303 FinalOpcode = Mips::ADDu_MM;
4306 FinalOpcode = Mips::AND_MM;
4309 FinalOpcode = Mips::OR_MM;
4312 FinalOpcode = Mips::SLT_MM;
4314 case Mips::SLTiu_MM:
4315 FinalOpcode = Mips::SLTu_MM;
4318 FinalOpcode = Mips::XOR_MM;
4321 FinalOpcode = Mips::AND64;
4323 case Mips::NORImm64:
4324 FinalOpcode = Mips::NOR64;
4327 FinalOpcode = Mips::OR64;
4329 case Mips::SLTImm64:
4330 FinalOpcode = Mips::SLT64;
4332 case Mips::SLTUImm64:
4333 FinalOpcode = Mips::SLTu64;
4336 FinalOpcode = Mips::XOR64;
4340 if (FinalDstReg == Mips::NoRegister)
4341 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4343 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4349 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4350 const MCSubtargetInfo *STI) {
4351 MipsTargetStreamer &TOut = getTargetStreamer();
4352 unsigned ATReg = Mips::NoRegister;
4353 unsigned DReg = Inst.getOperand(0).getReg();
4354 unsigned SReg = Inst.getOperand(1).getReg();
4355 unsigned TReg = Inst.getOperand(2).getReg();
4356 unsigned TmpReg = DReg;
4358 unsigned FirstShift = Mips::NOP;
4359 unsigned SecondShift = Mips::NOP;
4361 if (hasMips32r2()) {
4363 TmpReg = getATReg(Inst.getLoc());
4368 if (Inst.getOpcode() == Mips::ROL) {
4369 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4370 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4374 if (Inst.getOpcode() == Mips::ROR) {
4375 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4383 switch (Inst.getOpcode()) {
4385 llvm_unreachable("unexpected instruction opcode");
4387 FirstShift = Mips::SRLV;
4388 SecondShift = Mips::SLLV;
4391 FirstShift = Mips::SLLV;
4392 SecondShift = Mips::SRLV;
4396 ATReg = getATReg(Inst.getLoc());
4400 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4401 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4402 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4403 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4411 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4413 const MCSubtargetInfo *STI) {
4414 MipsTargetStreamer &TOut = getTargetStreamer();
4415 unsigned ATReg = Mips::NoRegister;
4416 unsigned DReg = Inst.getOperand(0).getReg();
4417 unsigned SReg = Inst.getOperand(1).getReg();
4418 int64_t ImmValue = Inst.getOperand(2).getImm();
4420 unsigned FirstShift = Mips::NOP;
4421 unsigned SecondShift = Mips::NOP;
4423 if (hasMips32r2()) {
4424 if (Inst.getOpcode() == Mips::ROLImm) {
4425 uint64_t MaxShift = 32;
4426 uint64_t ShiftValue = ImmValue;
4428 ShiftValue = MaxShift - ImmValue;
4429 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4433 if (Inst.getOpcode() == Mips::RORImm) {
4434 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4442 if (ImmValue == 0) {
4443 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4447 switch (Inst.getOpcode()) {
4449 llvm_unreachable("unexpected instruction opcode");
4451 FirstShift = Mips::SLL;
4452 SecondShift = Mips::SRL;
4455 FirstShift = Mips::SRL;
4456 SecondShift = Mips::SLL;
4460 ATReg = getATReg(Inst.getLoc());
4464 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4465 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4466 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4474 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4475 const MCSubtargetInfo *STI) {
4476 MipsTargetStreamer &TOut = getTargetStreamer();
4477 unsigned ATReg = Mips::NoRegister;
4478 unsigned DReg = Inst.getOperand(0).getReg();
4479 unsigned SReg = Inst.getOperand(1).getReg();
4480 unsigned TReg = Inst.getOperand(2).getReg();
4481 unsigned TmpReg = DReg;
4483 unsigned FirstShift = Mips::NOP;
4484 unsigned SecondShift = Mips::NOP;
4486 if (hasMips64r2()) {
4487 if (TmpReg == SReg) {
4488 TmpReg = getATReg(Inst.getLoc());
4493 if (Inst.getOpcode() == Mips::DROL) {
4494 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4495 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4499 if (Inst.getOpcode() == Mips::DROR) {
4500 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4508 switch (Inst.getOpcode()) {
4510 llvm_unreachable("unexpected instruction opcode");
4512 FirstShift = Mips::DSRLV;
4513 SecondShift = Mips::DSLLV;
4516 FirstShift = Mips::DSLLV;
4517 SecondShift = Mips::DSRLV;
4521 ATReg = getATReg(Inst.getLoc());
4525 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4526 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4527 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4528 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4536 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4538 const MCSubtargetInfo *STI) {
4539 MipsTargetStreamer &TOut = getTargetStreamer();
4540 unsigned ATReg = Mips::NoRegister;
4541 unsigned DReg = Inst.getOperand(0).getReg();
4542 unsigned SReg = Inst.getOperand(1).getReg();
4543 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4545 unsigned FirstShift = Mips::NOP;
4546 unsigned SecondShift = Mips::NOP;
4550 if (hasMips64r2()) {
4551 unsigned FinalOpcode = Mips::NOP;
4553 FinalOpcode = Mips::DROTR;
4554 else if (ImmValue % 32 == 0)
4555 FinalOpcode = Mips::DROTR32;
4556 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4557 if (Inst.getOpcode() == Mips::DROLImm)
4558 FinalOpcode = Mips::DROTR32;
4560 FinalOpcode = Mips::DROTR;
4561 } else if (ImmValue >= 33) {
4562 if (Inst.getOpcode() == Mips::DROLImm)
4563 FinalOpcode = Mips::DROTR;
4565 FinalOpcode = Mips::DROTR32;
4568 uint64_t ShiftValue = ImmValue % 32;
4569 if (Inst.getOpcode() == Mips::DROLImm)
4570 ShiftValue = (32 - ImmValue % 32) % 32;
4572 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4578 if (ImmValue == 0) {
4579 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4583 switch (Inst.getOpcode()) {
4585 llvm_unreachable("unexpected instruction opcode");
4587 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4588 FirstShift = Mips::DSLL;
4589 SecondShift = Mips::DSRL32;
4591 if (ImmValue == 32) {
4592 FirstShift = Mips::DSLL32;
4593 SecondShift = Mips::DSRL32;
4595 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4596 FirstShift = Mips::DSLL32;
4597 SecondShift = Mips::DSRL;
4601 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4602 FirstShift = Mips::DSRL;
4603 SecondShift = Mips::DSLL32;
4605 if (ImmValue == 32) {
4606 FirstShift = Mips::DSRL32;
4607 SecondShift = Mips::DSLL32;
4609 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4610 FirstShift = Mips::DSRL32;
4611 SecondShift = Mips::DSLL;
4616 ATReg = getATReg(Inst.getLoc());
4620 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4621 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4622 Inst.getLoc(), STI);
4623 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4631 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4632 const MCSubtargetInfo *STI) {
4633 MipsTargetStreamer &TOut = getTargetStreamer();
4634 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4635 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4637 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4638 if (FirstRegOp != SecondRegOp)
4639 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4641 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4642 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4647 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4648 const MCSubtargetInfo *STI) {
4649 MipsTargetStreamer &TOut = getTargetStreamer();
4650 unsigned ATReg = Mips::NoRegister;
4651 unsigned DstReg = Inst.getOperand(0).getReg();
4652 unsigned SrcReg = Inst.getOperand(1).getReg();
4653 int32_t ImmValue = Inst.getOperand(2).getImm();
4655 ATReg = getATReg(IDLoc);
4659 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, STI);
4661 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4662 SrcReg, ATReg, IDLoc, STI);
4664 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4669 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4670 const MCSubtargetInfo *STI) {
4671 MipsTargetStreamer &TOut = getTargetStreamer();
4672 unsigned ATReg = Mips::NoRegister;
4673 unsigned DstReg = Inst.getOperand(0).getReg();
4674 unsigned SrcReg = Inst.getOperand(1).getReg();
4675 unsigned TmpReg = Inst.getOperand(2).getReg();
4677 ATReg = getATReg(Inst.getLoc());
4681 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4682 SrcReg, TmpReg, IDLoc, STI);
4684 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4686 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4687 DstReg, DstReg, 0x1F, IDLoc, STI);
4689 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4692 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4694 MCContext & Context = TOut.getStreamer().getContext();
4695 MCSymbol * BrTarget = Context.createTempSymbol();
4697 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4699 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4700 if (AssemblerOptions.back()->isReorder())
4701 TOut.emitNop(IDLoc, STI);
4702 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4704 TOut.getStreamer().EmitLabel(BrTarget);
4706 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4711 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4712 const MCSubtargetInfo *STI) {
4713 MipsTargetStreamer &TOut = getTargetStreamer();
4714 unsigned ATReg = Mips::NoRegister;
4715 unsigned DstReg = Inst.getOperand(0).getReg();
4716 unsigned SrcReg = Inst.getOperand(1).getReg();
4717 unsigned TmpReg = Inst.getOperand(2).getReg();
4719 ATReg = getATReg(IDLoc);
4723 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4724 SrcReg, TmpReg, IDLoc, STI);
4726 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4727 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4729 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4731 MCContext & Context = TOut.getStreamer().getContext();
4732 MCSymbol * BrTarget = Context.createTempSymbol();
4734 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4736 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4737 if (AssemblerOptions.back()->isReorder())
4738 TOut.emitNop(IDLoc, STI);
4739 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4741 TOut.getStreamer().EmitLabel(BrTarget);
4747 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4748 const MCSubtargetInfo *STI) {
4749 MipsTargetStreamer &TOut = getTargetStreamer();
4750 unsigned DstReg = Inst.getOperand(0).getReg();
4751 unsigned SrcReg = Inst.getOperand(1).getReg();
4752 unsigned TmpReg = Inst.getOperand(2).getReg();
4754 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4755 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4760 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4761 // lw $<reg+1>>, offset+4($reg2)'
4762 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4763 // sw $<reg+1>>, offset+4($reg2)'
4765 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4767 const MCSubtargetInfo *STI,
4772 warnIfNoMacro(IDLoc);
4774 MipsTargetStreamer &TOut = getTargetStreamer();
4775 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4776 unsigned FirstReg = Inst.getOperand(0).getReg();
4777 unsigned SecondReg = nextReg(FirstReg);
4778 unsigned BaseReg = Inst.getOperand(1).getReg();
4782 warnIfRegIndexIsAT(FirstReg, IDLoc);
4784 assert(Inst.getOperand(2).isImm() &&
4785 "Offset for load macro is not immediate!");
4787 MCOperand &FirstOffset = Inst.getOperand(2);
4788 signed NextOffset = FirstOffset.getImm() + 4;
4789 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4791 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4794 // For loads, clobber the base register with the second load instead of the
4795 // first if the BaseReg == FirstReg.
4796 if (FirstReg != BaseReg || !IsLoad) {
4797 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4798 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4800 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4801 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4807 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4808 const MCSubtargetInfo *STI) {
4810 warnIfNoMacro(IDLoc);
4811 MipsTargetStreamer &TOut = getTargetStreamer();
4813 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4814 Inst.getOperand(2).getReg() != Mips::ZERO) {
4815 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4816 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4818 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4819 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4824 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4825 Reg = Inst.getOperand(2).getReg();
4827 Reg = Inst.getOperand(1).getReg();
4829 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4833 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4834 const MCSubtargetInfo *STI) {
4835 warnIfNoMacro(IDLoc);
4836 MipsTargetStreamer &TOut = getTargetStreamer();
4839 int64_t Imm = Inst.getOperand(2).getImm();
4840 unsigned Reg = Inst.getOperand(1).getReg();
4843 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4844 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4848 if (Reg == Mips::ZERO) {
4849 Warning(IDLoc, "comparison is always false");
4850 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4851 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4855 if (Imm > -0x8000 && Imm < 0) {
4857 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4862 if (!isUInt<16>(Imm)) {
4863 unsigned ATReg = getATReg(IDLoc);
4867 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4871 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4872 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4873 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4874 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4878 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4880 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4881 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4886 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
4887 const OperandVector &Operands) {
4888 switch (Inst.getOpcode()) {
4890 return Match_Success;
4893 case Mips::DATI_MM64R6:
4894 case Mips::DAHI_MM64R6:
4895 if (static_cast<MipsOperand &>(*Operands[1])
4896 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4897 return Match_Success;
4898 return Match_RequiresSameSrcAndDst;
4902 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4903 switch (Inst.getOpcode()) {
4904 // As described by the MIPSR6 spec, daui must not use the zero operand for
4905 // its source operand.
4907 case Mips::DAUI_MM64R6:
4908 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4909 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4910 return Match_RequiresNoZeroRegister;
4911 return Match_Success;
4912 // As described by the Mips32r2 spec, the registers Rd and Rs for
4913 // jalr.hb must be different.
4914 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
4915 // and registers Rd and Base for microMIPS lwp instruction
4917 case Mips::JALRC_HB_MMR6:
4918 case Mips::JALRC_MMR6:
4919 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4920 return Match_RequiresDifferentSrcAndDst;
4921 return Match_Success;
4923 case Mips::LWP_MMR6:
4924 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
4925 return Match_RequiresDifferentSrcAndDst;
4926 return Match_Success;
4928 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
4929 return Match_NonZeroOperandForSync;
4930 return Match_Success;
4931 // As described the MIPSR6 spec, the compact branches that compare registers
4933 // a) Not use the zero register.
4934 // b) Not use the same register twice.
4935 // c) rs < rt for bnec, beqc.
4936 // NB: For this case, the encoding will swap the operands as their
4937 // ordering doesn't matter. GAS performs this transformation too.
4938 // Hence, that constraint does not have to be enforced.
4940 // The compact branches that branch iff the signed addition of two registers
4941 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
4942 // operand swapping. They do not have restriction of using the zero register.
4943 case Mips::BLEZC: case Mips::BLEZC_MMR6:
4944 case Mips::BGEZC: case Mips::BGEZC_MMR6:
4945 case Mips::BGTZC: case Mips::BGTZC_MMR6:
4946 case Mips::BLTZC: case Mips::BLTZC_MMR6:
4947 case Mips::BEQZC: case Mips::BEQZC_MMR6:
4948 case Mips::BNEZC: case Mips::BNEZC_MMR6:
4955 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4956 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4957 return Match_RequiresNoZeroRegister;
4958 return Match_Success;
4959 case Mips::BGEC: case Mips::BGEC_MMR6:
4960 case Mips::BLTC: case Mips::BLTC_MMR6:
4961 case Mips::BGEUC: case Mips::BGEUC_MMR6:
4962 case Mips::BLTUC: case Mips::BLTUC_MMR6:
4963 case Mips::BEQC: case Mips::BEQC_MMR6:
4964 case Mips::BNEC: case Mips::BNEC_MMR6:
4971 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4972 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4973 return Match_RequiresNoZeroRegister;
4974 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4975 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4976 return Match_RequiresNoZeroRegister;
4977 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4978 return Match_RequiresDifferentOperands;
4979 return Match_Success;
4982 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
4983 if ((TSFlags & MipsII::HasFCCRegOperand) &&
4984 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
4985 return Match_NoFCCRegisterForCurrentISA;
4987 return Match_Success;
4991 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
4992 uint64_t ErrorInfo) {
4993 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
4994 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4995 if (ErrorLoc == SMLoc())
5002 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5003 OperandVector &Operands,
5005 uint64_t &ErrorInfo,
5006 bool MatchingInlineAsm) {
5008 unsigned MatchResult =
5009 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5011 switch (MatchResult) {
5013 if (processInstruction(Inst, IDLoc, Out, STI))
5016 case Match_MissingFeature:
5017 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5019 case Match_InvalidOperand: {
5020 SMLoc ErrorLoc = IDLoc;
5021 if (ErrorInfo != ~0ULL) {
5022 if (ErrorInfo >= Operands.size())
5023 return Error(IDLoc, "too few operands for instruction");
5025 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5026 if (ErrorLoc == SMLoc())
5030 return Error(ErrorLoc, "invalid operand for instruction");
5032 case Match_NonZeroOperandForSync:
5033 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5034 case Match_MnemonicFail:
5035 return Error(IDLoc, "invalid instruction");
5036 case Match_RequiresDifferentSrcAndDst:
5037 return Error(IDLoc, "source and destination must be different");
5038 case Match_RequiresDifferentOperands:
5039 return Error(IDLoc, "registers must be different");
5040 case Match_RequiresNoZeroRegister:
5041 return Error(IDLoc, "invalid operand ($zero) for instruction");
5042 case Match_RequiresSameSrcAndDst:
5043 return Error(IDLoc, "source and destination must match");
5044 case Match_NoFCCRegisterForCurrentISA:
5045 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5046 "non-zero fcc register doesn't exist in current ISA level");
5048 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5050 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5051 "expected 1-bit unsigned immediate");
5053 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5054 "expected 2-bit unsigned immediate");
5056 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5057 "expected immediate in range 1 .. 4");
5059 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5060 "expected 3-bit unsigned immediate");
5062 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5063 "expected 4-bit unsigned immediate");
5065 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5066 "expected 4-bit signed immediate");
5068 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5069 "expected 5-bit unsigned immediate");
5071 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5072 "expected 5-bit signed immediate");
5074 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5075 "expected immediate in range 1 .. 32");
5076 case Match_UImm5_32:
5077 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5078 "expected immediate in range 32 .. 63");
5079 case Match_UImm5_33:
5080 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5081 "expected immediate in range 33 .. 64");
5082 case Match_UImm5_0_Report_UImm6:
5083 // This is used on UImm5 operands that have a corresponding UImm5_32
5084 // operand to avoid confusing the user.
5085 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5086 "expected 6-bit unsigned immediate");
5087 case Match_UImm5_Lsl2:
5088 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5089 "expected both 7-bit unsigned immediate and multiple of 4");
5090 case Match_UImmRange2_64:
5091 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5092 "expected immediate in range 2 .. 64");
5094 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5095 "expected 6-bit unsigned immediate");
5096 case Match_UImm6_Lsl2:
5097 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5098 "expected both 8-bit unsigned immediate and multiple of 4");
5100 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5101 "expected 6-bit signed immediate");
5103 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5104 "expected 7-bit unsigned immediate");
5105 case Match_UImm7_N1:
5106 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5107 "expected immediate in range -1 .. 126");
5108 case Match_SImm7_Lsl2:
5109 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5110 "expected both 9-bit signed immediate and multiple of 4");
5112 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5113 "expected 8-bit unsigned immediate");
5114 case Match_UImm10_0:
5115 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5116 "expected 10-bit unsigned immediate");
5117 case Match_SImm10_0:
5118 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5119 "expected 10-bit signed immediate");
5120 case Match_SImm11_0:
5121 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5122 "expected 11-bit signed immediate");
5124 case Match_UImm16_Relaxed:
5125 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5126 "expected 16-bit unsigned immediate");
5128 case Match_SImm16_Relaxed:
5129 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5130 "expected 16-bit signed immediate");
5131 case Match_SImm19_Lsl2:
5132 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5133 "expected both 19-bit signed immediate and multiple of 4");
5134 case Match_UImm20_0:
5135 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5136 "expected 20-bit unsigned immediate");
5137 case Match_UImm26_0:
5138 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5139 "expected 26-bit unsigned immediate");
5141 case Match_SImm32_Relaxed:
5142 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5143 "expected 32-bit signed immediate");
5144 case Match_UImm32_Coerced:
5145 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5146 "expected 32-bit immediate");
5147 case Match_MemSImm9:
5148 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5149 "expected memory with 9-bit signed offset");
5150 case Match_MemSImm10:
5151 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5152 "expected memory with 10-bit signed offset");
5153 case Match_MemSImm10Lsl1:
5154 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5155 "expected memory with 11-bit signed offset and multiple of 2");
5156 case Match_MemSImm10Lsl2:
5157 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5158 "expected memory with 12-bit signed offset and multiple of 4");
5159 case Match_MemSImm10Lsl3:
5160 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5161 "expected memory with 13-bit signed offset and multiple of 8");
5162 case Match_MemSImm11:
5163 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5164 "expected memory with 11-bit signed offset");
5165 case Match_MemSImm12:
5166 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5167 "expected memory with 12-bit signed offset");
5168 case Match_MemSImm16:
5169 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5170 "expected memory with 16-bit signed offset");
5173 llvm_unreachable("Implement any new match types added!");
5176 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5177 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5178 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5179 ") without \".set noat\"");
5182 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5183 if (!AssemblerOptions.back()->isMacro())
5184 Warning(Loc, "macro instruction expanded into multiple instructions");
5188 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5189 SMRange Range, bool ShowColors) {
5190 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5191 Range, SMFixIt(Range, FixMsg),
5195 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5198 CC = StringSwitch<unsigned>(Name)
5200 .Cases("at", "AT", 1)
5234 if (!(isABI_N32() || isABI_N64()))
5237 if (12 <= CC && CC <= 15) {
5238 // Name is one of t4-t7
5239 AsmToken RegTok = getLexer().peekTok();
5240 SMRange RegRange = RegTok.getLocRange();
5242 StringRef FixedName = StringSwitch<StringRef>(Name)
5248 assert(FixedName != "" && "Register name is not one of t4-t7.");
5250 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5251 "Did you mean $" + FixedName + "?", RegRange);
5254 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5255 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5256 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5257 if (8 <= CC && CC <= 11)
5261 CC = StringSwitch<unsigned>(Name)
5273 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5276 CC = StringSwitch<unsigned>(Name)
5277 .Case("hwr_cpunum", 0)
5278 .Case("hwr_synci_step", 1)
5280 .Case("hwr_ccres", 3)
5281 .Case("hwr_ulr", 29)
5287 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5288 if (Name[0] == 'f') {
5289 StringRef NumString = Name.substr(1);
5291 if (NumString.getAsInteger(10, IntVal))
5292 return -1; // This is not an integer.
5293 if (IntVal > 31) // Maximum index for fpu register.
5300 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5301 if (Name.startswith("fcc")) {
5302 StringRef NumString = Name.substr(3);
5304 if (NumString.getAsInteger(10, IntVal))
5305 return -1; // This is not an integer.
5306 if (IntVal > 7) // There are only 8 fcc registers.
5313 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5314 if (Name.startswith("ac")) {
5315 StringRef NumString = Name.substr(2);
5317 if (NumString.getAsInteger(10, IntVal))
5318 return -1; // This is not an integer.
5319 if (IntVal > 3) // There are only 3 acc registers.
5326 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5329 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5338 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5341 CC = StringSwitch<unsigned>(Name)
5344 .Case("msaaccess", 2)
5346 .Case("msamodify", 4)
5347 .Case("msarequest", 5)
5349 .Case("msaunmap", 7)
5355 bool MipsAsmParser::canUseATReg() {
5356 return AssemblerOptions.back()->getATRegIndex() != 0;
5359 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5360 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5362 reportParseError(Loc,
5363 "pseudo-instruction requires $at, which is not available");
5366 unsigned AT = getReg(
5367 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5371 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5372 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5375 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5376 MCAsmParser &Parser = getParser();
5377 DEBUG(dbgs() << "parseOperand\n");
5379 // Check if the current operand has a custom associated parser, if so, try to
5380 // custom parse the operand, or fallback to the general approach.
5381 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5382 if (ResTy == MatchOperand_Success)
5384 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5385 // there was a match, but an error occurred, in which case, just return that
5386 // the operand parsing failed.
5387 if (ResTy == MatchOperand_ParseFail)
5390 DEBUG(dbgs() << ".. Generic Parser\n");
5392 switch (getLexer().getKind()) {
5393 case AsmToken::Dollar: {
5394 // Parse the register.
5395 SMLoc S = Parser.getTok().getLoc();
5397 // Almost all registers have been parsed by custom parsers. There is only
5398 // one exception to this. $zero (and it's alias $0) will reach this point
5399 // for div, divu, and similar instructions because it is not an operand
5400 // to the instruction definition but an explicit register. Special case
5401 // this situation for now.
5402 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5405 // Maybe it is a symbol reference.
5406 StringRef Identifier;
5407 if (Parser.parseIdentifier(Identifier))
5410 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5411 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5412 // Otherwise create a symbol reference.
5414 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5416 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5420 DEBUG(dbgs() << ".. generic integer expression\n");
5423 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5424 if (getParser().parseExpression(Expr))
5427 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5429 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5432 } // switch(getLexer().getKind())
5436 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5437 switch (Expr->getKind()) {
5438 case MCExpr::Constant:
5440 case MCExpr::SymbolRef:
5441 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5442 case MCExpr::Binary:
5443 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
5444 if (!isEvaluated(BE->getLHS()))
5446 return isEvaluated(BE->getRHS());
5449 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5450 case MCExpr::Target:
5456 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5458 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5459 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5460 if (ResTy == MatchOperand_Success) {
5461 assert(Operands.size() == 1);
5462 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5463 StartLoc = Operand.getStartLoc();
5464 EndLoc = Operand.getEndLoc();
5466 // AFAIK, we only support numeric registers and named GPR's in CFI
5468 // Don't worry about eating tokens before failing. Using an unrecognised
5469 // register is a parse error.
5470 if (Operand.isGPRAsmReg()) {
5471 // Resolve to GPR32 or GPR64 appropriately.
5472 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5475 return (RegNo == (unsigned)-1);
5478 assert(Operands.size() == 0);
5479 return (RegNo == (unsigned)-1);
5482 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5486 return getParser().parseParenExprOfDepth(0, Res, S);
5487 return getParser().parseExpression(Res);
5490 OperandMatchResultTy
5491 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5492 MCAsmParser &Parser = getParser();
5493 DEBUG(dbgs() << "parseMemOperand\n");
5494 const MCExpr *IdVal = nullptr;
5496 bool isParenExpr = false;
5497 OperandMatchResultTy Res = MatchOperand_NoMatch;
5498 // First operand is the offset.
5499 S = Parser.getTok().getLoc();
5501 if (getLexer().getKind() == AsmToken::LParen) {
5506 if (getLexer().getKind() != AsmToken::Dollar) {
5507 if (parseMemOffset(IdVal, isParenExpr))
5508 return MatchOperand_ParseFail;
5510 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5511 if (Tok.isNot(AsmToken::LParen)) {
5512 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5513 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5515 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5516 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5517 return MatchOperand_Success;
5519 if (Tok.is(AsmToken::EndOfStatement)) {
5521 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5523 // Zero register assumed, add a memory operand with ZERO as its base.
5524 // "Base" will be managed by k_Memory.
5525 auto Base = MipsOperand::createGPRReg(
5526 0, "0", getContext().getRegisterInfo(), S, E, *this);
5528 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5529 return MatchOperand_Success;
5531 MCBinaryExpr::Opcode Opcode;
5532 // GAS and LLVM treat comparison operators different. GAS will generate -1
5533 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5534 // highly unlikely to be found in a memory offset expression, we don't
5536 switch (Tok.getKind()) {
5537 case AsmToken::Plus:
5538 Opcode = MCBinaryExpr::Add;
5541 case AsmToken::Minus:
5542 Opcode = MCBinaryExpr::Sub;
5545 case AsmToken::Star:
5546 Opcode = MCBinaryExpr::Mul;
5549 case AsmToken::Pipe:
5550 Opcode = MCBinaryExpr::Or;
5554 Opcode = MCBinaryExpr::And;
5557 case AsmToken::LessLess:
5558 Opcode = MCBinaryExpr::Shl;
5561 case AsmToken::GreaterGreater:
5562 Opcode = MCBinaryExpr::LShr;
5565 case AsmToken::Caret:
5566 Opcode = MCBinaryExpr::Xor;
5569 case AsmToken::Slash:
5570 Opcode = MCBinaryExpr::Div;
5573 case AsmToken::Percent:
5574 Opcode = MCBinaryExpr::Mod;
5578 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5579 return MatchOperand_ParseFail;
5581 const MCExpr * NextExpr;
5582 if (getParser().parseExpression(NextExpr))
5583 return MatchOperand_ParseFail;
5584 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5587 Parser.Lex(); // Eat the '(' token.
5590 Res = parseAnyRegister(Operands);
5591 if (Res != MatchOperand_Success)
5594 if (Parser.getTok().isNot(AsmToken::RParen)) {
5595 Error(Parser.getTok().getLoc(), "')' expected");
5596 return MatchOperand_ParseFail;
5599 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5601 Parser.Lex(); // Eat the ')' token.
5604 IdVal = MCConstantExpr::create(0, getContext());
5606 // Replace the register operand with the memory operand.
5607 std::unique_ptr<MipsOperand> op(
5608 static_cast<MipsOperand *>(Operands.back().release()));
5609 // Remove the register from the operands.
5610 // "op" will be managed by k_Memory.
5611 Operands.pop_back();
5612 // Add the memory operand.
5613 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5615 if (IdVal->evaluateAsAbsolute(Imm))
5616 IdVal = MCConstantExpr::create(Imm, getContext());
5617 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5618 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5622 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5623 return MatchOperand_Success;
5626 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5627 MCAsmParser &Parser = getParser();
5628 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5630 SMLoc S = Parser.getTok().getLoc();
5632 if (Sym->isVariable())
5633 Expr = Sym->getVariableValue();
5636 if (Expr->getKind() == MCExpr::SymbolRef) {
5637 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5638 StringRef DefSymbol = Ref->getSymbol().getName();
5639 if (DefSymbol.startswith("$")) {
5640 OperandMatchResultTy ResTy =
5641 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5642 if (ResTy == MatchOperand_Success) {
5645 } else if (ResTy == MatchOperand_ParseFail)
5646 llvm_unreachable("Should never ParseFail");
5654 OperandMatchResultTy
5655 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
5656 StringRef Identifier,
5658 int Index = matchCPURegisterName(Identifier);
5660 Operands.push_back(MipsOperand::createGPRReg(
5661 Index, Identifier, getContext().getRegisterInfo(), S,
5662 getLexer().getLoc(), *this));
5663 return MatchOperand_Success;
5666 Index = matchHWRegsRegisterName(Identifier);
5668 Operands.push_back(MipsOperand::createHWRegsReg(
5669 Index, Identifier, getContext().getRegisterInfo(), S,
5670 getLexer().getLoc(), *this));
5671 return MatchOperand_Success;
5674 Index = matchFPURegisterName(Identifier);
5676 Operands.push_back(MipsOperand::createFGRReg(
5677 Index, Identifier, getContext().getRegisterInfo(), S,
5678 getLexer().getLoc(), *this));
5679 return MatchOperand_Success;
5682 Index = matchFCCRegisterName(Identifier);
5684 Operands.push_back(MipsOperand::createFCCReg(
5685 Index, Identifier, getContext().getRegisterInfo(), S,
5686 getLexer().getLoc(), *this));
5687 return MatchOperand_Success;
5690 Index = matchACRegisterName(Identifier);
5692 Operands.push_back(MipsOperand::createACCReg(
5693 Index, Identifier, getContext().getRegisterInfo(), S,
5694 getLexer().getLoc(), *this));
5695 return MatchOperand_Success;
5698 Index = matchMSA128RegisterName(Identifier);
5700 Operands.push_back(MipsOperand::createMSA128Reg(
5701 Index, Identifier, getContext().getRegisterInfo(), S,
5702 getLexer().getLoc(), *this));
5703 return MatchOperand_Success;
5706 Index = matchMSA128CtrlRegisterName(Identifier);
5708 Operands.push_back(MipsOperand::createMSACtrlReg(
5709 Index, Identifier, getContext().getRegisterInfo(), S,
5710 getLexer().getLoc(), *this));
5711 return MatchOperand_Success;
5714 return MatchOperand_NoMatch;
5717 OperandMatchResultTy
5718 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
5719 MCAsmParser &Parser = getParser();
5720 auto Token = Parser.getLexer().peekTok(false);
5722 if (Token.is(AsmToken::Identifier)) {
5723 DEBUG(dbgs() << ".. identifier\n");
5724 StringRef Identifier = Token.getIdentifier();
5725 OperandMatchResultTy ResTy =
5726 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
5728 } else if (Token.is(AsmToken::Integer)) {
5729 DEBUG(dbgs() << ".. integer\n");
5730 Operands.push_back(MipsOperand::createNumericReg(
5731 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
5732 Token.getLoc(), *this));
5733 return MatchOperand_Success;
5736 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
5738 return MatchOperand_NoMatch;
5741 OperandMatchResultTy
5742 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
5743 MCAsmParser &Parser = getParser();
5744 DEBUG(dbgs() << "parseAnyRegister\n");
5746 auto Token = Parser.getTok();
5748 SMLoc S = Token.getLoc();
5750 if (Token.isNot(AsmToken::Dollar)) {
5751 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
5752 if (Token.is(AsmToken::Identifier)) {
5753 if (searchSymbolAlias(Operands))
5754 return MatchOperand_Success;
5756 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
5757 return MatchOperand_NoMatch;
5759 DEBUG(dbgs() << ".. $\n");
5761 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
5762 if (ResTy == MatchOperand_Success) {
5764 Parser.Lex(); // identifier
5769 OperandMatchResultTy
5770 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
5771 MCAsmParser &Parser = getParser();
5772 DEBUG(dbgs() << "parseJumpTarget\n");
5774 SMLoc S = getLexer().getLoc();
5776 // Registers are a valid target and have priority over symbols.
5777 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5778 if (ResTy != MatchOperand_NoMatch)
5781 // Integers and expressions are acceptable
5782 const MCExpr *Expr = nullptr;
5783 if (Parser.parseExpression(Expr)) {
5784 // We have no way of knowing if a symbol was consumed so we must ParseFail
5785 return MatchOperand_ParseFail;
5788 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
5789 return MatchOperand_Success;
5792 OperandMatchResultTy
5793 MipsAsmParser::parseInvNum(OperandVector &Operands) {
5794 MCAsmParser &Parser = getParser();
5795 const MCExpr *IdVal;
5796 // If the first token is '$' we may have register operand.
5797 if (Parser.getTok().is(AsmToken::Dollar))
5798 return MatchOperand_NoMatch;
5799 SMLoc S = Parser.getTok().getLoc();
5800 if (getParser().parseExpression(IdVal))
5801 return MatchOperand_ParseFail;
5802 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
5803 assert(MCE && "Unexpected MCExpr type.");
5804 int64_t Val = MCE->getValue();
5805 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5806 Operands.push_back(MipsOperand::CreateImm(
5807 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
5808 return MatchOperand_Success;
5811 OperandMatchResultTy
5812 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
5813 MCAsmParser &Parser = getParser();
5814 SmallVector<unsigned, 10> Regs;
5816 unsigned PrevReg = Mips::NoRegister;
5817 bool RegRange = false;
5818 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5820 if (Parser.getTok().isNot(AsmToken::Dollar))
5821 return MatchOperand_ParseFail;
5823 SMLoc S = Parser.getTok().getLoc();
5824 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
5825 SMLoc E = getLexer().getLoc();
5826 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
5827 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
5829 // Remove last register operand because registers from register range
5830 // should be inserted first.
5831 if ((isGP64bit() && RegNo == Mips::RA_64) ||
5832 (!isGP64bit() && RegNo == Mips::RA)) {
5833 Regs.push_back(RegNo);
5835 unsigned TmpReg = PrevReg + 1;
5836 while (TmpReg <= RegNo) {
5837 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
5838 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
5840 Error(E, "invalid register operand");
5841 return MatchOperand_ParseFail;
5845 Regs.push_back(TmpReg++);
5851 if ((PrevReg == Mips::NoRegister) &&
5852 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5853 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5854 Error(E, "$16 or $31 expected");
5855 return MatchOperand_ParseFail;
5856 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5857 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5859 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5860 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5862 Error(E, "invalid register operand");
5863 return MatchOperand_ParseFail;
5864 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5865 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5866 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5868 Error(E, "consecutive register numbers expected");
5869 return MatchOperand_ParseFail;
5872 Regs.push_back(RegNo);
5875 if (Parser.getTok().is(AsmToken::Minus))
5878 if (!Parser.getTok().isNot(AsmToken::Minus) &&
5879 !Parser.getTok().isNot(AsmToken::Comma)) {
5880 Error(E, "',' or '-' expected");
5881 return MatchOperand_ParseFail;
5884 Lex(); // Consume comma or minus
5885 if (Parser.getTok().isNot(AsmToken::Dollar))
5891 SMLoc E = Parser.getTok().getLoc();
5892 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5893 parseMemOperand(Operands);
5894 return MatchOperand_Success;
5897 OperandMatchResultTy
5898 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
5899 MCAsmParser &Parser = getParser();
5901 SMLoc S = Parser.getTok().getLoc();
5902 if (parseAnyRegister(Operands) != MatchOperand_Success)
5903 return MatchOperand_ParseFail;
5905 SMLoc E = Parser.getTok().getLoc();
5906 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
5908 Operands.pop_back();
5909 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
5910 return MatchOperand_Success;
5913 OperandMatchResultTy
5914 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
5915 MCAsmParser &Parser = getParser();
5916 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5917 SmallVector<unsigned, 10> Regs;
5919 if (Parser.getTok().isNot(AsmToken::Dollar))
5920 return MatchOperand_ParseFail;
5922 SMLoc S = Parser.getTok().getLoc();
5924 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5925 return MatchOperand_ParseFail;
5927 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5928 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5929 Regs.push_back(RegNo);
5931 SMLoc E = Parser.getTok().getLoc();
5932 if (Parser.getTok().isNot(AsmToken::Comma)) {
5933 Error(E, "',' expected");
5934 return MatchOperand_ParseFail;
5940 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5941 return MatchOperand_ParseFail;
5943 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5944 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5945 Regs.push_back(RegNo);
5947 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5949 return MatchOperand_Success;
5952 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
5954 /// ::= '(', register, ')'
5955 /// handle it before we iterate so we don't get tripped up by the lack of
5957 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
5958 MCAsmParser &Parser = getParser();
5959 if (getLexer().is(AsmToken::LParen)) {
5961 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
5963 if (parseOperand(Operands, Name)) {
5964 SMLoc Loc = getLexer().getLoc();
5965 return Error(Loc, "unexpected token in argument list");
5967 if (Parser.getTok().isNot(AsmToken::RParen)) {
5968 SMLoc Loc = getLexer().getLoc();
5969 return Error(Loc, "unexpected token, expected ')'");
5972 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
5978 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
5979 /// either one of these.
5980 /// ::= '[', register, ']'
5981 /// ::= '[', integer, ']'
5982 /// handle it before we iterate so we don't get tripped up by the lack of
5984 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
5985 OperandVector &Operands) {
5986 MCAsmParser &Parser = getParser();
5987 if (getLexer().is(AsmToken::LBrac)) {
5989 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
5991 if (parseOperand(Operands, Name)) {
5992 SMLoc Loc = getLexer().getLoc();
5993 return Error(Loc, "unexpected token in argument list");
5995 if (Parser.getTok().isNot(AsmToken::RBrac)) {
5996 SMLoc Loc = getLexer().getLoc();
5997 return Error(Loc, "unexpected token, expected ']'");
6000 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6006 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6007 SMLoc NameLoc, OperandVector &Operands) {
6008 MCAsmParser &Parser = getParser();
6009 DEBUG(dbgs() << "ParseInstruction\n");
6011 // We have reached first instruction, module directive are now forbidden.
6012 getTargetStreamer().forbidModuleDirective();
6014 // Check if we have valid mnemonic
6015 if (!mnemonicIsValid(Name, 0)) {
6016 return Error(NameLoc, "unknown instruction");
6018 // First operand in MCInst is instruction mnemonic.
6019 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6021 // Read the remaining operands.
6022 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6023 // Read the first operand.
6024 if (parseOperand(Operands, Name)) {
6025 SMLoc Loc = getLexer().getLoc();
6026 return Error(Loc, "unexpected token in argument list");
6028 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6030 // AFAIK, parenthesis suffixes are never on the first operand
6032 while (getLexer().is(AsmToken::Comma)) {
6033 Parser.Lex(); // Eat the comma.
6034 // Parse and remember the operand.
6035 if (parseOperand(Operands, Name)) {
6036 SMLoc Loc = getLexer().getLoc();
6037 return Error(Loc, "unexpected token in argument list");
6039 // Parse bracket and parenthesis suffixes before we iterate
6040 if (getLexer().is(AsmToken::LBrac)) {
6041 if (parseBracketSuffix(Name, Operands))
6043 } else if (getLexer().is(AsmToken::LParen) &&
6044 parseParenSuffix(Name, Operands))
6048 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6049 SMLoc Loc = getLexer().getLoc();
6050 return Error(Loc, "unexpected token in argument list");
6052 Parser.Lex(); // Consume the EndOfStatement.
6056 // FIXME: Given that these have the same name, these should both be
6057 // consistent on affecting the Parser.
6058 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6059 SMLoc Loc = getLexer().getLoc();
6060 return Error(Loc, ErrorMsg);
6063 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6064 return Error(Loc, ErrorMsg);
6067 bool MipsAsmParser::parseSetNoAtDirective() {
6068 MCAsmParser &Parser = getParser();
6069 // Line should look like: ".set noat".
6071 // Set the $at register to $0.
6072 AssemblerOptions.back()->setATRegIndex(0);
6074 Parser.Lex(); // Eat "noat".
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");
6082 getTargetStreamer().emitDirectiveSetNoAt();
6083 Parser.Lex(); // Consume the EndOfStatement.
6087 bool MipsAsmParser::parseSetAtDirective() {
6088 // Line can be: ".set at", which sets $at to $1
6089 // or ".set at=$reg", which sets $at to $reg.
6090 MCAsmParser &Parser = getParser();
6091 Parser.Lex(); // Eat "at".
6093 if (getLexer().is(AsmToken::EndOfStatement)) {
6094 // No register was specified, so we set $at to $1.
6095 AssemblerOptions.back()->setATRegIndex(1);
6097 getTargetStreamer().emitDirectiveSetAt();
6098 Parser.Lex(); // Consume the EndOfStatement.
6102 if (getLexer().isNot(AsmToken::Equal)) {
6103 reportParseError("unexpected token, expected equals sign");
6106 Parser.Lex(); // Eat "=".
6108 if (getLexer().isNot(AsmToken::Dollar)) {
6109 if (getLexer().is(AsmToken::EndOfStatement)) {
6110 reportParseError("no register specified");
6113 reportParseError("unexpected token, expected dollar sign '$'");
6117 Parser.Lex(); // Eat "$".
6119 // Find out what "reg" is.
6121 const AsmToken &Reg = Parser.getTok();
6122 if (Reg.is(AsmToken::Identifier)) {
6123 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6124 } else if (Reg.is(AsmToken::Integer)) {
6125 AtRegNo = Reg.getIntVal();
6127 reportParseError("unexpected token, expected identifier or integer");
6131 // Check if $reg is a valid register. If it is, set $at to $reg.
6132 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6133 reportParseError("invalid register");
6136 Parser.Lex(); // Eat "reg".
6138 // If this is not the end of the statement, report an error.
6139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6140 reportParseError("unexpected token, expected end of statement");
6144 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6146 Parser.Lex(); // Consume the EndOfStatement.
6150 bool MipsAsmParser::parseSetReorderDirective() {
6151 MCAsmParser &Parser = getParser();
6153 // If this is not the end of the statement, report an error.
6154 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6155 reportParseError("unexpected token, expected end of statement");
6158 AssemblerOptions.back()->setReorder();
6159 getTargetStreamer().emitDirectiveSetReorder();
6160 Parser.Lex(); // Consume the EndOfStatement.
6164 bool MipsAsmParser::parseSetNoReorderDirective() {
6165 MCAsmParser &Parser = getParser();
6167 // If this is not the end of the statement, report an error.
6168 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6169 reportParseError("unexpected token, expected end of statement");
6172 AssemblerOptions.back()->setNoReorder();
6173 getTargetStreamer().emitDirectiveSetNoReorder();
6174 Parser.Lex(); // Consume the EndOfStatement.
6178 bool MipsAsmParser::parseSetMacroDirective() {
6179 MCAsmParser &Parser = getParser();
6181 // If this is not the end of the statement, report an error.
6182 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6183 reportParseError("unexpected token, expected end of statement");
6186 AssemblerOptions.back()->setMacro();
6187 getTargetStreamer().emitDirectiveSetMacro();
6188 Parser.Lex(); // Consume the EndOfStatement.
6192 bool MipsAsmParser::parseSetNoMacroDirective() {
6193 MCAsmParser &Parser = getParser();
6195 // If this is not the end of the statement, report an error.
6196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6197 reportParseError("unexpected token, expected end of statement");
6200 if (AssemblerOptions.back()->isReorder()) {
6201 reportParseError("`noreorder' must be set before `nomacro'");
6204 AssemblerOptions.back()->setNoMacro();
6205 getTargetStreamer().emitDirectiveSetNoMacro();
6206 Parser.Lex(); // Consume the EndOfStatement.
6210 bool MipsAsmParser::parseSetMsaDirective() {
6211 MCAsmParser &Parser = getParser();
6214 // If this is not the end of the statement, report an error.
6215 if (getLexer().isNot(AsmToken::EndOfStatement))
6216 return reportParseError("unexpected token, expected end of statement");
6218 setFeatureBits(Mips::FeatureMSA, "msa");
6219 getTargetStreamer().emitDirectiveSetMsa();
6223 bool MipsAsmParser::parseSetNoMsaDirective() {
6224 MCAsmParser &Parser = getParser();
6227 // If this is not the end of the statement, report an error.
6228 if (getLexer().isNot(AsmToken::EndOfStatement))
6229 return reportParseError("unexpected token, expected end of statement");
6231 clearFeatureBits(Mips::FeatureMSA, "msa");
6232 getTargetStreamer().emitDirectiveSetNoMsa();
6236 bool MipsAsmParser::parseSetNoDspDirective() {
6237 MCAsmParser &Parser = getParser();
6238 Parser.Lex(); // Eat "nodsp".
6240 // If this is not the end of the statement, report an error.
6241 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6242 reportParseError("unexpected token, expected end of statement");
6246 clearFeatureBits(Mips::FeatureDSP, "dsp");
6247 getTargetStreamer().emitDirectiveSetNoDsp();
6251 bool MipsAsmParser::parseSetMips16Directive() {
6252 MCAsmParser &Parser = getParser();
6253 Parser.Lex(); // Eat "mips16".
6255 // If this is not the end of the statement, report an error.
6256 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6257 reportParseError("unexpected token, expected end of statement");
6261 setFeatureBits(Mips::FeatureMips16, "mips16");
6262 getTargetStreamer().emitDirectiveSetMips16();
6263 Parser.Lex(); // Consume the EndOfStatement.
6267 bool MipsAsmParser::parseSetNoMips16Directive() {
6268 MCAsmParser &Parser = getParser();
6269 Parser.Lex(); // Eat "nomips16".
6271 // If this is not the end of the statement, report an error.
6272 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6273 reportParseError("unexpected token, expected end of statement");
6277 clearFeatureBits(Mips::FeatureMips16, "mips16");
6278 getTargetStreamer().emitDirectiveSetNoMips16();
6279 Parser.Lex(); // Consume the EndOfStatement.
6283 bool MipsAsmParser::parseSetFpDirective() {
6284 MCAsmParser &Parser = getParser();
6285 MipsABIFlagsSection::FpABIKind FpAbiVal;
6286 // Line can be: .set fp=32
6289 Parser.Lex(); // Eat fp token
6290 AsmToken Tok = Parser.getTok();
6291 if (Tok.isNot(AsmToken::Equal)) {
6292 reportParseError("unexpected token, expected equals sign '='");
6295 Parser.Lex(); // Eat '=' token.
6296 Tok = Parser.getTok();
6298 if (!parseFpABIValue(FpAbiVal, ".set"))
6301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6302 reportParseError("unexpected token, expected end of statement");
6305 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6306 Parser.Lex(); // Consume the EndOfStatement.
6310 bool MipsAsmParser::parseSetOddSPRegDirective() {
6311 MCAsmParser &Parser = getParser();
6313 Parser.Lex(); // Eat "oddspreg".
6314 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6315 reportParseError("unexpected token, expected end of statement");
6319 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6320 getTargetStreamer().emitDirectiveSetOddSPReg();
6324 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6325 MCAsmParser &Parser = getParser();
6327 Parser.Lex(); // Eat "nooddspreg".
6328 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6329 reportParseError("unexpected token, expected end of statement");
6333 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6334 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6338 bool MipsAsmParser::parseSetMtDirective() {
6339 MCAsmParser &Parser = getParser();
6340 Parser.Lex(); // Eat "mt".
6342 // If this is not the end of the statement, report an error.
6343 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6344 reportParseError("unexpected token, expected end of statement");
6348 setFeatureBits(Mips::FeatureMT, "mt");
6349 getTargetStreamer().emitDirectiveSetMt();
6350 Parser.Lex(); // Consume the EndOfStatement.
6354 bool MipsAsmParser::parseSetNoMtDirective() {
6355 MCAsmParser &Parser = getParser();
6356 Parser.Lex(); // Eat "nomt".
6358 // If this is not the end of the statement, report an error.
6359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6360 reportParseError("unexpected token, expected end of statement");
6364 clearFeatureBits(Mips::FeatureMT, "mt");
6366 getTargetStreamer().emitDirectiveSetNoMt();
6367 Parser.Lex(); // Consume the EndOfStatement.
6371 bool MipsAsmParser::parseSetPopDirective() {
6372 MCAsmParser &Parser = getParser();
6373 SMLoc Loc = getLexer().getLoc();
6376 if (getLexer().isNot(AsmToken::EndOfStatement))
6377 return reportParseError("unexpected token, expected end of statement");
6379 // Always keep an element on the options "stack" to prevent the user
6380 // from changing the initial options. This is how we remember them.
6381 if (AssemblerOptions.size() == 2)
6382 return reportParseError(Loc, ".set pop with no .set push");
6384 MCSubtargetInfo &STI = copySTI();
6385 AssemblerOptions.pop_back();
6386 setAvailableFeatures(
6387 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6388 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6390 getTargetStreamer().emitDirectiveSetPop();
6394 bool MipsAsmParser::parseSetPushDirective() {
6395 MCAsmParser &Parser = getParser();
6397 if (getLexer().isNot(AsmToken::EndOfStatement))
6398 return reportParseError("unexpected token, expected end of statement");
6400 // Create a copy of the current assembler options environment and push it.
6401 AssemblerOptions.push_back(
6402 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6404 getTargetStreamer().emitDirectiveSetPush();
6408 bool MipsAsmParser::parseSetSoftFloatDirective() {
6409 MCAsmParser &Parser = getParser();
6411 if (getLexer().isNot(AsmToken::EndOfStatement))
6412 return reportParseError("unexpected token, expected end of statement");
6414 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6415 getTargetStreamer().emitDirectiveSetSoftFloat();
6419 bool MipsAsmParser::parseSetHardFloatDirective() {
6420 MCAsmParser &Parser = getParser();
6422 if (getLexer().isNot(AsmToken::EndOfStatement))
6423 return reportParseError("unexpected token, expected end of statement");
6425 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6426 getTargetStreamer().emitDirectiveSetHardFloat();
6430 bool MipsAsmParser::parseSetAssignment() {
6432 const MCExpr *Value;
6433 MCAsmParser &Parser = getParser();
6435 if (Parser.parseIdentifier(Name))
6436 reportParseError("expected identifier after .set");
6438 if (getLexer().isNot(AsmToken::Comma))
6439 return reportParseError("unexpected token, expected comma");
6442 if (Parser.parseExpression(Value))
6443 return reportParseError("expected valid expression after comma");
6445 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6446 Sym->setVariableValue(Value);
6451 bool MipsAsmParser::parseSetMips0Directive() {
6452 MCAsmParser &Parser = getParser();
6454 if (getLexer().isNot(AsmToken::EndOfStatement))
6455 return reportParseError("unexpected token, expected end of statement");
6457 // Reset assembler options to their initial values.
6458 MCSubtargetInfo &STI = copySTI();
6459 setAvailableFeatures(
6460 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6461 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6462 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6464 getTargetStreamer().emitDirectiveSetMips0();
6468 bool MipsAsmParser::parseSetArchDirective() {
6469 MCAsmParser &Parser = getParser();
6471 if (getLexer().isNot(AsmToken::Equal))
6472 return reportParseError("unexpected token, expected equals sign");
6476 if (Parser.parseIdentifier(Arch))
6477 return reportParseError("expected arch identifier");
6479 StringRef ArchFeatureName =
6480 StringSwitch<StringRef>(Arch)
6481 .Case("mips1", "mips1")
6482 .Case("mips2", "mips2")
6483 .Case("mips3", "mips3")
6484 .Case("mips4", "mips4")
6485 .Case("mips5", "mips5")
6486 .Case("mips32", "mips32")
6487 .Case("mips32r2", "mips32r2")
6488 .Case("mips32r3", "mips32r3")
6489 .Case("mips32r5", "mips32r5")
6490 .Case("mips32r6", "mips32r6")
6491 .Case("mips64", "mips64")
6492 .Case("mips64r2", "mips64r2")
6493 .Case("mips64r3", "mips64r3")
6494 .Case("mips64r5", "mips64r5")
6495 .Case("mips64r6", "mips64r6")
6496 .Case("octeon", "cnmips")
6497 .Case("r4000", "mips3") // This is an implementation of Mips3.
6500 if (ArchFeatureName.empty())
6501 return reportParseError("unsupported architecture");
6503 selectArch(ArchFeatureName);
6504 getTargetStreamer().emitDirectiveSetArch(Arch);
6508 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6509 MCAsmParser &Parser = getParser();
6511 if (getLexer().isNot(AsmToken::EndOfStatement))
6512 return reportParseError("unexpected token, expected end of statement");
6516 llvm_unreachable("Unimplemented feature");
6517 case Mips::FeatureDSP:
6518 setFeatureBits(Mips::FeatureDSP, "dsp");
6519 getTargetStreamer().emitDirectiveSetDsp();
6521 case Mips::FeatureMicroMips:
6522 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6523 getTargetStreamer().emitDirectiveSetMicroMips();
6525 case Mips::FeatureMips1:
6526 selectArch("mips1");
6527 getTargetStreamer().emitDirectiveSetMips1();
6529 case Mips::FeatureMips2:
6530 selectArch("mips2");
6531 getTargetStreamer().emitDirectiveSetMips2();
6533 case Mips::FeatureMips3:
6534 selectArch("mips3");
6535 getTargetStreamer().emitDirectiveSetMips3();
6537 case Mips::FeatureMips4:
6538 selectArch("mips4");
6539 getTargetStreamer().emitDirectiveSetMips4();
6541 case Mips::FeatureMips5:
6542 selectArch("mips5");
6543 getTargetStreamer().emitDirectiveSetMips5();
6545 case Mips::FeatureMips32:
6546 selectArch("mips32");
6547 getTargetStreamer().emitDirectiveSetMips32();
6549 case Mips::FeatureMips32r2:
6550 selectArch("mips32r2");
6551 getTargetStreamer().emitDirectiveSetMips32R2();
6553 case Mips::FeatureMips32r3:
6554 selectArch("mips32r3");
6555 getTargetStreamer().emitDirectiveSetMips32R3();
6557 case Mips::FeatureMips32r5:
6558 selectArch("mips32r5");
6559 getTargetStreamer().emitDirectiveSetMips32R5();
6561 case Mips::FeatureMips32r6:
6562 selectArch("mips32r6");
6563 getTargetStreamer().emitDirectiveSetMips32R6();
6565 case Mips::FeatureMips64:
6566 selectArch("mips64");
6567 getTargetStreamer().emitDirectiveSetMips64();
6569 case Mips::FeatureMips64r2:
6570 selectArch("mips64r2");
6571 getTargetStreamer().emitDirectiveSetMips64R2();
6573 case Mips::FeatureMips64r3:
6574 selectArch("mips64r3");
6575 getTargetStreamer().emitDirectiveSetMips64R3();
6577 case Mips::FeatureMips64r5:
6578 selectArch("mips64r5");
6579 getTargetStreamer().emitDirectiveSetMips64R5();
6581 case Mips::FeatureMips64r6:
6582 selectArch("mips64r6");
6583 getTargetStreamer().emitDirectiveSetMips64R6();
6589 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6590 MCAsmParser &Parser = getParser();
6591 if (getLexer().isNot(AsmToken::Comma)) {
6592 SMLoc Loc = getLexer().getLoc();
6593 return Error(Loc, ErrorStr);
6596 Parser.Lex(); // Eat the comma.
6600 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
6601 // In this class, it is only used for .cprestore.
6602 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
6603 // MipsTargetELFStreamer and MipsAsmParser.
6604 bool MipsAsmParser::isPicAndNotNxxAbi() {
6605 return inPicMode() && !(isABI_N32() || isABI_N64());
6608 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
6609 if (AssemblerOptions.back()->isReorder())
6610 Warning(Loc, ".cpload should be inside a noreorder section");
6612 if (inMips16Mode()) {
6613 reportParseError(".cpload is not supported in Mips16 mode");
6617 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
6618 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
6619 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6620 reportParseError("expected register containing function address");
6624 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
6625 if (!RegOpnd.isGPRAsmReg()) {
6626 reportParseError(RegOpnd.getStartLoc(), "invalid register");
6630 // If this is not the end of the statement, report an error.
6631 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6632 reportParseError("unexpected token, expected end of statement");
6636 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
6640 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
6641 MCAsmParser &Parser = getParser();
6643 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
6644 // is used in non-PIC mode.
6646 if (inMips16Mode()) {
6647 reportParseError(".cprestore is not supported in Mips16 mode");
6651 // Get the stack offset value.
6652 const MCExpr *StackOffset;
6653 int64_t StackOffsetVal;
6654 if (Parser.parseExpression(StackOffset)) {
6655 reportParseError("expected stack offset value");
6659 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
6660 reportParseError("stack offset is not an absolute expression");
6664 if (StackOffsetVal < 0) {
6665 Warning(Loc, ".cprestore with negative stack offset has no effect");
6666 IsCpRestoreSet = false;
6668 IsCpRestoreSet = true;
6669 CpRestoreOffset = StackOffsetVal;
6672 // If this is not the end of the statement, report an error.
6673 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6674 reportParseError("unexpected token, expected end of statement");
6678 if (!getTargetStreamer().emitDirectiveCpRestore(
6679 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
6681 Parser.Lex(); // Consume the EndOfStatement.
6685 bool MipsAsmParser::parseDirectiveCPSetup() {
6686 MCAsmParser &Parser = getParser();
6689 bool SaveIsReg = true;
6691 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6692 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6693 if (ResTy == MatchOperand_NoMatch) {
6694 reportParseError("expected register containing function address");
6698 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6699 if (!FuncRegOpnd.isGPRAsmReg()) {
6700 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
6704 FuncReg = FuncRegOpnd.getGPR32Reg();
6707 if (!eatComma("unexpected token, expected comma"))
6710 ResTy = parseAnyRegister(TmpReg);
6711 if (ResTy == MatchOperand_NoMatch) {
6712 const MCExpr *OffsetExpr;
6714 SMLoc ExprLoc = getLexer().getLoc();
6716 if (Parser.parseExpression(OffsetExpr) ||
6717 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
6718 reportParseError(ExprLoc, "expected save register or stack offset");
6725 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6726 if (!SaveOpnd.isGPRAsmReg()) {
6727 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
6730 Save = SaveOpnd.getGPR32Reg();
6733 if (!eatComma("unexpected token, expected comma"))
6737 if (Parser.parseExpression(Expr)) {
6738 reportParseError("expected expression");
6742 if (Expr->getKind() != MCExpr::SymbolRef) {
6743 reportParseError("expected symbol");
6746 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6748 CpSaveLocation = Save;
6749 CpSaveLocationIsRegister = SaveIsReg;
6751 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
6756 bool MipsAsmParser::parseDirectiveCPReturn() {
6757 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
6758 CpSaveLocationIsRegister);
6762 bool MipsAsmParser::parseDirectiveNaN() {
6763 MCAsmParser &Parser = getParser();
6764 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6765 const AsmToken &Tok = Parser.getTok();
6767 if (Tok.getString() == "2008") {
6769 getTargetStreamer().emitDirectiveNaN2008();
6771 } else if (Tok.getString() == "legacy") {
6773 getTargetStreamer().emitDirectiveNaNLegacy();
6777 // If we don't recognize the option passed to the .nan
6778 // directive (e.g. no option or unknown option), emit an error.
6779 reportParseError("invalid option in .nan directive");
6783 bool MipsAsmParser::parseDirectiveSet() {
6784 MCAsmParser &Parser = getParser();
6785 // Get the next token.
6786 const AsmToken &Tok = Parser.getTok();
6788 if (Tok.getString() == "noat") {
6789 return parseSetNoAtDirective();
6790 } else if (Tok.getString() == "at") {
6791 return parseSetAtDirective();
6792 } else if (Tok.getString() == "arch") {
6793 return parseSetArchDirective();
6794 } else if (Tok.getString() == "bopt") {
6795 Warning(Tok.getLoc(), "'bopt' feature is unsupported");
6798 } else if (Tok.getString() == "nobopt") {
6799 // We're already running in nobopt mode, so nothing to do.
6802 } else if (Tok.getString() == "fp") {
6803 return parseSetFpDirective();
6804 } else if (Tok.getString() == "oddspreg") {
6805 return parseSetOddSPRegDirective();
6806 } else if (Tok.getString() == "nooddspreg") {
6807 return parseSetNoOddSPRegDirective();
6808 } else if (Tok.getString() == "pop") {
6809 return parseSetPopDirective();
6810 } else if (Tok.getString() == "push") {
6811 return parseSetPushDirective();
6812 } else if (Tok.getString() == "reorder") {
6813 return parseSetReorderDirective();
6814 } else if (Tok.getString() == "noreorder") {
6815 return parseSetNoReorderDirective();
6816 } else if (Tok.getString() == "macro") {
6817 return parseSetMacroDirective();
6818 } else if (Tok.getString() == "nomacro") {
6819 return parseSetNoMacroDirective();
6820 } else if (Tok.getString() == "mips16") {
6821 return parseSetMips16Directive();
6822 } else if (Tok.getString() == "nomips16") {
6823 return parseSetNoMips16Directive();
6824 } else if (Tok.getString() == "nomicromips") {
6825 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
6826 getTargetStreamer().emitDirectiveSetNoMicroMips();
6827 Parser.eatToEndOfStatement();
6829 } else if (Tok.getString() == "micromips") {
6830 return parseSetFeature(Mips::FeatureMicroMips);
6831 } else if (Tok.getString() == "mips0") {
6832 return parseSetMips0Directive();
6833 } else if (Tok.getString() == "mips1") {
6834 return parseSetFeature(Mips::FeatureMips1);
6835 } else if (Tok.getString() == "mips2") {
6836 return parseSetFeature(Mips::FeatureMips2);
6837 } else if (Tok.getString() == "mips3") {
6838 return parseSetFeature(Mips::FeatureMips3);
6839 } else if (Tok.getString() == "mips4") {
6840 return parseSetFeature(Mips::FeatureMips4);
6841 } else if (Tok.getString() == "mips5") {
6842 return parseSetFeature(Mips::FeatureMips5);
6843 } else if (Tok.getString() == "mips32") {
6844 return parseSetFeature(Mips::FeatureMips32);
6845 } else if (Tok.getString() == "mips32r2") {
6846 return parseSetFeature(Mips::FeatureMips32r2);
6847 } else if (Tok.getString() == "mips32r3") {
6848 return parseSetFeature(Mips::FeatureMips32r3);
6849 } else if (Tok.getString() == "mips32r5") {
6850 return parseSetFeature(Mips::FeatureMips32r5);
6851 } else if (Tok.getString() == "mips32r6") {
6852 return parseSetFeature(Mips::FeatureMips32r6);
6853 } else if (Tok.getString() == "mips64") {
6854 return parseSetFeature(Mips::FeatureMips64);
6855 } else if (Tok.getString() == "mips64r2") {
6856 return parseSetFeature(Mips::FeatureMips64r2);
6857 } else if (Tok.getString() == "mips64r3") {
6858 return parseSetFeature(Mips::FeatureMips64r3);
6859 } else if (Tok.getString() == "mips64r5") {
6860 return parseSetFeature(Mips::FeatureMips64r5);
6861 } else if (Tok.getString() == "mips64r6") {
6862 return parseSetFeature(Mips::FeatureMips64r6);
6863 } else if (Tok.getString() == "dsp") {
6864 return parseSetFeature(Mips::FeatureDSP);
6865 } else if (Tok.getString() == "nodsp") {
6866 return parseSetNoDspDirective();
6867 } else if (Tok.getString() == "msa") {
6868 return parseSetMsaDirective();
6869 } else if (Tok.getString() == "nomsa") {
6870 return parseSetNoMsaDirective();
6871 } else if (Tok.getString() == "mt") {
6872 return parseSetMtDirective();
6873 } else if (Tok.getString() == "nomt") {
6874 return parseSetNoMtDirective();
6875 } else if (Tok.getString() == "softfloat") {
6876 return parseSetSoftFloatDirective();
6877 } else if (Tok.getString() == "hardfloat") {
6878 return parseSetHardFloatDirective();
6880 // It is just an identifier, look for an assignment.
6881 parseSetAssignment();
6888 /// parseDataDirective
6889 /// ::= .word [ expression (, expression)* ]
6890 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
6891 MCAsmParser &Parser = getParser();
6892 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6894 const MCExpr *Value;
6895 if (getParser().parseExpression(Value))
6898 getParser().getStreamer().EmitValue(Value, Size);
6900 if (getLexer().is(AsmToken::EndOfStatement))
6903 if (getLexer().isNot(AsmToken::Comma))
6904 return Error(L, "unexpected token, expected comma");
6913 /// parseDirectiveGpWord
6914 /// ::= .gpword local_sym
6915 bool MipsAsmParser::parseDirectiveGpWord() {
6916 MCAsmParser &Parser = getParser();
6917 const MCExpr *Value;
6918 // EmitGPRel32Value requires an expression, so we are using base class
6919 // method to evaluate the expression.
6920 if (getParser().parseExpression(Value))
6922 getParser().getStreamer().EmitGPRel32Value(Value);
6924 if (getLexer().isNot(AsmToken::EndOfStatement))
6925 return Error(getLexer().getLoc(),
6926 "unexpected token, expected end of statement");
6927 Parser.Lex(); // Eat EndOfStatement token.
6931 /// parseDirectiveGpDWord
6932 /// ::= .gpdword local_sym
6933 bool MipsAsmParser::parseDirectiveGpDWord() {
6934 MCAsmParser &Parser = getParser();
6935 const MCExpr *Value;
6936 // EmitGPRel64Value requires an expression, so we are using base class
6937 // method to evaluate the expression.
6938 if (getParser().parseExpression(Value))
6940 getParser().getStreamer().EmitGPRel64Value(Value);
6942 if (getLexer().isNot(AsmToken::EndOfStatement))
6943 return Error(getLexer().getLoc(),
6944 "unexpected token, expected end of statement");
6945 Parser.Lex(); // Eat EndOfStatement token.
6949 /// parseDirectiveDtpRelWord
6950 /// ::= .dtprelword tls_sym
6951 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6952 MCAsmParser &Parser = getParser();
6953 const MCExpr *Value;
6954 // EmitDTPRel32Value requires an expression, so we are using base class
6955 // method to evaluate the expression.
6956 if (getParser().parseExpression(Value))
6958 getParser().getStreamer().EmitDTPRel32Value(Value);
6960 if (getLexer().isNot(AsmToken::EndOfStatement))
6961 return Error(getLexer().getLoc(),
6962 "unexpected token, expected end of statement");
6963 Parser.Lex(); // Eat EndOfStatement token.
6967 /// parseDirectiveDtpRelDWord
6968 /// ::= .dtpreldword tls_sym
6969 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6970 MCAsmParser &Parser = getParser();
6971 const MCExpr *Value;
6972 // EmitDTPRel64Value requires an expression, so we are using base class
6973 // method to evaluate the expression.
6974 if (getParser().parseExpression(Value))
6976 getParser().getStreamer().EmitDTPRel64Value(Value);
6978 if (getLexer().isNot(AsmToken::EndOfStatement))
6979 return Error(getLexer().getLoc(),
6980 "unexpected token, expected end of statement");
6981 Parser.Lex(); // Eat EndOfStatement token.
6985 /// parseDirectiveTpRelWord
6986 /// ::= .tprelword tls_sym
6987 bool MipsAsmParser::parseDirectiveTpRelWord() {
6988 MCAsmParser &Parser = getParser();
6989 const MCExpr *Value;
6990 // EmitTPRel32Value requires an expression, so we are using base class
6991 // method to evaluate the expression.
6992 if (getParser().parseExpression(Value))
6994 getParser().getStreamer().EmitTPRel32Value(Value);
6996 if (getLexer().isNot(AsmToken::EndOfStatement))
6997 return Error(getLexer().getLoc(),
6998 "unexpected token, expected end of statement");
6999 Parser.Lex(); // Eat EndOfStatement token.
7003 /// parseDirectiveTpRelDWord
7004 /// ::= .tpreldword tls_sym
7005 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7006 MCAsmParser &Parser = getParser();
7007 const MCExpr *Value;
7008 // EmitTPRel64Value requires an expression, so we are using base class
7009 // method to evaluate the expression.
7010 if (getParser().parseExpression(Value))
7012 getParser().getStreamer().EmitTPRel64Value(Value);
7014 if (getLexer().isNot(AsmToken::EndOfStatement))
7015 return Error(getLexer().getLoc(),
7016 "unexpected token, expected end of statement");
7017 Parser.Lex(); // Eat EndOfStatement token.
7021 bool MipsAsmParser::parseDirectiveOption() {
7022 MCAsmParser &Parser = getParser();
7023 // Get the option token.
7024 AsmToken Tok = Parser.getTok();
7025 // At the moment only identifiers are supported.
7026 if (Tok.isNot(AsmToken::Identifier)) {
7027 return Error(Parser.getTok().getLoc(),
7028 "unexpected token, expected identifier");
7031 StringRef Option = Tok.getIdentifier();
7033 if (Option == "pic0") {
7034 // MipsAsmParser needs to know if the current PIC mode changes.
7035 IsPicEnabled = false;
7037 getTargetStreamer().emitDirectiveOptionPic0();
7039 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7040 return Error(Parser.getTok().getLoc(),
7041 "unexpected token, expected end of statement");
7046 if (Option == "pic2") {
7047 // MipsAsmParser needs to know if the current PIC mode changes.
7048 IsPicEnabled = true;
7050 getTargetStreamer().emitDirectiveOptionPic2();
7052 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7053 return Error(Parser.getTok().getLoc(),
7054 "unexpected token, expected end of statement");
7060 Warning(Parser.getTok().getLoc(),
7061 "unknown option, expected 'pic0' or 'pic2'");
7062 Parser.eatToEndOfStatement();
7066 /// parseInsnDirective
7068 bool MipsAsmParser::parseInsnDirective() {
7069 // If this is not the end of the statement, report an error.
7070 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7071 reportParseError("unexpected token, expected end of statement");
7075 // The actual label marking happens in
7076 // MipsELFStreamer::createPendingLabelRelocs().
7077 getTargetStreamer().emitDirectiveInsn();
7079 getParser().Lex(); // Eat EndOfStatement token.
7083 /// parseRSectionDirective
7085 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7086 // If this is not the end of the statement, report an error.
7087 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7088 reportParseError("unexpected token, expected end of statement");
7092 MCSection *ELFSection = getContext().getELFSection(
7093 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7094 getParser().getStreamer().SwitchSection(ELFSection);
7096 getParser().Lex(); // Eat EndOfStatement token.
7100 /// parseSSectionDirective
7103 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7104 // If this is not the end of the statement, report an error.
7105 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7106 reportParseError("unexpected token, expected end of statement");
7110 MCSection *ELFSection = getContext().getELFSection(
7111 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7112 getParser().getStreamer().SwitchSection(ELFSection);
7114 getParser().Lex(); // Eat EndOfStatement token.
7118 /// parseDirectiveModule
7119 /// ::= .module oddspreg
7120 /// ::= .module nooddspreg
7121 /// ::= .module fp=value
7122 /// ::= .module softfloat
7123 /// ::= .module hardfloat
7125 bool MipsAsmParser::parseDirectiveModule() {
7126 MCAsmParser &Parser = getParser();
7127 MCAsmLexer &Lexer = getLexer();
7128 SMLoc L = Lexer.getLoc();
7130 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7131 // TODO : get a better message.
7132 reportParseError(".module directive must appear before any code");
7137 if (Parser.parseIdentifier(Option)) {
7138 reportParseError("expected .module option identifier");
7142 if (Option == "oddspreg") {
7143 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7145 // Synchronize the abiflags information with the FeatureBits information we
7147 getTargetStreamer().updateABIInfo(*this);
7149 // If printing assembly, use the recently updated abiflags information.
7150 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7151 // emitted at the end).
7152 getTargetStreamer().emitDirectiveModuleOddSPReg();
7154 // If this is not the end of the statement, report an error.
7155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7156 reportParseError("unexpected token, expected end of statement");
7160 return false; // parseDirectiveModule has finished successfully.
7161 } else if (Option == "nooddspreg") {
7163 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7166 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7168 // Synchronize the abiflags information with the FeatureBits information we
7170 getTargetStreamer().updateABIInfo(*this);
7172 // If printing assembly, use the recently updated abiflags information.
7173 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7174 // emitted at the end).
7175 getTargetStreamer().emitDirectiveModuleOddSPReg();
7177 // If this is not the end of the statement, report an error.
7178 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7179 reportParseError("unexpected token, expected end of statement");
7183 return false; // parseDirectiveModule has finished successfully.
7184 } else if (Option == "fp") {
7185 return parseDirectiveModuleFP();
7186 } else if (Option == "softfloat") {
7187 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7189 // Synchronize the ABI Flags information with the FeatureBits information we
7191 getTargetStreamer().updateABIInfo(*this);
7193 // If printing assembly, use the recently updated ABI Flags information.
7194 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7196 getTargetStreamer().emitDirectiveModuleSoftFloat();
7198 // If this is not the end of the statement, report an error.
7199 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7200 reportParseError("unexpected token, expected end of statement");
7204 return false; // parseDirectiveModule has finished successfully.
7205 } else if (Option == "hardfloat") {
7206 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7208 // Synchronize the ABI Flags information with the FeatureBits information we
7210 getTargetStreamer().updateABIInfo(*this);
7212 // If printing assembly, use the recently updated ABI Flags information.
7213 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7215 getTargetStreamer().emitDirectiveModuleHardFloat();
7217 // If this is not the end of the statement, report an error.
7218 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7219 reportParseError("unexpected token, expected end of statement");
7223 return false; // parseDirectiveModule has finished successfully.
7224 } else if (Option == "mt") {
7225 setModuleFeatureBits(Mips::FeatureMT, "mt");
7227 // Synchronize the ABI Flags information with the FeatureBits information we
7229 getTargetStreamer().updateABIInfo(*this);
7231 // If printing assembly, use the recently updated ABI Flags information.
7232 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7234 getTargetStreamer().emitDirectiveModuleMT();
7236 // If this is not the end of the statement, report an error.
7237 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7238 reportParseError("unexpected token, expected end of statement");
7242 return false; // parseDirectiveModule has finished successfully.
7244 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7248 /// parseDirectiveModuleFP
7252 bool MipsAsmParser::parseDirectiveModuleFP() {
7253 MCAsmParser &Parser = getParser();
7254 MCAsmLexer &Lexer = getLexer();
7256 if (Lexer.isNot(AsmToken::Equal)) {
7257 reportParseError("unexpected token, expected equals sign '='");
7260 Parser.Lex(); // Eat '=' token.
7262 MipsABIFlagsSection::FpABIKind FpABI;
7263 if (!parseFpABIValue(FpABI, ".module"))
7266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7267 reportParseError("unexpected token, expected end of statement");
7271 // Synchronize the abiflags information with the FeatureBits information we
7273 getTargetStreamer().updateABIInfo(*this);
7275 // If printing assembly, use the recently updated abiflags information.
7276 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7277 // emitted at the end).
7278 getTargetStreamer().emitDirectiveModuleFP();
7280 Parser.Lex(); // Consume the EndOfStatement.
7284 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7285 StringRef Directive) {
7286 MCAsmParser &Parser = getParser();
7287 MCAsmLexer &Lexer = getLexer();
7288 bool ModuleLevelOptions = Directive == ".module";
7290 if (Lexer.is(AsmToken::Identifier)) {
7291 StringRef Value = Parser.getTok().getString();
7294 if (Value != "xx") {
7295 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7300 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7304 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7305 if (ModuleLevelOptions) {
7306 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7307 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7309 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7310 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7315 if (Lexer.is(AsmToken::Integer)) {
7316 unsigned Value = Parser.getTok().getIntVal();
7319 if (Value != 32 && Value != 64) {
7320 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7326 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7330 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7331 if (ModuleLevelOptions) {
7332 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7333 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7335 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7336 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7339 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7340 if (ModuleLevelOptions) {
7341 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7342 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7344 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7345 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7355 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7356 // This returns false if this function recognizes the directive
7357 // regardless of whether it is successfully handles or reports an
7358 // error. Otherwise it returns true to give the generic parser a
7359 // chance at recognizing it.
7361 MCAsmParser &Parser = getParser();
7362 StringRef IDVal = DirectiveID.getString();
7364 if (IDVal == ".cpload") {
7365 parseDirectiveCpLoad(DirectiveID.getLoc());
7368 if (IDVal == ".cprestore") {
7369 parseDirectiveCpRestore(DirectiveID.getLoc());
7372 if (IDVal == ".dword") {
7373 parseDataDirective(8, DirectiveID.getLoc());
7376 if (IDVal == ".ent") {
7377 StringRef SymbolName;
7379 if (Parser.parseIdentifier(SymbolName)) {
7380 reportParseError("expected identifier after .ent");
7384 // There's an undocumented extension that allows an integer to
7385 // follow the name of the procedure which AFAICS is ignored by GAS.
7386 // Example: .ent foo,2
7387 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7388 if (getLexer().isNot(AsmToken::Comma)) {
7389 // Even though we accept this undocumented extension for compatibility
7390 // reasons, the additional integer argument does not actually change
7391 // the behaviour of the '.ent' directive, so we would like to discourage
7392 // its use. We do this by not referring to the extended version in
7393 // error messages which are not directly related to its use.
7394 reportParseError("unexpected token, expected end of statement");
7397 Parser.Lex(); // Eat the comma.
7398 const MCExpr *DummyNumber;
7399 int64_t DummyNumberVal;
7400 // If the user was explicitly trying to use the extended version,
7401 // we still give helpful extension-related error messages.
7402 if (Parser.parseExpression(DummyNumber)) {
7403 reportParseError("expected number after comma");
7406 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7407 reportParseError("expected an absolute expression after comma");
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 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7420 getTargetStreamer().emitDirectiveEnt(*Sym);
7422 IsCpRestoreSet = false;
7426 if (IDVal == ".end") {
7427 StringRef SymbolName;
7429 if (Parser.parseIdentifier(SymbolName)) {
7430 reportParseError("expected identifier after .end");
7434 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7435 reportParseError("unexpected token, expected end of statement");
7439 if (CurrentFn == nullptr) {
7440 reportParseError(".end used without .ent");
7444 if ((SymbolName != CurrentFn->getName())) {
7445 reportParseError(".end symbol does not match .ent symbol");
7449 getTargetStreamer().emitDirectiveEnd(SymbolName);
7450 CurrentFn = nullptr;
7451 IsCpRestoreSet = false;
7455 if (IDVal == ".frame") {
7456 // .frame $stack_reg, frame_size_in_bytes, $return_reg
7457 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7458 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7459 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7460 reportParseError("expected stack register");
7464 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7465 if (!StackRegOpnd.isGPRAsmReg()) {
7466 reportParseError(StackRegOpnd.getStartLoc(),
7467 "expected general purpose register");
7470 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7472 if (Parser.getTok().is(AsmToken::Comma))
7475 reportParseError("unexpected token, expected comma");
7479 // Parse the frame size.
7480 const MCExpr *FrameSize;
7481 int64_t FrameSizeVal;
7483 if (Parser.parseExpression(FrameSize)) {
7484 reportParseError("expected frame size value");
7488 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
7489 reportParseError("frame size not an absolute expression");
7493 if (Parser.getTok().is(AsmToken::Comma))
7496 reportParseError("unexpected token, expected comma");
7500 // Parse the return register.
7502 ResTy = parseAnyRegister(TmpReg);
7503 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7504 reportParseError("expected return register");
7508 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7509 if (!ReturnRegOpnd.isGPRAsmReg()) {
7510 reportParseError(ReturnRegOpnd.getStartLoc(),
7511 "expected general purpose register");
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().emitFrame(StackReg, FrameSizeVal,
7522 ReturnRegOpnd.getGPR32Reg());
7523 IsCpRestoreSet = false;
7527 if (IDVal == ".set") {
7528 parseDirectiveSet();
7532 if (IDVal == ".mask" || IDVal == ".fmask") {
7533 // .mask bitmask, frame_offset
7534 // bitmask: One bit for each register used.
7535 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
7536 // first register is expected to be saved.
7538 // .mask 0x80000000, -4
7539 // .fmask 0x80000000, -4
7542 // Parse the bitmask
7543 const MCExpr *BitMask;
7546 if (Parser.parseExpression(BitMask)) {
7547 reportParseError("expected bitmask value");
7551 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
7552 reportParseError("bitmask not an absolute expression");
7556 if (Parser.getTok().is(AsmToken::Comma))
7559 reportParseError("unexpected token, expected comma");
7563 // Parse the frame_offset
7564 const MCExpr *FrameOffset;
7565 int64_t FrameOffsetVal;
7567 if (Parser.parseExpression(FrameOffset)) {
7568 reportParseError("expected frame offset value");
7572 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
7573 reportParseError("frame offset not an absolute expression");
7577 // If this is not the end of the statement, report an error.
7578 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7579 reportParseError("unexpected token, expected end of statement");
7583 if (IDVal == ".mask")
7584 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
7586 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
7590 if (IDVal == ".nan")
7591 return parseDirectiveNaN();
7593 if (IDVal == ".gpword") {
7594 parseDirectiveGpWord();
7598 if (IDVal == ".gpdword") {
7599 parseDirectiveGpDWord();
7603 if (IDVal == ".dtprelword") {
7604 parseDirectiveDtpRelWord();
7608 if (IDVal == ".dtpreldword") {
7609 parseDirectiveDtpRelDWord();
7613 if (IDVal == ".tprelword") {
7614 parseDirectiveTpRelWord();
7618 if (IDVal == ".tpreldword") {
7619 parseDirectiveTpRelDWord();
7623 if (IDVal == ".word") {
7624 parseDataDirective(4, DirectiveID.getLoc());
7628 if (IDVal == ".hword") {
7629 parseDataDirective(2, DirectiveID.getLoc());
7633 if (IDVal == ".option") {
7634 parseDirectiveOption();
7638 if (IDVal == ".abicalls") {
7639 getTargetStreamer().emitDirectiveAbiCalls();
7640 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7641 Error(Parser.getTok().getLoc(),
7642 "unexpected token, expected end of statement");
7647 if (IDVal == ".cpsetup") {
7648 parseDirectiveCPSetup();
7651 if (IDVal == ".cpreturn") {
7652 parseDirectiveCPReturn();
7655 if (IDVal == ".module") {
7656 parseDirectiveModule();
7659 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
7660 parseInternalDirectiveReallowModule();
7663 if (IDVal == ".insn") {
7664 parseInsnDirective();
7667 if (IDVal == ".rdata") {
7668 parseRSectionDirective(".rodata");
7671 if (IDVal == ".sbss") {
7672 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
7675 if (IDVal == ".sdata") {
7676 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
7683 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
7684 // If this is not the end of the statement, report an error.
7685 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7686 reportParseError("unexpected token, expected end of statement");
7690 getTargetStreamer().reallowModuleDirective();
7692 getParser().Lex(); // Eat EndOfStatement token.
7696 extern "C" void LLVMInitializeMipsAsmParser() {
7697 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
7698 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
7699 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
7700 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
7703 #define GET_REGISTER_MATCHER
7704 #define GET_MATCHER_IMPLEMENTATION
7705 #include "MipsGenAsmMatcher.inc"
7707 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
7708 // Find the appropriate table for this asm variant.
7709 const MatchEntry *Start, *End;
7710 switch (VariantID) {
7711 default: llvm_unreachable("invalid variant!");
7712 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
7714 // Search the table.
7715 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
7716 return MnemonicRange.first != MnemonicRange.second;