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 expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308 const MCSubtargetInfo *STI);
310 bool reportParseError(Twine ErrorMsg);
311 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
313 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
315 bool isEvaluated(const MCExpr *Expr);
316 bool parseSetMips0Directive();
317 bool parseSetArchDirective();
318 bool parseSetFeature(uint64_t Feature);
319 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
320 bool parseDirectiveCpLoad(SMLoc Loc);
321 bool parseDirectiveCpRestore(SMLoc Loc);
322 bool parseDirectiveCPSetup();
323 bool parseDirectiveCPReturn();
324 bool parseDirectiveNaN();
325 bool parseDirectiveSet();
326 bool parseDirectiveOption();
327 bool parseInsnDirective();
328 bool parseRSectionDirective(StringRef Section);
329 bool parseSSectionDirective(StringRef Section, unsigned Type);
331 bool parseSetAtDirective();
332 bool parseSetNoAtDirective();
333 bool parseSetMacroDirective();
334 bool parseSetNoMacroDirective();
335 bool parseSetMsaDirective();
336 bool parseSetNoMsaDirective();
337 bool parseSetNoDspDirective();
338 bool parseSetReorderDirective();
339 bool parseSetNoReorderDirective();
340 bool parseSetMips16Directive();
341 bool parseSetNoMips16Directive();
342 bool parseSetFpDirective();
343 bool parseSetOddSPRegDirective();
344 bool parseSetNoOddSPRegDirective();
345 bool parseSetPopDirective();
346 bool parseSetPushDirective();
347 bool parseSetSoftFloatDirective();
348 bool parseSetHardFloatDirective();
349 bool parseSetMtDirective();
350 bool parseSetNoMtDirective();
352 bool parseSetAssignment();
354 bool parseDataDirective(unsigned Size, SMLoc L);
355 bool parseDirectiveGpWord();
356 bool parseDirectiveGpDWord();
357 bool parseDirectiveDtpRelWord();
358 bool parseDirectiveDtpRelDWord();
359 bool parseDirectiveTpRelWord();
360 bool parseDirectiveTpRelDWord();
361 bool parseDirectiveModule();
362 bool parseDirectiveModuleFP();
363 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
364 StringRef Directive);
366 bool parseInternalDirectiveReallowModule();
368 bool eatComma(StringRef ErrorStr);
370 int matchCPURegisterName(StringRef Symbol);
372 int matchHWRegsRegisterName(StringRef Symbol);
374 int matchFPURegisterName(StringRef Name);
376 int matchFCCRegisterName(StringRef Name);
378 int matchACRegisterName(StringRef Name);
380 int matchMSA128RegisterName(StringRef Name);
382 int matchMSA128CtrlRegisterName(StringRef Name);
384 unsigned getReg(int RC, int RegNo);
386 /// Returns the internal register number for the current AT. Also checks if
387 /// the current AT is unavailable (set to $0) and gives an error if it is.
388 /// This should be used in pseudo-instruction expansions which need AT.
389 unsigned getATReg(SMLoc Loc);
393 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
394 const MCSubtargetInfo *STI);
396 // Helper function that checks if the value of a vector index is within the
397 // boundaries of accepted values for each RegisterKind
398 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
399 bool validateMSAIndex(int Val, int RegKind);
401 // Selects a new architecture by updating the FeatureBits with the necessary
402 // info including implied dependencies.
403 // Internally, it clears all the feature bits related to *any* architecture
404 // and selects the new one using the ToggleFeature functionality of the
405 // MCSubtargetInfo object that handles implied dependencies. The reason we
406 // clear all the arch related bits manually is because ToggleFeature only
407 // clears the features that imply the feature being cleared and not the
408 // features implied by the feature being cleared. This is easier to see
410 // --------------------------------------------------
411 // | Feature | Implies |
412 // | -------------------------------------------------|
413 // | FeatureMips1 | None |
414 // | FeatureMips2 | FeatureMips1 |
415 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
416 // | FeatureMips4 | FeatureMips3 |
418 // --------------------------------------------------
420 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
421 // FeatureMipsGP64 | FeatureMips1)
422 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
423 void selectArch(StringRef ArchFeature) {
424 MCSubtargetInfo &STI = copySTI();
425 FeatureBitset FeatureBits = STI.getFeatureBits();
426 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
427 STI.setFeatureBits(FeatureBits);
428 setAvailableFeatures(
429 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
430 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
433 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
434 if (!(getSTI().getFeatureBits()[Feature])) {
435 MCSubtargetInfo &STI = copySTI();
436 setAvailableFeatures(
437 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
438 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
442 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
443 if (getSTI().getFeatureBits()[Feature]) {
444 MCSubtargetInfo &STI = copySTI();
445 setAvailableFeatures(
446 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
447 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
451 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
452 setFeatureBits(Feature, FeatureString);
453 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
456 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
457 clearFeatureBits(Feature, FeatureString);
458 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
462 enum MipsMatchResultTy {
463 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
464 Match_RequiresDifferentOperands,
465 Match_RequiresNoZeroRegister,
466 Match_RequiresSameSrcAndDst,
467 Match_NoFCCRegisterForCurrentISA,
468 Match_NonZeroOperandForSync,
469 #define GET_OPERAND_DIAGNOSTIC_TYPES
470 #include "MipsGenAsmMatcher.inc"
471 #undef GET_OPERAND_DIAGNOSTIC_TYPES
474 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
475 const MCInstrInfo &MII, const MCTargetOptions &Options)
476 : MCTargetAsmParser(Options, sti),
477 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
478 sti.getCPU(), Options)) {
479 MCAsmParserExtension::Initialize(parser);
481 parser.addAliasForDirective(".asciiz", ".asciz");
483 // Initialize the set of available features.
484 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
486 // Remember the initial assembler options. The user can not modify these.
487 AssemblerOptions.push_back(
488 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
490 // Create an assembler options environment for the user to modify.
491 AssemblerOptions.push_back(
492 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
494 getTargetStreamer().updateABIInfo(*this);
496 if (!isABI_O32() && !useOddSPReg() != 0)
497 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
501 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
503 IsCpRestoreSet = false;
504 CpRestoreOffset = -1;
506 const Triple &TheTriple = sti.getTargetTriple();
507 if ((TheTriple.getArch() == Triple::mips) ||
508 (TheTriple.getArch() == Triple::mips64))
509 IsLittleEndian = false;
511 IsLittleEndian = true;
514 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
515 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
517 bool isGP64bit() const {
518 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
521 bool isFP64bit() const {
522 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
525 const MipsABIInfo &getABI() const { return ABI; }
526 bool isABI_N32() const { return ABI.IsN32(); }
527 bool isABI_N64() const { return ABI.IsN64(); }
528 bool isABI_O32() const { return ABI.IsO32(); }
529 bool isABI_FPXX() const {
530 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
533 bool useOddSPReg() const {
534 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
537 bool inMicroMipsMode() const {
538 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
541 bool hasMips1() const {
542 return getSTI().getFeatureBits()[Mips::FeatureMips1];
545 bool hasMips2() const {
546 return getSTI().getFeatureBits()[Mips::FeatureMips2];
549 bool hasMips3() const {
550 return getSTI().getFeatureBits()[Mips::FeatureMips3];
553 bool hasMips4() const {
554 return getSTI().getFeatureBits()[Mips::FeatureMips4];
557 bool hasMips5() const {
558 return getSTI().getFeatureBits()[Mips::FeatureMips5];
561 bool hasMips32() const {
562 return getSTI().getFeatureBits()[Mips::FeatureMips32];
565 bool hasMips64() const {
566 return getSTI().getFeatureBits()[Mips::FeatureMips64];
569 bool hasMips32r2() const {
570 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
573 bool hasMips64r2() const {
574 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
577 bool hasMips32r3() const {
578 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
581 bool hasMips64r3() const {
582 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
585 bool hasMips32r5() const {
586 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
589 bool hasMips64r5() const {
590 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
593 bool hasMips32r6() const {
594 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
597 bool hasMips64r6() const {
598 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
601 bool hasDSP() const {
602 return getSTI().getFeatureBits()[Mips::FeatureDSP];
605 bool hasDSPR2() const {
606 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
609 bool hasDSPR3() const {
610 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
613 bool hasMSA() const {
614 return getSTI().getFeatureBits()[Mips::FeatureMSA];
617 bool hasCnMips() const {
618 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
625 bool inMips16Mode() const {
626 return getSTI().getFeatureBits()[Mips::FeatureMips16];
629 bool useTraps() const {
630 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
633 bool useSoftFloat() const {
634 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
637 return getSTI().getFeatureBits()[Mips::FeatureMT];
640 /// Warn if RegIndex is the same as the current AT.
641 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
643 void warnIfNoMacro(SMLoc Loc);
645 bool isLittle() const { return IsLittleEndian; }
647 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
648 AsmToken::TokenKind OperatorToken,
649 MCContext &Ctx) override {
650 switch(OperatorToken) {
652 llvm_unreachable("Unknown token");
654 case AsmToken::PercentCall16:
655 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
656 case AsmToken::PercentCall_Hi:
657 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
658 case AsmToken::PercentCall_Lo:
659 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
660 case AsmToken::PercentDtprel_Hi:
661 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
662 case AsmToken::PercentDtprel_Lo:
663 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
664 case AsmToken::PercentGot:
665 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
666 case AsmToken::PercentGot_Disp:
667 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
668 case AsmToken::PercentGot_Hi:
669 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
670 case AsmToken::PercentGot_Lo:
671 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
672 case AsmToken::PercentGot_Ofst:
673 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
674 case AsmToken::PercentGot_Page:
675 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
676 case AsmToken::PercentGottprel:
677 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
678 case AsmToken::PercentGp_Rel:
679 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
680 case AsmToken::PercentHi:
681 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
682 case AsmToken::PercentHigher:
683 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
684 case AsmToken::PercentHighest:
685 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
686 case AsmToken::PercentLo:
687 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
688 case AsmToken::PercentNeg:
689 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
690 case AsmToken::PercentPcrel_Hi:
691 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
692 case AsmToken::PercentPcrel_Lo:
693 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
694 case AsmToken::PercentTlsgd:
695 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
696 case AsmToken::PercentTlsldm:
697 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
698 case AsmToken::PercentTprel_Hi:
699 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
700 case AsmToken::PercentTprel_Lo:
701 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
706 /// MipsOperand - Instances of this class represent a parsed Mips machine
708 class MipsOperand : public MCParsedAsmOperand {
710 /// Broad categories of register classes
711 /// The exact class is finalized by the render method.
713 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
714 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
716 RegKind_FCC = 4, /// FCC
717 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
718 RegKind_MSACtrl = 16, /// MSA control registers
719 RegKind_COP2 = 32, /// COP2
720 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
722 RegKind_CCR = 128, /// CCR
723 RegKind_HWRegs = 256, /// HWRegs
724 RegKind_COP3 = 512, /// COP3
725 RegKind_COP0 = 1024, /// COP0
726 /// Potentially any (e.g. $1)
727 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
728 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
729 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
734 k_Immediate, /// An immediate (possibly involving symbol references)
735 k_Memory, /// Base + Offset Memory Address
736 k_RegisterIndex, /// A register index in one or more RegKind.
737 k_Token, /// A simple token
738 k_RegList, /// A physical register list
739 k_RegPair /// A pair of physical register
743 MipsOperand(KindTy K, MipsAsmParser &Parser)
744 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
746 ~MipsOperand() override {
755 case k_RegisterIndex:
763 /// For diagnostics, and checking the assembler temporary
764 MipsAsmParser &AsmParser;
772 unsigned Index; /// Index into the register class
773 RegKind Kind; /// Bitfield of the kinds it could possibly be
774 struct Token Tok; /// The input token this operand originated from.
775 const MCRegisterInfo *RegInfo;
788 SmallVector<unsigned, 10> *List;
793 struct RegIdxOp RegIdx;
796 struct RegListOp RegList;
799 SMLoc StartLoc, EndLoc;
801 /// Internal constructor for register kinds
802 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
804 const MCRegisterInfo *RegInfo,
806 MipsAsmParser &Parser) {
807 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
808 Op->RegIdx.Index = Index;
809 Op->RegIdx.RegInfo = RegInfo;
810 Op->RegIdx.Kind = RegKind;
811 Op->RegIdx.Tok.Data = Str.data();
812 Op->RegIdx.Tok.Length = Str.size();
819 /// Coerce the register to GPR32 and return the real register for the current
821 unsigned getGPR32Reg() const {
822 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
823 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
824 unsigned ClassID = Mips::GPR32RegClassID;
825 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
828 /// Coerce the register to GPR32 and return the real register for the current
830 unsigned getGPRMM16Reg() const {
831 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
832 unsigned ClassID = Mips::GPR32RegClassID;
833 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
836 /// Coerce the register to GPR64 and return the real register for the current
838 unsigned getGPR64Reg() const {
839 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
840 unsigned ClassID = Mips::GPR64RegClassID;
841 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
845 /// Coerce the register to AFGR64 and return the real register for the current
847 unsigned getAFGR64Reg() const {
848 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
849 if (RegIdx.Index % 2 != 0)
850 AsmParser.Warning(StartLoc, "Float register should be even.");
851 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
852 .getRegister(RegIdx.Index / 2);
855 /// Coerce the register to FGR64 and return the real register for the current
857 unsigned getFGR64Reg() const {
858 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
859 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
860 .getRegister(RegIdx.Index);
863 /// Coerce the register to FGR32 and return the real register for the current
865 unsigned getFGR32Reg() const {
866 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
867 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
868 .getRegister(RegIdx.Index);
871 /// Coerce the register to FGRH32 and return the real register for the current
873 unsigned getFGRH32Reg() const {
874 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
875 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
876 .getRegister(RegIdx.Index);
879 /// Coerce the register to FCC and return the real register for the current
881 unsigned getFCCReg() const {
882 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
883 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
884 .getRegister(RegIdx.Index);
887 /// Coerce the register to MSA128 and return the real register for the current
889 unsigned getMSA128Reg() const {
890 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
891 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
893 unsigned ClassID = Mips::MSA128BRegClassID;
894 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
897 /// Coerce the register to MSACtrl and return the real register for the
899 unsigned getMSACtrlReg() const {
900 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
901 unsigned ClassID = Mips::MSACtrlRegClassID;
902 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
905 /// Coerce the register to COP0 and return the real register for the
907 unsigned getCOP0Reg() const {
908 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
909 unsigned ClassID = Mips::COP0RegClassID;
910 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
913 /// Coerce the register to COP2 and return the real register for the
915 unsigned getCOP2Reg() const {
916 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
917 unsigned ClassID = Mips::COP2RegClassID;
918 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
921 /// Coerce the register to COP3 and return the real register for the
923 unsigned getCOP3Reg() const {
924 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
925 unsigned ClassID = Mips::COP3RegClassID;
926 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
929 /// Coerce the register to ACC64DSP and return the real register for the
931 unsigned getACC64DSPReg() const {
932 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
933 unsigned ClassID = Mips::ACC64DSPRegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 /// Coerce the register to HI32DSP and return the real register for the
939 unsigned getHI32DSPReg() const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
941 unsigned ClassID = Mips::HI32DSPRegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 /// Coerce the register to LO32DSP and return the real register for the
947 unsigned getLO32DSPReg() const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
949 unsigned ClassID = Mips::LO32DSPRegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
953 /// Coerce the register to CCR and return the real register for the
955 unsigned getCCRReg() const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
957 unsigned ClassID = Mips::CCRRegClassID;
958 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
961 /// Coerce the register to HWRegs and return the real register for the
963 unsigned getHWRegsReg() const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
965 unsigned ClassID = Mips::HWRegsRegClassID;
966 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
970 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
971 // Add as immediate when possible. Null MCExpr = 0.
973 Inst.addOperand(MCOperand::createImm(0));
974 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
975 Inst.addOperand(MCOperand::createImm(CE->getValue()));
977 Inst.addOperand(MCOperand::createExpr(Expr));
980 void addRegOperands(MCInst &Inst, unsigned N) const {
981 llvm_unreachable("Use a custom parser instead");
984 /// Render the operand to an MCInst as a GPR32
985 /// Asserts if the wrong number of operands are requested, or the operand
986 /// is not a k_RegisterIndex compatible with RegKind_GPR
987 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
988 assert(N == 1 && "Invalid number of operands!");
989 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
992 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
993 assert(N == 1 && "Invalid number of operands!");
994 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
997 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
998 assert(N == 1 && "Invalid number of operands!");
999 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1002 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1003 assert(N == 1 && "Invalid number of operands!");
1004 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1007 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1008 assert(N == 1 && "Invalid number of operands!");
1009 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1012 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1013 assert(N == 1 && "Invalid number of operands!");
1014 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1017 /// Render the operand to an MCInst as a GPR64
1018 /// Asserts if the wrong number of operands are requested, or the operand
1019 /// is not a k_RegisterIndex compatible with RegKind_GPR
1020 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1021 assert(N == 1 && "Invalid number of operands!");
1022 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1025 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1026 assert(N == 1 && "Invalid number of operands!");
1027 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1030 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1031 assert(N == 1 && "Invalid number of operands!");
1032 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1035 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1036 assert(N == 1 && "Invalid number of operands!");
1037 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1040 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1041 assert(N == 1 && "Invalid number of operands!");
1042 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1045 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1046 assert(N == 1 && "Invalid number of operands!");
1047 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1048 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1049 // FIXME: This should propagate failure up to parseStatement.
1050 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1051 AsmParser.getParser().printError(
1052 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1056 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1057 assert(N == 1 && "Invalid number of operands!");
1058 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1059 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1060 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1061 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1065 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1066 assert(N == 1 && "Invalid number of operands!");
1067 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1070 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1071 assert(N == 1 && "Invalid number of operands!");
1072 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1075 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1076 assert(N == 1 && "Invalid number of operands!");
1077 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1080 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1081 assert(N == 1 && "Invalid number of operands!");
1082 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1085 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1086 assert(N == 1 && "Invalid number of operands!");
1087 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1090 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1091 assert(N == 1 && "Invalid number of operands!");
1092 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1095 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1096 assert(N == 1 && "Invalid number of operands!");
1097 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1100 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1101 assert(N == 1 && "Invalid number of operands!");
1102 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1105 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1106 assert(N == 1 && "Invalid number of operands!");
1107 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1110 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1111 assert(N == 1 && "Invalid number of operands!");
1112 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1115 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1116 assert(N == 1 && "Invalid number of operands!");
1117 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1120 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1121 assert(N == 1 && "Invalid number of operands!");
1122 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1125 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1126 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1127 assert(N == 1 && "Invalid number of operands!");
1128 uint64_t Imm = getConstantImm() - Offset;
1129 Imm &= (1ULL << Bits) - 1;
1131 Imm += AdjustOffset;
1132 Inst.addOperand(MCOperand::createImm(Imm));
1135 template <unsigned Bits>
1136 void addSImmOperands(MCInst &Inst, unsigned N) const {
1137 if (isImm() && !isConstantImm()) {
1138 addExpr(Inst, getImm());
1141 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1144 template <unsigned Bits>
1145 void addUImmOperands(MCInst &Inst, unsigned N) const {
1146 if (isImm() && !isConstantImm()) {
1147 addExpr(Inst, getImm());
1150 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1153 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1154 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1155 assert(N == 1 && "Invalid number of operands!");
1156 int64_t Imm = getConstantImm() - Offset;
1157 Imm = SignExtend64<Bits>(Imm);
1159 Imm += AdjustOffset;
1160 Inst.addOperand(MCOperand::createImm(Imm));
1163 void addImmOperands(MCInst &Inst, unsigned N) const {
1164 assert(N == 1 && "Invalid number of operands!");
1165 const MCExpr *Expr = getImm();
1166 addExpr(Inst, Expr);
1169 void addMemOperands(MCInst &Inst, unsigned N) const {
1170 assert(N == 2 && "Invalid number of operands!");
1172 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1173 ? getMemBase()->getGPR64Reg()
1174 : getMemBase()->getGPR32Reg()));
1176 const MCExpr *Expr = getMemOff();
1177 addExpr(Inst, Expr);
1180 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1181 assert(N == 2 && "Invalid number of operands!");
1183 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1185 const MCExpr *Expr = getMemOff();
1186 addExpr(Inst, Expr);
1189 void addRegListOperands(MCInst &Inst, unsigned N) const {
1190 assert(N == 1 && "Invalid number of operands!");
1192 for (auto RegNo : getRegList())
1193 Inst.addOperand(MCOperand::createReg(RegNo));
1196 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1197 assert(N == 2 && "Invalid number of operands!");
1198 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1199 unsigned RegNo = getRegPair();
1200 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1201 Inst.addOperand(MCOperand::createReg(
1202 RegIdx.RegInfo->getRegClass(
1203 AsmParser.getABI().AreGprs64bit()
1204 ? Mips::GPR64RegClassID
1205 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1206 Inst.addOperand(MCOperand::createReg(
1207 RegIdx.RegInfo->getRegClass(
1208 AsmParser.getABI().AreGprs64bit()
1209 ? Mips::GPR64RegClassID
1210 : Mips::GPR32RegClassID).getRegister(RegNo)));
1213 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1214 assert(N == 2 && "Invalid number of operands!");
1215 for (auto RegNo : getRegList())
1216 Inst.addOperand(MCOperand::createReg(RegNo));
1219 bool isReg() const override {
1220 // As a special case until we sort out the definition of div/divu, accept
1221 // $0/$zero here so that MCK_ZERO works correctly.
1222 return isGPRAsmReg() && RegIdx.Index == 0;
1225 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1226 bool isImm() const override { return Kind == k_Immediate; }
1228 bool isConstantImm() const {
1230 return isImm() && getImm()->evaluateAsAbsolute(Res);
1233 bool isConstantImmz() const {
1234 return isConstantImm() && getConstantImm() == 0;
1237 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1238 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1241 template <unsigned Bits> bool isSImm() const {
1242 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1245 template <unsigned Bits> bool isUImm() const {
1246 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1249 template <unsigned Bits> bool isAnyImm() const {
1250 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1251 isUInt<Bits>(getConstantImm()))
1255 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1256 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1259 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1260 return isConstantImm() && getConstantImm() >= Bottom &&
1261 getConstantImm() <= Top;
1264 bool isToken() const override {
1265 // Note: It's not possible to pretend that other operand kinds are tokens.
1266 // The matcher emitter checks tokens first.
1267 return Kind == k_Token;
1270 bool isMem() const override { return Kind == k_Memory; }
1272 bool isConstantMemOff() const {
1273 return isMem() && isa<MCConstantExpr>(getMemOff());
1276 // Allow relocation operators.
1277 // FIXME: This predicate and others need to look through binary expressions
1278 // and determine whether a Value is a constant or not.
1279 template <unsigned Bits, unsigned ShiftAmount = 0>
1280 bool isMemWithSimmOffset() const {
1283 if (!getMemBase()->isGPRAsmReg())
1285 if (isa<MCTargetExpr>(getMemOff()) ||
1286 (isConstantMemOff() &&
1287 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1290 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1291 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1294 bool isMemWithGRPMM16Base() const {
1295 return isMem() && getMemBase()->isMM16AsmReg();
1298 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1299 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1300 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1303 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1304 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1305 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1306 && (getMemBase()->getGPR32Reg() == Mips::SP);
1309 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1310 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1311 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1312 && (getMemBase()->getGPR32Reg() == Mips::GP);
1315 template <unsigned Bits, unsigned ShiftLeftAmount>
1316 bool isScaledUImm() const {
1317 return isConstantImm() &&
1318 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1321 template <unsigned Bits, unsigned ShiftLeftAmount>
1322 bool isScaledSImm() const {
1323 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1325 // Operand can also be a symbol or symbol plus offset in case of relocations.
1326 if (Kind != k_Immediate)
1329 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1330 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1333 bool isRegList16() const {
1337 int Size = RegList.List->size();
1338 if (Size < 2 || Size > 5)
1341 unsigned R0 = RegList.List->front();
1342 unsigned R1 = RegList.List->back();
1343 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1344 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1347 int PrevReg = *RegList.List->begin();
1348 for (int i = 1; i < Size - 1; i++) {
1349 int Reg = (*(RegList.List))[i];
1350 if ( Reg != PrevReg + 1)
1358 bool isInvNum() const { return Kind == k_Immediate; }
1360 bool isLSAImm() const {
1361 if (!isConstantImm())
1363 int64_t Val = getConstantImm();
1364 return 1 <= Val && Val <= 4;
1367 bool isRegList() const { return Kind == k_RegList; }
1369 bool isMovePRegPair() const {
1370 if (Kind != k_RegList || RegList.List->size() != 2)
1373 unsigned R0 = RegList.List->front();
1374 unsigned R1 = RegList.List->back();
1376 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1377 (R0 == Mips::A1 && R1 == Mips::A3) ||
1378 (R0 == Mips::A2 && R1 == Mips::A3) ||
1379 (R0 == Mips::A0 && R1 == Mips::S5) ||
1380 (R0 == Mips::A0 && R1 == Mips::S6) ||
1381 (R0 == Mips::A0 && R1 == Mips::A1) ||
1382 (R0 == Mips::A0 && R1 == Mips::A2) ||
1383 (R0 == Mips::A0 && R1 == Mips::A3) ||
1384 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1385 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1386 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1387 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1388 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1389 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1390 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1391 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1397 StringRef getToken() const {
1398 assert(Kind == k_Token && "Invalid access!");
1399 return StringRef(Tok.Data, Tok.Length);
1402 bool isRegPair() const {
1403 return Kind == k_RegPair && RegIdx.Index <= 30;
1406 unsigned getReg() const override {
1407 // As a special case until we sort out the definition of div/divu, accept
1408 // $0/$zero here so that MCK_ZERO works correctly.
1409 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1410 RegIdx.Kind & RegKind_GPR)
1411 return getGPR32Reg(); // FIXME: GPR64 too
1413 llvm_unreachable("Invalid access!");
1417 const MCExpr *getImm() const {
1418 assert((Kind == k_Immediate) && "Invalid access!");
1422 int64_t getConstantImm() const {
1423 const MCExpr *Val = getImm();
1425 (void)Val->evaluateAsAbsolute(Value);
1429 MipsOperand *getMemBase() const {
1430 assert((Kind == k_Memory) && "Invalid access!");
1434 const MCExpr *getMemOff() const {
1435 assert((Kind == k_Memory) && "Invalid access!");
1439 int64_t getConstantMemOff() const {
1440 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1443 const SmallVectorImpl<unsigned> &getRegList() const {
1444 assert((Kind == k_RegList) && "Invalid access!");
1445 return *(RegList.List);
1448 unsigned getRegPair() const {
1449 assert((Kind == k_RegPair) && "Invalid access!");
1450 return RegIdx.Index;
1453 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1454 MipsAsmParser &Parser) {
1455 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1456 Op->Tok.Data = Str.data();
1457 Op->Tok.Length = Str.size();
1463 /// Create a numeric register (e.g. $1). The exact register remains
1464 /// unresolved until an instruction successfully matches
1465 static std::unique_ptr<MipsOperand>
1466 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1467 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1468 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1469 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1472 /// Create a register that is definitely a GPR.
1473 /// This is typically only used for named registers such as $gp.
1474 static std::unique_ptr<MipsOperand>
1475 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1476 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1477 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1480 /// Create a register that is definitely a FGR.
1481 /// This is typically only used for named registers such as $f0.
1482 static std::unique_ptr<MipsOperand>
1483 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1484 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1485 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1488 /// Create a register that is definitely a HWReg.
1489 /// This is typically only used for named registers such as $hwr_cpunum.
1490 static std::unique_ptr<MipsOperand>
1491 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1492 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1493 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1496 /// Create a register that is definitely an FCC.
1497 /// This is typically only used for named registers such as $fcc0.
1498 static std::unique_ptr<MipsOperand>
1499 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1500 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1501 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1504 /// Create a register that is definitely an ACC.
1505 /// This is typically only used for named registers such as $ac0.
1506 static std::unique_ptr<MipsOperand>
1507 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1508 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1509 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1512 /// Create a register that is definitely an MSA128.
1513 /// This is typically only used for named registers such as $w0.
1514 static std::unique_ptr<MipsOperand>
1515 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1516 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1517 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1520 /// Create a register that is definitely an MSACtrl.
1521 /// This is typically only used for named registers such as $msaaccess.
1522 static std::unique_ptr<MipsOperand>
1523 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1524 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1525 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1528 static std::unique_ptr<MipsOperand>
1529 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1530 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1537 static std::unique_ptr<MipsOperand>
1538 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1539 SMLoc E, MipsAsmParser &Parser) {
1540 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1541 Op->Mem.Base = Base.release();
1548 static std::unique_ptr<MipsOperand>
1549 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1550 MipsAsmParser &Parser) {
1551 assert(Regs.size() > 0 && "Empty list not allowed");
1553 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1554 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1555 Op->StartLoc = StartLoc;
1556 Op->EndLoc = EndLoc;
1560 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1562 MipsAsmParser &Parser) {
1563 auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
1564 Op->RegIdx.Index = MOP.RegIdx.Index;
1565 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1566 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1572 bool isGPRZeroAsmReg() const {
1573 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1576 bool isGPRNonZeroAsmReg() const {
1577 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1581 bool isGPRAsmReg() const {
1582 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1585 bool isMM16AsmReg() const {
1586 if (!(isRegIdx() && RegIdx.Kind))
1588 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1589 || RegIdx.Index == 16 || RegIdx.Index == 17);
1592 bool isMM16AsmRegZero() const {
1593 if (!(isRegIdx() && RegIdx.Kind))
1595 return (RegIdx.Index == 0 ||
1596 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1597 RegIdx.Index == 17);
1600 bool isMM16AsmRegMoveP() const {
1601 if (!(isRegIdx() && RegIdx.Kind))
1603 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1604 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1607 bool isFGRAsmReg() const {
1608 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1609 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1612 bool isStrictlyFGRAsmReg() const {
1613 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1614 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1617 bool isHWRegsAsmReg() const {
1618 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1621 bool isCCRAsmReg() const {
1622 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1625 bool isFCCAsmReg() const {
1626 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1628 return RegIdx.Index <= 7;
1631 bool isACCAsmReg() const {
1632 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1635 bool isCOP0AsmReg() const {
1636 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1639 bool isCOP2AsmReg() const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1643 bool isCOP3AsmReg() const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1647 bool isMSA128AsmReg() const {
1648 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1651 bool isMSACtrlAsmReg() const {
1652 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1655 /// getStartLoc - Get the location of the first token of this operand.
1656 SMLoc getStartLoc() const override { return StartLoc; }
1657 /// getEndLoc - Get the location of the last token of this operand.
1658 SMLoc getEndLoc() const override { return EndLoc; }
1660 void print(raw_ostream &OS) const override {
1669 Mem.Base->print(OS);
1674 case k_RegisterIndex:
1675 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1676 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1683 for (auto Reg : (*RegList.List))
1688 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1693 bool isValidForTie(const MipsOperand &Other) const {
1694 if (Kind != Other.Kind)
1699 llvm_unreachable("Unexpected kind");
1701 case k_RegisterIndex: {
1702 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1703 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1704 return Token == OtherToken;
1708 }; // class MipsOperand
1710 } // end anonymous namespace
1714 extern const MCInstrDesc MipsInsts[];
1716 } // end namespace llvm
1718 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1719 return MipsInsts[Opcode];
1722 static bool hasShortDelaySlot(unsigned Opcode) {
1725 case Mips::JALRS_MM:
1726 case Mips::JALRS16_MM:
1727 case Mips::BGEZALS_MM:
1728 case Mips::BLTZALS_MM:
1735 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1736 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1737 return &SRExpr->getSymbol();
1740 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1741 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1742 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1753 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1754 return getSingleMCSymbol(UExpr->getSubExpr());
1759 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1760 if (isa<MCSymbolRefExpr>(Expr))
1763 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1764 return countMCSymbolRefExpr(BExpr->getLHS()) +
1765 countMCSymbolRefExpr(BExpr->getRHS());
1767 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1768 return countMCSymbolRefExpr(UExpr->getSubExpr());
1773 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1775 const MCSubtargetInfo *STI) {
1776 MipsTargetStreamer &TOut = getTargetStreamer();
1777 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1778 bool ExpandedJalSym = false;
1782 if (MCID.isBranch() || MCID.isCall()) {
1783 const unsigned Opcode = Inst.getOpcode();
1793 assert(hasCnMips() && "instruction only valid for octeon cpus");
1800 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1801 Offset = Inst.getOperand(2);
1802 if (!Offset.isImm())
1803 break; // We'll deal with this situation later on when applying fixups.
1804 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1805 return Error(IDLoc, "branch target out of range");
1806 if (OffsetToAlignment(Offset.getImm(),
1807 1LL << (inMicroMipsMode() ? 1 : 2)))
1808 return Error(IDLoc, "branch to misaligned address");
1822 case Mips::BGEZAL_MM:
1823 case Mips::BLTZAL_MM:
1826 case Mips::BC1EQZC_MMR6:
1827 case Mips::BC1NEZC_MMR6:
1828 case Mips::BC2EQZC_MMR6:
1829 case Mips::BC2NEZC_MMR6:
1830 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1831 Offset = Inst.getOperand(1);
1832 if (!Offset.isImm())
1833 break; // We'll deal with this situation later on when applying fixups.
1834 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1835 return Error(IDLoc, "branch target out of range");
1836 if (OffsetToAlignment(Offset.getImm(),
1837 1LL << (inMicroMipsMode() ? 1 : 2)))
1838 return Error(IDLoc, "branch to misaligned address");
1840 case Mips::BGEC: case Mips::BGEC_MMR6:
1841 case Mips::BLTC: case Mips::BLTC_MMR6:
1842 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1843 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1844 case Mips::BEQC: case Mips::BEQC_MMR6:
1845 case Mips::BNEC: case Mips::BNEC_MMR6:
1846 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1847 Offset = Inst.getOperand(2);
1848 if (!Offset.isImm())
1849 break; // We'll deal with this situation later on when applying fixups.
1850 if (!isIntN(18, Offset.getImm()))
1851 return Error(IDLoc, "branch target out of range");
1852 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1853 return Error(IDLoc, "branch to misaligned address");
1855 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1856 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1857 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1858 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1859 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1860 Offset = Inst.getOperand(1);
1861 if (!Offset.isImm())
1862 break; // We'll deal with this situation later on when applying fixups.
1863 if (!isIntN(18, Offset.getImm()))
1864 return Error(IDLoc, "branch target out of range");
1865 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1866 return Error(IDLoc, "branch to misaligned address");
1868 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1869 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1870 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1871 Offset = Inst.getOperand(1);
1872 if (!Offset.isImm())
1873 break; // We'll deal with this situation later on when applying fixups.
1874 if (!isIntN(23, Offset.getImm()))
1875 return Error(IDLoc, "branch target out of range");
1876 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1877 return Error(IDLoc, "branch to misaligned address");
1879 case Mips::BEQZ16_MM:
1880 case Mips::BEQZC16_MMR6:
1881 case Mips::BNEZ16_MM:
1882 case Mips::BNEZC16_MMR6:
1883 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1884 Offset = Inst.getOperand(1);
1885 if (!Offset.isImm())
1886 break; // We'll deal with this situation later on when applying fixups.
1887 if (!isInt<8>(Offset.getImm()))
1888 return Error(IDLoc, "branch target out of range");
1889 if (OffsetToAlignment(Offset.getImm(), 2LL))
1890 return Error(IDLoc, "branch to misaligned address");
1895 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1896 // We still accept it but it is a normal nop.
1897 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1898 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1899 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1904 const unsigned Opcode = Inst.getOpcode();
1916 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1917 // The offset is handled above
1918 Opnd = Inst.getOperand(1);
1920 return Error(IDLoc, "expected immediate operand kind");
1921 Imm = Opnd.getImm();
1922 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1923 Opcode == Mips::BBIT1 ? 63 : 31))
1924 return Error(IDLoc, "immediate operand value out of range");
1926 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1928 Inst.getOperand(1).setImm(Imm - 32);
1934 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1935 Opnd = Inst.getOperand(2);
1937 return Error(IDLoc, "expected immediate operand kind");
1938 Imm = Opnd.getImm();
1939 if (!isInt<10>(Imm))
1940 return Error(IDLoc, "immediate operand value out of range");
1945 // Warn on division by zero. We're checking here as all instructions get
1946 // processed here, not just the macros that need expansion.
1948 // The MIPS backend models most of the divison instructions and macros as
1949 // three operand instructions. The pre-R6 divide instructions however have
1950 // two operands and explicitly define HI/LO as part of the instruction,
1951 // not in the operands.
1952 unsigned FirstOp = 1;
1953 unsigned SecondOp = 2;
1954 switch (Inst.getOpcode()) {
1957 case Mips::SDivIMacro:
1958 case Mips::UDivIMacro:
1959 case Mips::DSDivIMacro:
1960 case Mips::DUDivIMacro:
1961 if (Inst.getOperand(2).getImm() == 0) {
1962 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1963 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1964 Warning(IDLoc, "dividing zero by zero");
1966 Warning(IDLoc, "division by zero");
1978 case Mips::SDivMacro:
1979 case Mips::DSDivMacro:
1980 case Mips::UDivMacro:
1981 case Mips::DUDivMacro:
1986 case Mips::DIVU_MMR6:
1987 case Mips::DDIVU_MM64R6:
1988 case Mips::DIV_MMR6:
1989 case Mips::DDIV_MM64R6:
1990 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1991 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1992 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1993 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1994 Warning(IDLoc, "dividing zero by zero");
1996 Warning(IDLoc, "division by zero");
2001 // For PIC code convert unconditional jump to unconditional branch.
2002 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2005 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2006 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2007 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2008 BInst.addOperand(Inst.getOperand(0));
2012 // This expansion is not in a function called by tryExpandInstruction()
2013 // because the pseudo-instruction doesn't have a distinct opcode.
2014 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2016 warnIfNoMacro(IDLoc);
2018 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2020 // We can do this expansion if there's only 1 symbol in the argument
2022 if (countMCSymbolRefExpr(JalExpr) > 1)
2023 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2025 // FIXME: This is checking the expression can be handled by the later stages
2026 // of the assembler. We ought to leave it to those later stages.
2027 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2029 // FIXME: Add support for label+offset operands (currently causes an error).
2030 // FIXME: Add support for forward-declared local symbols.
2031 // FIXME: Add expansion for when the LargeGOT option is enabled.
2032 if (JalSym->isInSection() || JalSym->isTemporary() ||
2033 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2035 // If it's a local symbol and the O32 ABI is being used, we expand to:
2037 // R_(MICRO)MIPS_GOT16 label
2038 // addiu $25, $25, 0
2039 // R_(MICRO)MIPS_LO16 label
2041 const MCExpr *Got16RelocExpr =
2042 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2043 const MCExpr *Lo16RelocExpr =
2044 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2046 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2047 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2048 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2049 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2050 } else if (isABI_N32() || isABI_N64()) {
2051 // If it's a local symbol and the N32/N64 ABIs are being used,
2053 // lw/ld $25, 0($gp)
2054 // R_(MICRO)MIPS_GOT_DISP label
2056 const MCExpr *GotDispRelocExpr =
2057 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2059 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2060 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2064 // If it's an external/weak symbol, we expand to:
2065 // lw/ld $25, 0($gp)
2066 // R_(MICRO)MIPS_CALL16 label
2068 const MCExpr *Call16RelocExpr =
2069 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2071 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2072 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2076 if (IsCpRestoreSet && inMicroMipsMode())
2077 JalrInst.setOpcode(Mips::JALRS_MM);
2079 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2080 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2081 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2083 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
2084 // This relocation is supposed to be an optimization hint for the linker
2085 // and is not necessary for correctness.
2088 ExpandedJalSym = true;
2091 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2092 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2093 // Check the offset of memory operand, if it is a symbol
2094 // reference or immediate we may have to expand instructions.
2095 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2096 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2097 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2098 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2099 MCOperand &Op = Inst.getOperand(i);
2101 int MemOffset = Op.getImm();
2102 if (MemOffset < -32768 || MemOffset > 32767) {
2103 // Offset can't exceed 16bit value.
2104 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
2105 return getParser().hasPendingError();
2107 } else if (Op.isExpr()) {
2108 const MCExpr *Expr = Op.getExpr();
2109 if (Expr->getKind() == MCExpr::SymbolRef) {
2110 const MCSymbolRefExpr *SR =
2111 static_cast<const MCSymbolRefExpr *>(Expr);
2112 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2114 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2115 return getParser().hasPendingError();
2117 } else if (!isEvaluated(Expr)) {
2118 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2119 return getParser().hasPendingError();
2126 if (inMicroMipsMode()) {
2127 if (MCID.mayLoad()) {
2128 // Try to create 16-bit GP relative load instruction.
2129 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2130 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2131 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2132 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2133 MCOperand &Op = Inst.getOperand(i);
2135 int MemOffset = Op.getImm();
2136 MCOperand &DstReg = Inst.getOperand(0);
2137 MCOperand &BaseReg = Inst.getOperand(1);
2138 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2139 getContext().getRegisterInfo()->getRegClass(
2140 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2141 (BaseReg.getReg() == Mips::GP ||
2142 BaseReg.getReg() == Mips::GP_64)) {
2144 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2153 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2158 switch (Inst.getOpcode()) {
2161 case Mips::ADDIUSP_MM:
2162 Opnd = Inst.getOperand(0);
2164 return Error(IDLoc, "expected immediate operand kind");
2165 Imm = Opnd.getImm();
2166 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2168 return Error(IDLoc, "immediate operand value out of range");
2170 case Mips::SLL16_MM:
2171 case Mips::SRL16_MM:
2172 Opnd = Inst.getOperand(2);
2174 return Error(IDLoc, "expected immediate operand kind");
2175 Imm = Opnd.getImm();
2176 if (Imm < 1 || Imm > 8)
2177 return Error(IDLoc, "immediate operand value out of range");
2180 Opnd = Inst.getOperand(1);
2182 return Error(IDLoc, "expected immediate operand kind");
2183 Imm = Opnd.getImm();
2184 if (Imm < -1 || Imm > 126)
2185 return Error(IDLoc, "immediate operand value out of range");
2187 case Mips::ADDIUR2_MM:
2188 Opnd = Inst.getOperand(2);
2190 return Error(IDLoc, "expected immediate operand kind");
2191 Imm = Opnd.getImm();
2192 if (!(Imm == 1 || Imm == -1 ||
2193 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2194 return Error(IDLoc, "immediate operand value out of range");
2196 case Mips::ANDI16_MM:
2197 Opnd = Inst.getOperand(2);
2199 return Error(IDLoc, "expected immediate operand kind");
2200 Imm = Opnd.getImm();
2201 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2202 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2203 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2204 return Error(IDLoc, "immediate operand value out of range");
2206 case Mips::LBU16_MM:
2207 Opnd = Inst.getOperand(2);
2209 return Error(IDLoc, "expected immediate operand kind");
2210 Imm = Opnd.getImm();
2211 if (Imm < -1 || Imm > 14)
2212 return Error(IDLoc, "immediate operand value out of range");
2215 case Mips::SB16_MMR6:
2216 Opnd = Inst.getOperand(2);
2218 return Error(IDLoc, "expected immediate operand kind");
2219 Imm = Opnd.getImm();
2220 if (Imm < 0 || Imm > 15)
2221 return Error(IDLoc, "immediate operand value out of range");
2223 case Mips::LHU16_MM:
2225 case Mips::SH16_MMR6:
2226 Opnd = Inst.getOperand(2);
2228 return Error(IDLoc, "expected immediate operand kind");
2229 Imm = Opnd.getImm();
2230 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2231 return Error(IDLoc, "immediate operand value out of range");
2235 case Mips::SW16_MMR6:
2236 Opnd = Inst.getOperand(2);
2238 return Error(IDLoc, "expected immediate operand kind");
2239 Imm = Opnd.getImm();
2240 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2241 return Error(IDLoc, "immediate operand value out of range");
2243 case Mips::ADDIUPC_MM:
2244 MCOperand Opnd = Inst.getOperand(1);
2246 return Error(IDLoc, "expected immediate operand kind");
2247 int Imm = Opnd.getImm();
2248 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2249 return Error(IDLoc, "immediate operand value out of range");
2254 bool FillDelaySlot =
2255 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2257 TOut.emitDirectiveSetNoReorder();
2259 MacroExpanderResultTy ExpandResult =
2260 tryExpandInstruction(Inst, IDLoc, Out, STI);
2261 switch (ExpandResult) {
2263 Out.EmitInstruction(Inst, *STI);
2271 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2272 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2273 if (inMicroMipsMode())
2274 TOut.setUsesMicroMips();
2276 // If this instruction has a delay slot and .set reorder is active,
2277 // emit a NOP after it.
2278 if (FillDelaySlot) {
2279 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2280 TOut.emitDirectiveSetReorder();
2283 if ((Inst.getOpcode() == Mips::JalOneReg ||
2284 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2285 isPicAndNotNxxAbi()) {
2286 if (IsCpRestoreSet) {
2287 // We need a NOP between the JALR and the LW:
2288 // If .set reorder has been used, we've already emitted a NOP.
2289 // If .set noreorder has been used, we need to emit a NOP at this point.
2290 if (!AssemblerOptions.back()->isReorder())
2291 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2294 // Load the $gp from the stack.
2295 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2297 Warning(IDLoc, "no .cprestore used in PIC mode");
2303 MipsAsmParser::MacroExpanderResultTy
2304 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2305 const MCSubtargetInfo *STI) {
2306 switch (Inst.getOpcode()) {
2308 return MER_NotAMacro;
2309 case Mips::LoadImm32:
2310 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2311 case Mips::LoadImm64:
2312 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2313 case Mips::LoadAddrImm32:
2314 case Mips::LoadAddrImm64:
2315 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2316 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2317 "expected immediate operand kind");
2319 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2321 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2325 case Mips::LoadAddrReg32:
2326 case Mips::LoadAddrReg64:
2327 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2328 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2329 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2330 "expected immediate operand kind");
2332 return expandLoadAddress(Inst.getOperand(0).getReg(),
2333 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2334 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2338 case Mips::B_MM_Pseudo:
2339 case Mips::B_MMR6_Pseudo:
2340 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2344 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2346 case Mips::JalOneReg:
2347 case Mips::JalTwoReg:
2348 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2351 case Mips::BEQLImmMacro:
2352 case Mips::BNELImmMacro:
2353 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2370 case Mips::BLTImmMacro:
2371 case Mips::BLEImmMacro:
2372 case Mips::BGEImmMacro:
2373 case Mips::BGTImmMacro:
2374 case Mips::BLTUImmMacro:
2375 case Mips::BLEUImmMacro:
2376 case Mips::BGEUImmMacro:
2377 case Mips::BGTUImmMacro:
2378 case Mips::BLTLImmMacro:
2379 case Mips::BLELImmMacro:
2380 case Mips::BGELImmMacro:
2381 case Mips::BGTLImmMacro:
2382 case Mips::BLTULImmMacro:
2383 case Mips::BLEULImmMacro:
2384 case Mips::BGEULImmMacro:
2385 case Mips::BGTULImmMacro:
2386 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2387 case Mips::SDivMacro:
2388 case Mips::SDivIMacro:
2389 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2391 case Mips::DSDivMacro:
2392 case Mips::DSDivIMacro:
2393 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2395 case Mips::UDivMacro:
2396 case Mips::UDivIMacro:
2397 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2399 case Mips::DUDivMacro:
2400 case Mips::DUDivIMacro:
2401 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2403 case Mips::PseudoTRUNC_W_S:
2404 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2406 case Mips::PseudoTRUNC_W_D32:
2407 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2409 case Mips::PseudoTRUNC_W_D:
2410 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2413 case Mips::LoadImmSingleGPR:
2414 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2417 case Mips::LoadImmSingleFGR:
2418 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2421 case Mips::LoadImmDoubleGPR:
2422 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2425 case Mips::LoadImmDoubleFGR:
2426 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2429 case Mips::LoadImmDoubleFGR_32:
2430 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2434 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2436 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2438 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2441 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2443 case Mips::NORImm64:
2444 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2445 case Mips::SLTImm64:
2446 if (isInt<16>(Inst.getOperand(2).getImm())) {
2447 Inst.setOpcode(Mips::SLTi64);
2448 return MER_NotAMacro;
2450 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2451 case Mips::SLTUImm64:
2452 if (isInt<16>(Inst.getOperand(2).getImm())) {
2453 Inst.setOpcode(Mips::SLTiu64);
2454 return MER_NotAMacro;
2456 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2457 case Mips::ADDi: case Mips::ADDi_MM:
2458 case Mips::ADDiu: case Mips::ADDiu_MM:
2459 case Mips::SLTi: case Mips::SLTi_MM:
2460 case Mips::SLTiu: case Mips::SLTiu_MM:
2461 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2462 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2463 int64_t ImmValue = Inst.getOperand(2).getImm();
2464 if (isInt<16>(ImmValue))
2465 return MER_NotAMacro;
2466 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2469 return MER_NotAMacro;
2470 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2471 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2472 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2473 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2474 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2475 int64_t ImmValue = Inst.getOperand(2).getImm();
2476 if (isUInt<16>(ImmValue))
2477 return MER_NotAMacro;
2478 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2481 return MER_NotAMacro;
2484 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2487 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2494 case Mips::ABSMacro:
2495 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2496 case Mips::MULImmMacro:
2497 case Mips::DMULImmMacro:
2498 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2499 case Mips::MULOMacro:
2500 case Mips::DMULOMacro:
2501 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2502 case Mips::MULOUMacro:
2503 case Mips::DMULOUMacro:
2504 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2505 case Mips::DMULMacro:
2506 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2509 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2510 Inst.getOpcode() == Mips::LDMacro)
2513 case Mips::SEQMacro:
2514 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2515 case Mips::SEQIMacro:
2516 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2517 case Mips::MFTC0: case Mips::MTTC0:
2518 case Mips::MFTGPR: case Mips::MTTGPR:
2519 case Mips::MFTLO: case Mips::MTTLO:
2520 case Mips::MFTHI: case Mips::MTTHI:
2521 case Mips::MFTACX: case Mips::MTTACX:
2522 case Mips::MFTDSP: case Mips::MTTDSP:
2523 case Mips::MFTC1: case Mips::MTTC1:
2524 case Mips::MFTHC1: case Mips::MTTHC1:
2525 case Mips::CFTC1: case Mips::CTTC1:
2526 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2530 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2532 const MCSubtargetInfo *STI) {
2533 MipsTargetStreamer &TOut = getTargetStreamer();
2535 // Create a JALR instruction which is going to replace the pseudo-JAL.
2537 JalrInst.setLoc(IDLoc);
2538 const MCOperand FirstRegOp = Inst.getOperand(0);
2539 const unsigned Opcode = Inst.getOpcode();
2541 if (Opcode == Mips::JalOneReg) {
2542 // jal $rs => jalr $rs
2543 if (IsCpRestoreSet && inMicroMipsMode()) {
2544 JalrInst.setOpcode(Mips::JALRS16_MM);
2545 JalrInst.addOperand(FirstRegOp);
2546 } else if (inMicroMipsMode()) {
2547 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2548 JalrInst.addOperand(FirstRegOp);
2550 JalrInst.setOpcode(Mips::JALR);
2551 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2552 JalrInst.addOperand(FirstRegOp);
2554 } else if (Opcode == Mips::JalTwoReg) {
2555 // jal $rd, $rs => jalr $rd, $rs
2556 if (IsCpRestoreSet && inMicroMipsMode())
2557 JalrInst.setOpcode(Mips::JALRS_MM);
2559 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2560 JalrInst.addOperand(FirstRegOp);
2561 const MCOperand SecondRegOp = Inst.getOperand(1);
2562 JalrInst.addOperand(SecondRegOp);
2564 Out.EmitInstruction(JalrInst, *STI);
2566 // If .set reorder is active and branch instruction has a delay slot,
2567 // emit a NOP after it.
2568 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2569 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2570 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2576 /// Can the value be represented by a unsigned N-bit value and a shift left?
2577 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2578 unsigned BitNum = findFirstSet(x);
2580 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2583 /// Load (or add) an immediate into a register.
2585 /// @param ImmValue The immediate to load.
2586 /// @param DstReg The register that will hold the immediate.
2587 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2588 /// for a simple initialization.
2589 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2590 /// @param IsAddress True if the immediate represents an address. False if it
2592 /// @param IDLoc Location of the immediate in the source file.
2593 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2594 unsigned SrcReg, bool Is32BitImm,
2595 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2596 const MCSubtargetInfo *STI) {
2597 MipsTargetStreamer &TOut = getTargetStreamer();
2599 if (!Is32BitImm && !isGP64bit()) {
2600 Error(IDLoc, "instruction requires a 64-bit architecture");
2605 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2606 // Sign extend up to 64-bit so that the predicates match the hardware
2607 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2609 ImmValue = SignExtend64<32>(ImmValue);
2611 Error(IDLoc, "instruction requires a 32-bit immediate");
2616 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2617 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2619 bool UseSrcReg = false;
2620 if (SrcReg != Mips::NoRegister)
2623 unsigned TmpReg = DstReg;
2625 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2626 // At this point we need AT to perform the expansions and we exit if it is
2628 unsigned ATReg = getATReg(IDLoc);
2634 if (isInt<16>(ImmValue)) {
2638 // This doesn't quite follow the usual ABI expectations for N32 but matches
2639 // traditional assembler behaviour. N32 would normally use addiu for both
2640 // integers and addresses.
2641 if (IsAddress && !Is32BitImm) {
2642 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2646 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2650 if (isUInt<16>(ImmValue)) {
2651 unsigned TmpReg = DstReg;
2652 if (SrcReg == DstReg) {
2653 TmpReg = getATReg(IDLoc);
2658 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2660 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2664 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2665 warnIfNoMacro(IDLoc);
2667 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2668 uint16_t Bits15To0 = ImmValue & 0xffff;
2669 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2670 // Traditional behaviour seems to special case this particular value. It's
2671 // not clear why other masks are handled differently.
2672 if (ImmValue == 0xffffffff) {
2673 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2674 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2676 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2680 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2682 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2683 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2685 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2687 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2691 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2693 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2695 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2699 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2701 Error(IDLoc, "instruction requires a 32-bit immediate");
2705 // Traditionally, these immediates are shifted as little as possible and as
2706 // such we align the most significant bit to bit 15 of our temporary.
2707 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2708 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2709 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2710 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2711 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2712 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2715 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2720 warnIfNoMacro(IDLoc);
2722 // The remaining case is packed with a sequence of dsll and ori with zeros
2723 // being omitted and any neighbouring dsll's being coalesced.
2724 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2726 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2727 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2731 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2732 // skip it and defer the shift to the next chunk.
2733 unsigned ShiftCarriedForwards = 16;
2734 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2735 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2737 if (ImmChunk != 0) {
2738 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2739 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2740 ShiftCarriedForwards = 0;
2743 ShiftCarriedForwards += 16;
2745 ShiftCarriedForwards -= 16;
2747 // Finish any remaining shifts left by trailing zeros.
2748 if (ShiftCarriedForwards)
2749 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2752 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2757 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2758 MCStreamer &Out, const MCSubtargetInfo *STI) {
2759 const MCOperand &ImmOp = Inst.getOperand(1);
2760 assert(ImmOp.isImm() && "expected immediate operand kind");
2761 const MCOperand &DstRegOp = Inst.getOperand(0);
2762 assert(DstRegOp.isReg() && "expected register operand kind");
2764 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2765 Is32BitImm, false, IDLoc, Out, STI))
2771 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2772 const MCOperand &Offset,
2773 bool Is32BitAddress, SMLoc IDLoc,
2775 const MCSubtargetInfo *STI) {
2776 // la can't produce a usable address when addresses are 64-bit.
2777 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2778 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2779 // We currently can't do this because we depend on the equality
2780 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2781 Error(IDLoc, "la used to load 64-bit address");
2782 // Continue as if we had 'dla' instead.
2783 Is32BitAddress = false;
2787 // dla requires 64-bit addresses.
2788 if (!Is32BitAddress && !hasMips3()) {
2789 Error(IDLoc, "instruction requires a 64-bit architecture");
2793 if (!Offset.isImm())
2794 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2795 Is32BitAddress, IDLoc, Out, STI);
2797 if (!ABI.ArePtrs64bit()) {
2798 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2799 Is32BitAddress = true;
2802 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2806 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2807 unsigned DstReg, unsigned SrcReg,
2808 bool Is32BitSym, SMLoc IDLoc,
2810 const MCSubtargetInfo *STI) {
2811 // FIXME: These expansions do not respect -mxgot.
2812 MipsTargetStreamer &TOut = getTargetStreamer();
2813 bool UseSrcReg = SrcReg != Mips::NoRegister;
2814 warnIfNoMacro(IDLoc);
2816 if (inPicMode() && ABI.IsO32()) {
2818 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2819 Error(IDLoc, "expected relocatable expression");
2822 if (Res.getSymB() != nullptr) {
2823 Error(IDLoc, "expected relocatable expression with only one symbol");
2827 // The case where the result register is $25 is somewhat special. If the
2828 // symbol in the final relocation is external and not modified with a
2829 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2830 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2831 Res.getConstant() == 0 &&
2832 !(Res.getSymA()->getSymbol().isInSection() ||
2833 Res.getSymA()->getSymbol().isTemporary() ||
2834 (Res.getSymA()->getSymbol().isELF() &&
2835 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2837 const MCExpr *CallExpr =
2838 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2839 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2840 MCOperand::createExpr(CallExpr), IDLoc, STI);
2844 // The remaining cases are:
2845 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2846 // >addiu $tmp, $tmp, %lo(offset)
2847 // >addiu $rd, $tmp, $rs
2848 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2849 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2850 // >addiu $rd, $tmp, $rs
2851 // The addiu's marked with a '>' may be omitted if they are redundant. If
2852 // this happens then the last instruction must use $rd as the result
2854 const MipsMCExpr *GotExpr =
2855 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2856 const MCExpr *LoExpr = nullptr;
2857 if (Res.getSymA()->getSymbol().isInSection() ||
2858 Res.getSymA()->getSymbol().isTemporary())
2859 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2860 else if (Res.getConstant() != 0) {
2861 // External symbols fully resolve the symbol with just the %got(symbol)
2862 // but we must still account for any offset to the symbol for expressions
2864 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2867 unsigned TmpReg = DstReg;
2869 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2871 // If $rs is the same as $rd, we need to use AT.
2872 // If it is not available we exit.
2873 unsigned ATReg = getATReg(IDLoc);
2879 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2880 MCOperand::createExpr(GotExpr), IDLoc, STI);
2883 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2887 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2892 if (inPicMode() && ABI.ArePtrs64bit()) {
2894 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2895 Error(IDLoc, "expected relocatable expression");
2898 if (Res.getSymB() != nullptr) {
2899 Error(IDLoc, "expected relocatable expression with only one symbol");
2903 // The case where the result register is $25 is somewhat special. If the
2904 // symbol in the final relocation is external and not modified with a
2905 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2906 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2907 Res.getConstant() == 0 &&
2908 !(Res.getSymA()->getSymbol().isInSection() ||
2909 Res.getSymA()->getSymbol().isTemporary() ||
2910 (Res.getSymA()->getSymbol().isELF() &&
2911 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2913 const MCExpr *CallExpr =
2914 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2915 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2916 MCOperand::createExpr(CallExpr), IDLoc, STI);
2920 // The remaining cases are:
2921 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2922 // >daddiu $tmp, $tmp, offset
2923 // >daddu $rd, $tmp, $rs
2924 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2925 // this happens then the last instruction must use $rd as the result
2927 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2930 const MCExpr *LoExpr = nullptr;
2931 if (Res.getConstant() != 0) {
2932 // Symbols fully resolve with just the %got_disp(symbol) but we
2933 // must still account for any offset to the symbol for
2934 // expressions like symbol+8.
2935 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2937 // FIXME: Offsets greater than 16 bits are not yet implemented.
2938 // FIXME: The correct range is a 32-bit sign-extended number.
2939 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2940 Error(IDLoc, "macro instruction uses large offset, which is not "
2941 "currently supported");
2946 unsigned TmpReg = DstReg;
2948 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2950 // If $rs is the same as $rd, we need to use AT.
2951 // If it is not available we exit.
2952 unsigned ATReg = getATReg(IDLoc);
2958 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
2959 MCOperand::createExpr(GotExpr), IDLoc, STI);
2962 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2966 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2971 const MipsMCExpr *HiExpr =
2972 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2973 const MipsMCExpr *LoExpr =
2974 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2976 // This is the 64-bit symbol address expansion.
2977 if (ABI.ArePtrs64bit() && isGP64bit()) {
2978 // We need AT for the 64-bit expansion in the cases where the optional
2979 // source register is the destination register and for the superscalar
2982 // If it is not available we exit if the destination is the same as the
2985 const MipsMCExpr *HighestExpr =
2986 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2987 const MipsMCExpr *HigherExpr =
2988 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2991 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
2993 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
2994 unsigned ATReg = getATReg(IDLoc);
2996 // If $rs is the same as $rd:
2997 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2998 // daddiu $at, $at, %higher(sym)
2999 // dsll $at, $at, 16
3000 // daddiu $at, $at, %hi(sym)
3001 // dsll $at, $at, 16
3002 // daddiu $at, $at, %lo(sym)
3003 // daddu $rd, $at, $rd
3004 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3006 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3007 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3008 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3009 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3011 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3012 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3014 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3017 } else if (canUseATReg() && !RdRegIsRsReg) {
3018 unsigned ATReg = getATReg(IDLoc);
3020 // If the $rs is different from $rd or if $rs isn't specified and we
3021 // have $at available:
3022 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3023 // lui $at, %hi(sym)
3024 // daddiu $rd, $rd, %higher(sym)
3025 // daddiu $at, $at, %lo(sym)
3026 // dsll32 $rd, $rd, 0
3027 // daddu $rd, $rd, $at
3028 // (daddu $rd, $rd, $rs)
3030 // Which is preferred for superscalar issue.
3031 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3033 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3034 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3035 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3036 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3038 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3039 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3041 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3044 } else if (!canUseATReg() && !RdRegIsRsReg) {
3045 // Otherwise, synthesize the address in the destination register
3047 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3048 // daddiu $rd, $rd, %higher(sym)
3049 // dsll $rd, $rd, 16
3050 // daddiu $rd, $rd, %hi(sym)
3051 // dsll $rd, $rd, 16
3052 // daddiu $rd, $rd, %lo(sym)
3053 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3055 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3056 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3057 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3058 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3059 MCOperand::createExpr(HiExpr), IDLoc, STI);
3060 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3061 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3062 MCOperand::createExpr(LoExpr), IDLoc, STI);
3064 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3068 // We have a case where SrcReg == DstReg and we don't have $at
3069 // available. We can't expand this case, so error out appropriately.
3070 assert(SrcReg == DstReg && !canUseATReg() &&
3071 "Could have expanded dla but didn't?");
3072 reportParseError(IDLoc,
3073 "pseudo-instruction requires $at, which is not available");
3078 // And now, the 32-bit symbol address expansion:
3079 // If $rs is the same as $rd:
3080 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3081 // ori $at, $at, %lo(sym)
3082 // addu $rd, $at, $rd
3083 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3084 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3085 // ori $rd, $rd, %lo(sym)
3086 // (addu $rd, $rd, $rs)
3087 unsigned TmpReg = DstReg;
3089 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3090 // If $rs is the same as $rd, we need to use AT.
3091 // If it is not available we exit.
3092 unsigned ATReg = getATReg(IDLoc);
3098 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3099 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3103 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3106 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3111 // Each double-precision register DO-D15 overlaps with two of the single
3112 // precision registers F0-F31. As an example, all of the following hold true:
3113 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3114 static unsigned nextReg(unsigned Reg) {
3115 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3116 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3118 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3119 case Mips::ZERO: return Mips::AT;
3120 case Mips::AT: return Mips::V0;
3121 case Mips::V0: return Mips::V1;
3122 case Mips::V1: return Mips::A0;
3123 case Mips::A0: return Mips::A1;
3124 case Mips::A1: return Mips::A2;
3125 case Mips::A2: return Mips::A3;
3126 case Mips::A3: return Mips::T0;
3127 case Mips::T0: return Mips::T1;
3128 case Mips::T1: return Mips::T2;
3129 case Mips::T2: return Mips::T3;
3130 case Mips::T3: return Mips::T4;
3131 case Mips::T4: return Mips::T5;
3132 case Mips::T5: return Mips::T6;
3133 case Mips::T6: return Mips::T7;
3134 case Mips::T7: return Mips::S0;
3135 case Mips::S0: return Mips::S1;
3136 case Mips::S1: return Mips::S2;
3137 case Mips::S2: return Mips::S3;
3138 case Mips::S3: return Mips::S4;
3139 case Mips::S4: return Mips::S5;
3140 case Mips::S5: return Mips::S6;
3141 case Mips::S6: return Mips::S7;
3142 case Mips::S7: return Mips::T8;
3143 case Mips::T8: return Mips::T9;
3144 case Mips::T9: return Mips::K0;
3145 case Mips::K0: return Mips::K1;
3146 case Mips::K1: return Mips::GP;
3147 case Mips::GP: return Mips::SP;
3148 case Mips::SP: return Mips::FP;
3149 case Mips::FP: return Mips::RA;
3150 case Mips::RA: return Mips::ZERO;
3151 case Mips::D0: return Mips::F1;
3152 case Mips::D1: return Mips::F3;
3153 case Mips::D2: return Mips::F5;
3154 case Mips::D3: return Mips::F7;
3155 case Mips::D4: return Mips::F9;
3156 case Mips::D5: return Mips::F11;
3157 case Mips::D6: return Mips::F13;
3158 case Mips::D7: return Mips::F15;
3159 case Mips::D8: return Mips::F17;
3160 case Mips::D9: return Mips::F19;
3161 case Mips::D10: return Mips::F21;
3162 case Mips::D11: return Mips::F23;
3163 case Mips::D12: return Mips::F25;
3164 case Mips::D13: return Mips::F27;
3165 case Mips::D14: return Mips::F29;
3166 case Mips::D15: return Mips::F31;
3170 // FIXME: This method is too general. In principle we should compute the number
3171 // of instructions required to synthesize the immediate inline compared to
3172 // synthesizing the address inline and relying on non .text sections.
3173 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3174 // likely to yield a much larger benefit as we have to synthesize a 64bit
3175 // address to load a 64 bit value.
3176 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3178 unsigned ATReg = getATReg(IDLoc);
3183 const MCExpr *GotSym =
3184 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3185 const MipsMCExpr *GotExpr =
3186 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3188 if(isABI_O32() || isABI_N32()) {
3189 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3191 } else { //isABI_N64()
3192 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3195 } else { //!IsPicEnabled
3196 const MCExpr *HiSym =
3197 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3198 const MipsMCExpr *HiExpr =
3199 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3201 // FIXME: This is technically correct but gives a different result to gas,
3202 // but gas is incomplete there (it has a fixme noting it doesn't work with
3203 // 64-bit addresses).
3204 // FIXME: With -msym32 option, the address expansion for N64 should probably
3205 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3206 // symbol's value is considered sign extended.
3207 if(isABI_O32() || isABI_N32()) {
3208 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3209 } else { //isABI_N64()
3210 const MCExpr *HighestSym =
3211 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3212 const MipsMCExpr *HighestExpr =
3213 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3214 const MCExpr *HigherSym =
3215 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3216 const MipsMCExpr *HigherExpr =
3217 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3219 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3221 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3222 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3223 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3224 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3226 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3232 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3233 bool Is64FPU, SMLoc IDLoc,
3235 const MCSubtargetInfo *STI) {
3236 MipsTargetStreamer &TOut = getTargetStreamer();
3237 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3238 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3239 "Invalid instruction operand.");
3241 unsigned FirstReg = Inst.getOperand(0).getReg();
3242 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3244 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3245 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3246 // exponent field), convert it to double (e.g. 1 to 1.0)
3247 if ((HiImmOp64 & 0x7ff00000) == 0) {
3248 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3249 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3252 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3253 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3256 // Conversion of a double in an uint64_t to a float in a uint32_t,
3257 // retaining the bit pattern of a float.
3259 double doubleImm = BitsToDouble(ImmOp64);
3260 float tmp_float = static_cast<float>(doubleImm);
3261 ImmOp32 = FloatToBits(tmp_float);
3264 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3269 unsigned ATReg = getATReg(IDLoc);
3272 if (LoImmOp64 == 0) {
3273 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3276 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3280 MCSection *CS = getStreamer().getCurrentSectionOnly();
3281 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3282 // where appropriate.
3283 MCSection *ReadOnlySection = getContext().getELFSection(
3284 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3286 MCSymbol *Sym = getContext().createTempSymbol();
3287 const MCExpr *LoSym =
3288 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3289 const MipsMCExpr *LoExpr =
3290 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3292 getStreamer().SwitchSection(ReadOnlySection);
3293 getStreamer().EmitLabel(Sym, IDLoc);
3294 getStreamer().EmitIntValue(ImmOp32, 4);
3295 getStreamer().SwitchSection(CS);
3297 if(emitPartialAddress(TOut, IDLoc, Sym))
3299 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3300 MCOperand::createExpr(LoExpr), IDLoc, STI);
3306 unsigned ATReg = getATReg(IDLoc);
3311 if (LoImmOp64 == 0) {
3312 if(isABI_N32() || isABI_N64()) {
3313 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3318 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3322 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3329 MCSection *CS = getStreamer().getCurrentSectionOnly();
3330 MCSection *ReadOnlySection = getContext().getELFSection(
3331 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3333 MCSymbol *Sym = getContext().createTempSymbol();
3334 const MCExpr *LoSym =
3335 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3336 const MipsMCExpr *LoExpr =
3337 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3339 getStreamer().SwitchSection(ReadOnlySection);
3340 getStreamer().EmitLabel(Sym, IDLoc);
3341 getStreamer().EmitIntValue(HiImmOp64, 4);
3342 getStreamer().EmitIntValue(LoImmOp64, 4);
3343 getStreamer().SwitchSection(CS);
3345 if(emitPartialAddress(TOut, IDLoc, Sym))
3348 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3349 MCOperand::createExpr(LoExpr), IDLoc, STI);
3351 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3352 MCOperand::createExpr(LoExpr), IDLoc, STI);
3354 if(isABI_N32() || isABI_N64())
3355 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3357 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3358 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3361 } else { // if(!IsGPR && !IsSingle)
3362 if ((LoImmOp64 == 0) &&
3363 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3364 // FIXME: In the case where the constant is zero, we can load the
3365 // register directly from the zero register.
3366 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3369 if (isABI_N32() || isABI_N64())
3370 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3371 else if (hasMips32r2()) {
3372 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3373 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3375 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3376 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3381 MCSection *CS = getStreamer().getCurrentSectionOnly();
3382 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3383 // where appropriate.
3384 MCSection *ReadOnlySection = getContext().getELFSection(
3385 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3387 MCSymbol *Sym = getContext().createTempSymbol();
3388 const MCExpr *LoSym =
3389 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3390 const MipsMCExpr *LoExpr =
3391 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3393 getStreamer().SwitchSection(ReadOnlySection);
3394 getStreamer().EmitLabel(Sym, IDLoc);
3395 getStreamer().EmitIntValue(HiImmOp64, 4);
3396 getStreamer().EmitIntValue(LoImmOp64, 4);
3397 getStreamer().SwitchSection(CS);
3399 if(emitPartialAddress(TOut, IDLoc, Sym))
3401 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3402 MCOperand::createExpr(LoExpr), IDLoc, STI);
3407 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3409 const MCSubtargetInfo *STI) {
3410 MipsTargetStreamer &TOut = getTargetStreamer();
3412 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3413 "unexpected number of operands");
3415 MCOperand Offset = Inst.getOperand(0);
3416 if (Offset.isExpr()) {
3418 Inst.setOpcode(Mips::BEQ_MM);
3419 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3420 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3421 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3423 assert(Offset.isImm() && "expected immediate operand kind");
3424 if (isInt<11>(Offset.getImm())) {
3425 // If offset fits into 11 bits then this instruction becomes microMIPS
3426 // 16-bit unconditional branch instruction.
3427 if (inMicroMipsMode())
3428 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3430 if (!isInt<17>(Offset.getImm()))
3431 return Error(IDLoc, "branch target out of range");
3432 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3433 return Error(IDLoc, "branch to misaligned address");
3435 Inst.setOpcode(Mips::BEQ_MM);
3436 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3437 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3438 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3441 Out.EmitInstruction(Inst, *STI);
3443 // If .set reorder is active and branch instruction has a delay slot,
3444 // emit a NOP after it.
3445 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3446 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3447 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3452 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3453 const MCSubtargetInfo *STI) {
3454 MipsTargetStreamer &TOut = getTargetStreamer();
3455 const MCOperand &DstRegOp = Inst.getOperand(0);
3456 assert(DstRegOp.isReg() && "expected register operand kind");
3458 const MCOperand &ImmOp = Inst.getOperand(1);
3459 assert(ImmOp.isImm() && "expected immediate operand kind");
3461 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3462 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3463 "expected immediate or expression operand");
3465 bool IsLikely = false;
3467 unsigned OpCode = 0;
3468 switch(Inst.getOpcode()) {
3475 case Mips::BEQLImmMacro:
3476 OpCode = Mips::BEQL;
3479 case Mips::BNELImmMacro:
3480 OpCode = Mips::BNEL;
3484 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3488 int64_t ImmValue = ImmOp.getImm();
3489 if (ImmValue == 0) {
3491 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3492 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3493 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3495 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3498 warnIfNoMacro(IDLoc);
3500 unsigned ATReg = getATReg(IDLoc);
3504 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3509 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3510 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3511 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3513 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3518 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3519 const MCSubtargetInfo *STI, bool IsLoad,
3522 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3525 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3528 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3529 const MCSubtargetInfo *STI, bool IsImmOpnd) {
3530 MipsTargetStreamer &TOut = getTargetStreamer();
3532 unsigned DstReg = Inst.getOperand(0).getReg();
3533 unsigned BaseReg = Inst.getOperand(1).getReg();
3535 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3536 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3537 unsigned DstRegClassID =
3538 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3539 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3540 (DstRegClassID == Mips::GPR64RegClassID);
3543 // Try to use DstReg as the temporary.
3544 if (IsGPR && (BaseReg != DstReg)) {
3545 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3546 Inst.getOperand(2).getImm(), DstReg, IDLoc,
3551 // At this point we need AT to perform the expansions and we exit if it is
3553 unsigned ATReg = getATReg(IDLoc);
3557 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3558 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
3562 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3563 MCOperand LoOperand = MCOperand::createExpr(
3564 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3565 MCOperand HiOperand = MCOperand::createExpr(
3566 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3568 // Try to use DstReg as the temporary.
3569 if (IsGPR && (BaseReg != DstReg)) {
3570 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3571 LoOperand, DstReg, IDLoc, STI);
3575 // At this point we need AT to perform the expansions and we exit if it is
3577 unsigned ATReg = getATReg(IDLoc);
3581 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3582 LoOperand, ATReg, IDLoc, STI);
3585 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3586 const MCSubtargetInfo *STI,
3588 MipsTargetStreamer &TOut = getTargetStreamer();
3590 unsigned SrcReg = Inst.getOperand(0).getReg();
3591 unsigned BaseReg = Inst.getOperand(1).getReg();
3594 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
3595 Inst.getOperand(2).getImm(),
3596 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
3600 unsigned ATReg = getATReg(IDLoc);
3604 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3605 MCOperand LoOperand = MCOperand::createExpr(
3606 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3607 MCOperand HiOperand = MCOperand::createExpr(
3608 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3609 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
3610 LoOperand, ATReg, IDLoc, STI);
3613 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3615 const MCSubtargetInfo *STI) {
3616 unsigned OpNum = Inst.getNumOperands();
3617 unsigned Opcode = Inst.getOpcode();
3618 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3620 assert(Inst.getOperand(OpNum - 1).isImm() &&
3621 Inst.getOperand(OpNum - 2).isReg() &&
3622 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3624 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3625 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3626 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3627 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3628 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3629 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3630 // It can be implemented as SWM16 or LWM16 instruction.
3631 if (inMicroMipsMode() && hasMips32r6())
3632 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3634 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3637 Inst.setOpcode(NewOpcode);
3638 Out.EmitInstruction(Inst, *STI);
3642 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3644 const MCSubtargetInfo *STI) {
3645 MipsTargetStreamer &TOut = getTargetStreamer();
3646 bool EmittedNoMacroWarning = false;
3647 unsigned PseudoOpcode = Inst.getOpcode();
3648 unsigned SrcReg = Inst.getOperand(0).getReg();
3649 const MCOperand &TrgOp = Inst.getOperand(1);
3650 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3652 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3653 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3657 TrgReg = TrgOp.getReg();
3658 else if (TrgOp.isImm()) {
3659 warnIfNoMacro(IDLoc);
3660 EmittedNoMacroWarning = true;
3662 TrgReg = getATReg(IDLoc);
3666 switch(PseudoOpcode) {
3668 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3669 case Mips::BLTImmMacro:
3670 PseudoOpcode = Mips::BLT;
3672 case Mips::BLEImmMacro:
3673 PseudoOpcode = Mips::BLE;
3675 case Mips::BGEImmMacro:
3676 PseudoOpcode = Mips::BGE;
3678 case Mips::BGTImmMacro:
3679 PseudoOpcode = Mips::BGT;
3681 case Mips::BLTUImmMacro:
3682 PseudoOpcode = Mips::BLTU;
3684 case Mips::BLEUImmMacro:
3685 PseudoOpcode = Mips::BLEU;
3687 case Mips::BGEUImmMacro:
3688 PseudoOpcode = Mips::BGEU;
3690 case Mips::BGTUImmMacro:
3691 PseudoOpcode = Mips::BGTU;
3693 case Mips::BLTLImmMacro:
3694 PseudoOpcode = Mips::BLTL;
3696 case Mips::BLELImmMacro:
3697 PseudoOpcode = Mips::BLEL;
3699 case Mips::BGELImmMacro:
3700 PseudoOpcode = Mips::BGEL;
3702 case Mips::BGTLImmMacro:
3703 PseudoOpcode = Mips::BGTL;
3705 case Mips::BLTULImmMacro:
3706 PseudoOpcode = Mips::BLTUL;
3708 case Mips::BLEULImmMacro:
3709 PseudoOpcode = Mips::BLEUL;
3711 case Mips::BGEULImmMacro:
3712 PseudoOpcode = Mips::BGEUL;
3714 case Mips::BGTULImmMacro:
3715 PseudoOpcode = Mips::BGTUL;
3719 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3720 false, IDLoc, Out, STI))
3724 switch (PseudoOpcode) {
3729 AcceptsEquality = false;
3730 ReverseOrderSLT = false;
3731 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3732 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3733 ZeroSrcOpcode = Mips::BGTZ;
3734 ZeroTrgOpcode = Mips::BLTZ;
3740 AcceptsEquality = true;
3741 ReverseOrderSLT = true;
3742 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3743 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3744 ZeroSrcOpcode = Mips::BGEZ;
3745 ZeroTrgOpcode = Mips::BLEZ;
3751 AcceptsEquality = true;
3752 ReverseOrderSLT = false;
3753 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3754 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3755 ZeroSrcOpcode = Mips::BLEZ;
3756 ZeroTrgOpcode = Mips::BGEZ;
3762 AcceptsEquality = false;
3763 ReverseOrderSLT = true;
3764 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3765 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3766 ZeroSrcOpcode = Mips::BLTZ;
3767 ZeroTrgOpcode = Mips::BGTZ;
3770 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3773 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3774 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3775 if (IsSrcRegZero && IsTrgRegZero) {
3776 // FIXME: All of these Opcode-specific if's are needed for compatibility
3777 // with GAS' behaviour. However, they may not generate the most efficient
3778 // code in some circumstances.
3779 if (PseudoOpcode == Mips::BLT) {
3780 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3784 if (PseudoOpcode == Mips::BLE) {
3785 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3787 Warning(IDLoc, "branch is always taken");
3790 if (PseudoOpcode == Mips::BGE) {
3791 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3793 Warning(IDLoc, "branch is always taken");
3796 if (PseudoOpcode == Mips::BGT) {
3797 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3801 if (PseudoOpcode == Mips::BGTU) {
3802 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3803 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3806 if (AcceptsEquality) {
3807 // If both registers are $0 and the pseudo-branch accepts equality, it
3808 // will always be taken, so we emit an unconditional branch.
3809 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3810 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3811 Warning(IDLoc, "branch is always taken");
3814 // If both registers are $0 and the pseudo-branch does not accept
3815 // equality, it will never be taken, so we don't have to emit anything.
3818 if (IsSrcRegZero || IsTrgRegZero) {
3819 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3820 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3821 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3822 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3823 // the pseudo-branch will never be taken, so we don't emit anything.
3824 // This only applies to unsigned pseudo-branches.
3827 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3828 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3829 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3830 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3831 // the pseudo-branch will always be taken, so we emit an unconditional
3833 // This only applies to unsigned pseudo-branches.
3834 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3835 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3836 Warning(IDLoc, "branch is always taken");
3840 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3841 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3842 // the pseudo-branch will be taken only when the non-zero register is
3843 // different from 0, so we emit a BNEZ.
3845 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3846 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3847 // the pseudo-branch will be taken only when the non-zero register is
3848 // equal to 0, so we emit a BEQZ.
3850 // Because only BLEU and BGEU branch on equality, we can use the
3851 // AcceptsEquality variable to decide when to emit the BEQZ.
3852 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3853 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3854 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3857 // If we have a signed pseudo-branch and one of the registers is $0,
3858 // we can use an appropriate compare-to-zero branch. We select which one
3859 // to use in the switch statement above.
3860 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3861 IsSrcRegZero ? TrgReg : SrcReg,
3862 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3866 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3867 // expansions. If it is not available, we return.
3868 unsigned ATRegNum = getATReg(IDLoc);
3872 if (!EmittedNoMacroWarning)
3873 warnIfNoMacro(IDLoc);
3875 // SLT fits well with 2 of our 4 pseudo-branches:
3876 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3877 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3878 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3879 // This is accomplished by using a BNEZ with the result of the SLT.
3881 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3882 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3883 // Because only BGE and BLE branch on equality, we can use the
3884 // AcceptsEquality variable to decide when to emit the BEQZ.
3885 // Note that the order of the SLT arguments doesn't change between
3888 // The same applies to the unsigned variants, except that SLTu is used
3890 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3891 ReverseOrderSLT ? TrgReg : SrcReg,
3892 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3894 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3895 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3896 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3901 // Expand a integer division macro.
3903 // Notably we don't have to emit a warning when encountering $rt as the $zero
3904 // register, or 0 as an immediate. processInstruction() has already done that.
3906 // The destination register can only be $zero when expanding (S)DivIMacro or
3909 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3910 const MCSubtargetInfo *STI, const bool IsMips64,
3911 const bool Signed) {
3912 MipsTargetStreamer &TOut = getTargetStreamer();
3914 warnIfNoMacro(IDLoc);
3916 const MCOperand &RdRegOp = Inst.getOperand(0);
3917 assert(RdRegOp.isReg() && "expected register operand kind");
3918 unsigned RdReg = RdRegOp.getReg();
3920 const MCOperand &RsRegOp = Inst.getOperand(1);
3921 assert(RsRegOp.isReg() && "expected register operand kind");
3922 unsigned RsReg = RsRegOp.getReg();
3927 const MCOperand &RtOp = Inst.getOperand(2);
3928 assert((RtOp.isReg() || RtOp.isImm()) &&
3929 "expected register or immediate operand kind");
3931 RtReg = RtOp.getReg();
3933 ImmValue = RtOp.getImm();
3940 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3941 ZeroReg = Mips::ZERO_64;
3944 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3945 ZeroReg = Mips::ZERO;
3949 bool UseTraps = useTraps();
3952 unsigned ATReg = getATReg(IDLoc);
3956 if (ImmValue == 0) {
3958 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3960 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3964 if (ImmValue == 1) {
3965 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3967 } else if (Signed && ImmValue == -1) {
3968 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3971 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
3972 false, Inst.getLoc(), Out, STI))
3974 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
3975 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3981 // If the macro expansion of (d)div(u) would always trap or break, insert
3982 // the trap/break and exit. This gives a different result to GAS. GAS has
3983 // an inconsistency/missed optimization in that not all cases are handled
3984 // equivalently. As the observed behaviour is the same, we're ok.
3985 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3987 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3990 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3994 // Temporary label for first branch traget
3995 MCContext &Context = TOut.getStreamer().getContext();
4000 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4002 // Branch to the li instruction.
4003 BrTarget = Context.createTempSymbol();
4004 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4005 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4008 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4011 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4015 TOut.getStreamer().EmitLabel(BrTarget);
4017 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4021 unsigned ATReg = getATReg(IDLoc);
4026 TOut.getStreamer().EmitLabel(BrTarget);
4028 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4030 // Temporary label for the second branch target.
4031 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4032 MCOperand LabelOpEnd =
4033 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4035 // Branch to the mflo instruction.
4036 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4039 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4040 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
4042 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4046 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4048 // Branch to the mflo instruction.
4049 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4050 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
4051 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4054 TOut.getStreamer().EmitLabel(BrTargetEnd);
4055 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4059 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4060 SMLoc IDLoc, MCStreamer &Out,
4061 const MCSubtargetInfo *STI) {
4062 MipsTargetStreamer &TOut = getTargetStreamer();
4064 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4065 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4066 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4068 unsigned FirstReg = Inst.getOperand(0).getReg();
4069 unsigned SecondReg = Inst.getOperand(1).getReg();
4070 unsigned ThirdReg = Inst.getOperand(2).getReg();
4072 if (hasMips1() && !hasMips2()) {
4073 unsigned ATReg = getATReg(IDLoc);
4076 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4077 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4078 TOut.emitNop(IDLoc, STI);
4079 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4080 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4081 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4082 TOut.emitNop(IDLoc, STI);
4083 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4085 FirstReg, SecondReg, IDLoc, STI);
4086 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4087 TOut.emitNop(IDLoc, STI);
4091 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4093 FirstReg, SecondReg, IDLoc, STI);
4098 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4099 MCStreamer &Out, const MCSubtargetInfo *STI) {
4100 if (hasMips32r6() || hasMips64r6()) {
4101 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4104 const MCOperand &DstRegOp = Inst.getOperand(0);
4105 assert(DstRegOp.isReg() && "expected register operand kind");
4106 const MCOperand &SrcRegOp = Inst.getOperand(1);
4107 assert(SrcRegOp.isReg() && "expected register operand kind");
4108 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4109 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4111 MipsTargetStreamer &TOut = getTargetStreamer();
4112 unsigned DstReg = DstRegOp.getReg();
4113 unsigned SrcReg = SrcRegOp.getReg();
4114 int64_t OffsetValue = OffsetImmOp.getImm();
4116 // NOTE: We always need AT for ULHU, as it is always used as the source
4117 // register for one of the LBu's.
4118 warnIfNoMacro(IDLoc);
4119 unsigned ATReg = getATReg(IDLoc);
4123 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4124 if (IsLargeOffset) {
4125 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4130 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4131 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4133 std::swap(FirstOffset, SecondOffset);
4135 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4136 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4138 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4139 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4141 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4142 FirstOffset, IDLoc, STI);
4143 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4144 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4145 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4150 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4151 const MCSubtargetInfo *STI) {
4152 if (hasMips32r6() || hasMips64r6()) {
4153 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4156 const MCOperand &DstRegOp = Inst.getOperand(0);
4157 assert(DstRegOp.isReg() && "expected register operand kind");
4158 const MCOperand &SrcRegOp = Inst.getOperand(1);
4159 assert(SrcRegOp.isReg() && "expected register operand kind");
4160 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4161 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4163 MipsTargetStreamer &TOut = getTargetStreamer();
4164 unsigned DstReg = DstRegOp.getReg();
4165 unsigned SrcReg = SrcRegOp.getReg();
4166 int64_t OffsetValue = OffsetImmOp.getImm();
4168 warnIfNoMacro(IDLoc);
4169 unsigned ATReg = getATReg(IDLoc);
4173 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4174 if (IsLargeOffset) {
4175 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4180 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4181 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4183 std::swap(FirstOffset, SecondOffset);
4185 if (IsLargeOffset) {
4186 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4187 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4188 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4189 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4190 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4191 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4193 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4194 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4195 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4201 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4202 const MCSubtargetInfo *STI) {
4203 if (hasMips32r6() || hasMips64r6()) {
4204 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4207 const MCOperand &DstRegOp = Inst.getOperand(0);
4208 assert(DstRegOp.isReg() && "expected register operand kind");
4209 const MCOperand &SrcRegOp = Inst.getOperand(1);
4210 assert(SrcRegOp.isReg() && "expected register operand kind");
4211 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4212 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4214 MipsTargetStreamer &TOut = getTargetStreamer();
4215 unsigned DstReg = DstRegOp.getReg();
4216 unsigned SrcReg = SrcRegOp.getReg();
4217 int64_t OffsetValue = OffsetImmOp.getImm();
4219 // Compute left/right load/store offsets.
4220 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4221 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4222 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4224 std::swap(LxlOffset, LxrOffset);
4226 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4227 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4228 unsigned TmpReg = SrcReg;
4229 if (IsLargeOffset || DoMove) {
4230 warnIfNoMacro(IDLoc);
4231 TmpReg = getATReg(IDLoc);
4236 if (IsLargeOffset) {
4237 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4243 std::swap(DstReg, TmpReg);
4245 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4246 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4247 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4248 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4251 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4256 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4258 const MCSubtargetInfo *STI) {
4259 MipsTargetStreamer &TOut = getTargetStreamer();
4261 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4262 assert(Inst.getOperand(0).isReg() &&
4263 Inst.getOperand(1).isReg() &&
4264 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4266 unsigned ATReg = Mips::NoRegister;
4267 unsigned FinalDstReg = Mips::NoRegister;
4268 unsigned DstReg = Inst.getOperand(0).getReg();
4269 unsigned SrcReg = Inst.getOperand(1).getReg();
4270 int64_t ImmValue = Inst.getOperand(2).getImm();
4272 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4274 unsigned FinalOpcode = Inst.getOpcode();
4276 if (DstReg == SrcReg) {
4277 ATReg = getATReg(Inst.getLoc());
4280 FinalDstReg = DstReg;
4284 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
4285 switch (FinalOpcode) {
4287 llvm_unreachable("unimplemented expansion");
4289 FinalOpcode = Mips::ADD;
4292 FinalOpcode = Mips::ADDu;
4295 FinalOpcode = Mips::AND;
4298 FinalOpcode = Mips::NOR;
4301 FinalOpcode = Mips::OR;
4304 FinalOpcode = Mips::SLT;
4307 FinalOpcode = Mips::SLTu;
4310 FinalOpcode = Mips::XOR;
4313 FinalOpcode = Mips::ADD_MM;
4315 case Mips::ADDiu_MM:
4316 FinalOpcode = Mips::ADDu_MM;
4319 FinalOpcode = Mips::AND_MM;
4322 FinalOpcode = Mips::OR_MM;
4325 FinalOpcode = Mips::SLT_MM;
4327 case Mips::SLTiu_MM:
4328 FinalOpcode = Mips::SLTu_MM;
4331 FinalOpcode = Mips::XOR_MM;
4334 FinalOpcode = Mips::AND64;
4336 case Mips::NORImm64:
4337 FinalOpcode = Mips::NOR64;
4340 FinalOpcode = Mips::OR64;
4342 case Mips::SLTImm64:
4343 FinalOpcode = Mips::SLT64;
4345 case Mips::SLTUImm64:
4346 FinalOpcode = Mips::SLTu64;
4349 FinalOpcode = Mips::XOR64;
4353 if (FinalDstReg == Mips::NoRegister)
4354 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4356 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4362 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4363 const MCSubtargetInfo *STI) {
4364 MipsTargetStreamer &TOut = getTargetStreamer();
4365 unsigned ATReg = Mips::NoRegister;
4366 unsigned DReg = Inst.getOperand(0).getReg();
4367 unsigned SReg = Inst.getOperand(1).getReg();
4368 unsigned TReg = Inst.getOperand(2).getReg();
4369 unsigned TmpReg = DReg;
4371 unsigned FirstShift = Mips::NOP;
4372 unsigned SecondShift = Mips::NOP;
4374 if (hasMips32r2()) {
4376 TmpReg = getATReg(Inst.getLoc());
4381 if (Inst.getOpcode() == Mips::ROL) {
4382 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4383 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4387 if (Inst.getOpcode() == Mips::ROR) {
4388 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4396 switch (Inst.getOpcode()) {
4398 llvm_unreachable("unexpected instruction opcode");
4400 FirstShift = Mips::SRLV;
4401 SecondShift = Mips::SLLV;
4404 FirstShift = Mips::SLLV;
4405 SecondShift = Mips::SRLV;
4409 ATReg = getATReg(Inst.getLoc());
4413 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4414 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4415 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4416 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4424 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4426 const MCSubtargetInfo *STI) {
4427 MipsTargetStreamer &TOut = getTargetStreamer();
4428 unsigned ATReg = Mips::NoRegister;
4429 unsigned DReg = Inst.getOperand(0).getReg();
4430 unsigned SReg = Inst.getOperand(1).getReg();
4431 int64_t ImmValue = Inst.getOperand(2).getImm();
4433 unsigned FirstShift = Mips::NOP;
4434 unsigned SecondShift = Mips::NOP;
4436 if (hasMips32r2()) {
4437 if (Inst.getOpcode() == Mips::ROLImm) {
4438 uint64_t MaxShift = 32;
4439 uint64_t ShiftValue = ImmValue;
4441 ShiftValue = MaxShift - ImmValue;
4442 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4446 if (Inst.getOpcode() == Mips::RORImm) {
4447 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4455 if (ImmValue == 0) {
4456 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4460 switch (Inst.getOpcode()) {
4462 llvm_unreachable("unexpected instruction opcode");
4464 FirstShift = Mips::SLL;
4465 SecondShift = Mips::SRL;
4468 FirstShift = Mips::SRL;
4469 SecondShift = Mips::SLL;
4473 ATReg = getATReg(Inst.getLoc());
4477 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4478 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4479 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4487 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4488 const MCSubtargetInfo *STI) {
4489 MipsTargetStreamer &TOut = getTargetStreamer();
4490 unsigned ATReg = Mips::NoRegister;
4491 unsigned DReg = Inst.getOperand(0).getReg();
4492 unsigned SReg = Inst.getOperand(1).getReg();
4493 unsigned TReg = Inst.getOperand(2).getReg();
4494 unsigned TmpReg = DReg;
4496 unsigned FirstShift = Mips::NOP;
4497 unsigned SecondShift = Mips::NOP;
4499 if (hasMips64r2()) {
4500 if (TmpReg == SReg) {
4501 TmpReg = getATReg(Inst.getLoc());
4506 if (Inst.getOpcode() == Mips::DROL) {
4507 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4508 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4512 if (Inst.getOpcode() == Mips::DROR) {
4513 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4521 switch (Inst.getOpcode()) {
4523 llvm_unreachable("unexpected instruction opcode");
4525 FirstShift = Mips::DSRLV;
4526 SecondShift = Mips::DSLLV;
4529 FirstShift = Mips::DSLLV;
4530 SecondShift = Mips::DSRLV;
4534 ATReg = getATReg(Inst.getLoc());
4538 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4539 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4540 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4541 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4549 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4551 const MCSubtargetInfo *STI) {
4552 MipsTargetStreamer &TOut = getTargetStreamer();
4553 unsigned ATReg = Mips::NoRegister;
4554 unsigned DReg = Inst.getOperand(0).getReg();
4555 unsigned SReg = Inst.getOperand(1).getReg();
4556 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4558 unsigned FirstShift = Mips::NOP;
4559 unsigned SecondShift = Mips::NOP;
4563 if (hasMips64r2()) {
4564 unsigned FinalOpcode = Mips::NOP;
4566 FinalOpcode = Mips::DROTR;
4567 else if (ImmValue % 32 == 0)
4568 FinalOpcode = Mips::DROTR32;
4569 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4570 if (Inst.getOpcode() == Mips::DROLImm)
4571 FinalOpcode = Mips::DROTR32;
4573 FinalOpcode = Mips::DROTR;
4574 } else if (ImmValue >= 33) {
4575 if (Inst.getOpcode() == Mips::DROLImm)
4576 FinalOpcode = Mips::DROTR;
4578 FinalOpcode = Mips::DROTR32;
4581 uint64_t ShiftValue = ImmValue % 32;
4582 if (Inst.getOpcode() == Mips::DROLImm)
4583 ShiftValue = (32 - ImmValue % 32) % 32;
4585 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4591 if (ImmValue == 0) {
4592 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4596 switch (Inst.getOpcode()) {
4598 llvm_unreachable("unexpected instruction opcode");
4600 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4601 FirstShift = Mips::DSLL;
4602 SecondShift = Mips::DSRL32;
4604 if (ImmValue == 32) {
4605 FirstShift = Mips::DSLL32;
4606 SecondShift = Mips::DSRL32;
4608 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4609 FirstShift = Mips::DSLL32;
4610 SecondShift = Mips::DSRL;
4614 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4615 FirstShift = Mips::DSRL;
4616 SecondShift = Mips::DSLL32;
4618 if (ImmValue == 32) {
4619 FirstShift = Mips::DSRL32;
4620 SecondShift = Mips::DSLL32;
4622 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4623 FirstShift = Mips::DSRL32;
4624 SecondShift = Mips::DSLL;
4629 ATReg = getATReg(Inst.getLoc());
4633 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4634 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4635 Inst.getLoc(), STI);
4636 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4644 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4645 const MCSubtargetInfo *STI) {
4646 MipsTargetStreamer &TOut = getTargetStreamer();
4647 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4648 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4650 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4651 if (FirstRegOp != SecondRegOp)
4652 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4654 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4655 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4660 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4661 const MCSubtargetInfo *STI) {
4662 MipsTargetStreamer &TOut = getTargetStreamer();
4663 unsigned ATReg = Mips::NoRegister;
4664 unsigned DstReg = Inst.getOperand(0).getReg();
4665 unsigned SrcReg = Inst.getOperand(1).getReg();
4666 int32_t ImmValue = Inst.getOperand(2).getImm();
4668 ATReg = getATReg(IDLoc);
4672 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, STI);
4674 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4675 SrcReg, ATReg, IDLoc, STI);
4677 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4682 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4683 const MCSubtargetInfo *STI) {
4684 MipsTargetStreamer &TOut = getTargetStreamer();
4685 unsigned ATReg = Mips::NoRegister;
4686 unsigned DstReg = Inst.getOperand(0).getReg();
4687 unsigned SrcReg = Inst.getOperand(1).getReg();
4688 unsigned TmpReg = Inst.getOperand(2).getReg();
4690 ATReg = getATReg(Inst.getLoc());
4694 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4695 SrcReg, TmpReg, IDLoc, STI);
4697 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4699 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4700 DstReg, DstReg, 0x1F, IDLoc, STI);
4702 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4705 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4707 MCContext & Context = TOut.getStreamer().getContext();
4708 MCSymbol * BrTarget = Context.createTempSymbol();
4710 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4712 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4713 if (AssemblerOptions.back()->isReorder())
4714 TOut.emitNop(IDLoc, STI);
4715 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4717 TOut.getStreamer().EmitLabel(BrTarget);
4719 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4724 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4725 const MCSubtargetInfo *STI) {
4726 MipsTargetStreamer &TOut = getTargetStreamer();
4727 unsigned ATReg = Mips::NoRegister;
4728 unsigned DstReg = Inst.getOperand(0).getReg();
4729 unsigned SrcReg = Inst.getOperand(1).getReg();
4730 unsigned TmpReg = Inst.getOperand(2).getReg();
4732 ATReg = getATReg(IDLoc);
4736 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4737 SrcReg, TmpReg, IDLoc, STI);
4739 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4740 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4742 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4744 MCContext & Context = TOut.getStreamer().getContext();
4745 MCSymbol * BrTarget = Context.createTempSymbol();
4747 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4749 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4750 if (AssemblerOptions.back()->isReorder())
4751 TOut.emitNop(IDLoc, STI);
4752 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4754 TOut.getStreamer().EmitLabel(BrTarget);
4760 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4761 const MCSubtargetInfo *STI) {
4762 MipsTargetStreamer &TOut = getTargetStreamer();
4763 unsigned DstReg = Inst.getOperand(0).getReg();
4764 unsigned SrcReg = Inst.getOperand(1).getReg();
4765 unsigned TmpReg = Inst.getOperand(2).getReg();
4767 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4768 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4773 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4774 // lw $<reg+1>>, offset+4($reg2)'
4775 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4776 // sw $<reg+1>>, offset+4($reg2)'
4778 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4780 const MCSubtargetInfo *STI,
4785 warnIfNoMacro(IDLoc);
4787 MipsTargetStreamer &TOut = getTargetStreamer();
4788 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4789 unsigned FirstReg = Inst.getOperand(0).getReg();
4790 unsigned SecondReg = nextReg(FirstReg);
4791 unsigned BaseReg = Inst.getOperand(1).getReg();
4795 warnIfRegIndexIsAT(FirstReg, IDLoc);
4797 assert(Inst.getOperand(2).isImm() &&
4798 "Offset for load macro is not immediate!");
4800 MCOperand &FirstOffset = Inst.getOperand(2);
4801 signed NextOffset = FirstOffset.getImm() + 4;
4802 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4804 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4807 // For loads, clobber the base register with the second load instead of the
4808 // first if the BaseReg == FirstReg.
4809 if (FirstReg != BaseReg || !IsLoad) {
4810 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4811 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4813 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4814 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4820 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4821 const MCSubtargetInfo *STI) {
4823 warnIfNoMacro(IDLoc);
4824 MipsTargetStreamer &TOut = getTargetStreamer();
4826 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4827 Inst.getOperand(2).getReg() != Mips::ZERO) {
4828 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4829 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4831 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4832 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4837 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4838 Reg = Inst.getOperand(2).getReg();
4840 Reg = Inst.getOperand(1).getReg();
4842 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4846 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4847 const MCSubtargetInfo *STI) {
4848 warnIfNoMacro(IDLoc);
4849 MipsTargetStreamer &TOut = getTargetStreamer();
4852 int64_t Imm = Inst.getOperand(2).getImm();
4853 unsigned Reg = Inst.getOperand(1).getReg();
4856 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4857 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4861 if (Reg == Mips::ZERO) {
4862 Warning(IDLoc, "comparison is always false");
4863 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4864 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4868 if (Imm > -0x8000 && Imm < 0) {
4870 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4875 if (!isUInt<16>(Imm)) {
4876 unsigned ATReg = getATReg(IDLoc);
4880 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4884 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4885 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4886 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4887 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4891 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4893 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4894 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4898 // Map the DSP accumulator and control register to the corresponding gpr
4899 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
4900 // do not map the DSP registers contigously to gpr registers.
4901 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
4902 switch (Inst.getOpcode()) {
4905 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4915 llvm_unreachable("Unknown register for 'mttr' alias!");
4919 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4929 llvm_unreachable("Unknown register for 'mttr' alias!");
4933 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4943 llvm_unreachable("Unknown register for 'mttr' alias!");
4949 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
4953 // Map the floating point register operand to the corresponding register
4955 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
4956 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
4957 case Mips::F0: return Mips::ZERO;
4958 case Mips::F1: return Mips::AT;
4959 case Mips::F2: return Mips::V0;
4960 case Mips::F3: return Mips::V1;
4961 case Mips::F4: return Mips::A0;
4962 case Mips::F5: return Mips::A1;
4963 case Mips::F6: return Mips::A2;
4964 case Mips::F7: return Mips::A3;
4965 case Mips::F8: return Mips::T0;
4966 case Mips::F9: return Mips::T1;
4967 case Mips::F10: return Mips::T2;
4968 case Mips::F11: return Mips::T3;
4969 case Mips::F12: return Mips::T4;
4970 case Mips::F13: return Mips::T5;
4971 case Mips::F14: return Mips::T6;
4972 case Mips::F15: return Mips::T7;
4973 case Mips::F16: return Mips::S0;
4974 case Mips::F17: return Mips::S1;
4975 case Mips::F18: return Mips::S2;
4976 case Mips::F19: return Mips::S3;
4977 case Mips::F20: return Mips::S4;
4978 case Mips::F21: return Mips::S5;
4979 case Mips::F22: return Mips::S6;
4980 case Mips::F23: return Mips::S7;
4981 case Mips::F24: return Mips::T8;
4982 case Mips::F25: return Mips::T9;
4983 case Mips::F26: return Mips::K0;
4984 case Mips::F27: return Mips::K1;
4985 case Mips::F28: return Mips::GP;
4986 case Mips::F29: return Mips::SP;
4987 case Mips::F30: return Mips::FP;
4988 case Mips::F31: return Mips::RA;
4989 default: llvm_unreachable("Unknown register for mttc1 alias!");
4993 // Map the coprocessor operand the corresponding gpr register operand.
4994 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
4995 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
4996 case Mips::COP00: return Mips::ZERO;
4997 case Mips::COP01: return Mips::AT;
4998 case Mips::COP02: return Mips::V0;
4999 case Mips::COP03: return Mips::V1;
5000 case Mips::COP04: return Mips::A0;
5001 case Mips::COP05: return Mips::A1;
5002 case Mips::COP06: return Mips::A2;
5003 case Mips::COP07: return Mips::A3;
5004 case Mips::COP08: return Mips::T0;
5005 case Mips::COP09: return Mips::T1;
5006 case Mips::COP010: return Mips::T2;
5007 case Mips::COP011: return Mips::T3;
5008 case Mips::COP012: return Mips::T4;
5009 case Mips::COP013: return Mips::T5;
5010 case Mips::COP014: return Mips::T6;
5011 case Mips::COP015: return Mips::T7;
5012 case Mips::COP016: return Mips::S0;
5013 case Mips::COP017: return Mips::S1;
5014 case Mips::COP018: return Mips::S2;
5015 case Mips::COP019: return Mips::S3;
5016 case Mips::COP020: return Mips::S4;
5017 case Mips::COP021: return Mips::S5;
5018 case Mips::COP022: return Mips::S6;
5019 case Mips::COP023: return Mips::S7;
5020 case Mips::COP024: return Mips::T8;
5021 case Mips::COP025: return Mips::T9;
5022 case Mips::COP026: return Mips::K0;
5023 case Mips::COP027: return Mips::K1;
5024 case Mips::COP028: return Mips::GP;
5025 case Mips::COP029: return Mips::SP;
5026 case Mips::COP030: return Mips::FP;
5027 case Mips::COP031: return Mips::RA;
5028 default: llvm_unreachable("Unknown register for mttc0 alias!");
5032 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5033 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5034 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5035 const MCSubtargetInfo *STI) {
5036 MipsTargetStreamer &TOut = getTargetStreamer();
5041 bool IsMFTR = false;
5042 switch (Inst.getOpcode()) {
5048 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5049 sel = Inst.getOperand(2).getImm();
5055 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5067 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5075 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5082 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5089 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5093 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5096 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5097 : Inst.getOperand(0).getReg());
5099 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5105 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5106 const OperandVector &Operands) {
5107 switch (Inst.getOpcode()) {
5109 return Match_Success;
5112 case Mips::DATI_MM64R6:
5113 case Mips::DAHI_MM64R6:
5114 if (static_cast<MipsOperand &>(*Operands[1])
5115 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5116 return Match_Success;
5117 return Match_RequiresSameSrcAndDst;
5121 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5122 switch (Inst.getOpcode()) {
5123 // As described by the MIPSR6 spec, daui must not use the zero operand for
5124 // its source operand.
5126 case Mips::DAUI_MM64R6:
5127 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5128 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5129 return Match_RequiresNoZeroRegister;
5130 return Match_Success;
5131 // As described by the Mips32r2 spec, the registers Rd and Rs for
5132 // jalr.hb must be different.
5133 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5134 // and registers Rd and Base for microMIPS lwp instruction
5136 case Mips::JALRC_HB_MMR6:
5137 case Mips::JALRC_MMR6:
5138 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5139 return Match_RequiresDifferentSrcAndDst;
5140 return Match_Success;
5142 case Mips::LWP_MMR6:
5143 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5144 return Match_RequiresDifferentSrcAndDst;
5145 return Match_Success;
5147 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5148 return Match_NonZeroOperandForSync;
5149 return Match_Success;
5150 // As described the MIPSR6 spec, the compact branches that compare registers
5152 // a) Not use the zero register.
5153 // b) Not use the same register twice.
5154 // c) rs < rt for bnec, beqc.
5155 // NB: For this case, the encoding will swap the operands as their
5156 // ordering doesn't matter. GAS performs this transformation too.
5157 // Hence, that constraint does not have to be enforced.
5159 // The compact branches that branch iff the signed addition of two registers
5160 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5161 // operand swapping. They do not have restriction of using the zero register.
5162 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5163 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5164 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5165 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5166 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5167 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5174 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5175 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5176 return Match_RequiresNoZeroRegister;
5177 return Match_Success;
5178 case Mips::BGEC: case Mips::BGEC_MMR6:
5179 case Mips::BLTC: case Mips::BLTC_MMR6:
5180 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5181 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5182 case Mips::BEQC: case Mips::BEQC_MMR6:
5183 case Mips::BNEC: case Mips::BNEC_MMR6:
5190 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5191 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5192 return Match_RequiresNoZeroRegister;
5193 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5194 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5195 return Match_RequiresNoZeroRegister;
5196 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5197 return Match_RequiresDifferentOperands;
5198 return Match_Success;
5201 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5202 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5203 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5204 return Match_NoFCCRegisterForCurrentISA;
5206 return Match_Success;
5210 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5211 uint64_t ErrorInfo) {
5212 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5213 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5214 if (ErrorLoc == SMLoc())
5221 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5222 OperandVector &Operands,
5224 uint64_t &ErrorInfo,
5225 bool MatchingInlineAsm) {
5227 unsigned MatchResult =
5228 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5230 switch (MatchResult) {
5232 if (processInstruction(Inst, IDLoc, Out, STI))
5235 case Match_MissingFeature:
5236 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5238 case Match_InvalidOperand: {
5239 SMLoc ErrorLoc = IDLoc;
5240 if (ErrorInfo != ~0ULL) {
5241 if (ErrorInfo >= Operands.size())
5242 return Error(IDLoc, "too few operands for instruction");
5244 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5245 if (ErrorLoc == SMLoc())
5249 return Error(ErrorLoc, "invalid operand for instruction");
5251 case Match_NonZeroOperandForSync:
5252 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5253 case Match_MnemonicFail:
5254 return Error(IDLoc, "invalid instruction");
5255 case Match_RequiresDifferentSrcAndDst:
5256 return Error(IDLoc, "source and destination must be different");
5257 case Match_RequiresDifferentOperands:
5258 return Error(IDLoc, "registers must be different");
5259 case Match_RequiresNoZeroRegister:
5260 return Error(IDLoc, "invalid operand ($zero) for instruction");
5261 case Match_RequiresSameSrcAndDst:
5262 return Error(IDLoc, "source and destination must match");
5263 case Match_NoFCCRegisterForCurrentISA:
5264 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5265 "non-zero fcc register doesn't exist in current ISA level");
5267 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5269 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5270 "expected 1-bit unsigned immediate");
5272 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5273 "expected 2-bit unsigned immediate");
5275 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5276 "expected immediate in range 1 .. 4");
5278 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5279 "expected 3-bit unsigned immediate");
5281 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5282 "expected 4-bit unsigned immediate");
5284 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5285 "expected 4-bit signed immediate");
5287 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5288 "expected 5-bit unsigned immediate");
5290 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5291 "expected 5-bit signed immediate");
5293 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5294 "expected immediate in range 1 .. 32");
5295 case Match_UImm5_32:
5296 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5297 "expected immediate in range 32 .. 63");
5298 case Match_UImm5_33:
5299 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5300 "expected immediate in range 33 .. 64");
5301 case Match_UImm5_0_Report_UImm6:
5302 // This is used on UImm5 operands that have a corresponding UImm5_32
5303 // operand to avoid confusing the user.
5304 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5305 "expected 6-bit unsigned immediate");
5306 case Match_UImm5_Lsl2:
5307 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5308 "expected both 7-bit unsigned immediate and multiple of 4");
5309 case Match_UImmRange2_64:
5310 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5311 "expected immediate in range 2 .. 64");
5313 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5314 "expected 6-bit unsigned immediate");
5315 case Match_UImm6_Lsl2:
5316 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5317 "expected both 8-bit unsigned immediate and multiple of 4");
5319 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5320 "expected 6-bit signed immediate");
5322 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5323 "expected 7-bit unsigned immediate");
5324 case Match_UImm7_N1:
5325 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5326 "expected immediate in range -1 .. 126");
5327 case Match_SImm7_Lsl2:
5328 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5329 "expected both 9-bit signed immediate and multiple of 4");
5331 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5332 "expected 8-bit unsigned immediate");
5333 case Match_UImm10_0:
5334 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5335 "expected 10-bit unsigned immediate");
5336 case Match_SImm10_0:
5337 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5338 "expected 10-bit signed immediate");
5339 case Match_SImm11_0:
5340 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5341 "expected 11-bit signed immediate");
5343 case Match_UImm16_Relaxed:
5344 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5345 "expected 16-bit unsigned immediate");
5347 case Match_SImm16_Relaxed:
5348 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5349 "expected 16-bit signed immediate");
5350 case Match_SImm19_Lsl2:
5351 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5352 "expected both 19-bit signed immediate and multiple of 4");
5353 case Match_UImm20_0:
5354 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5355 "expected 20-bit unsigned immediate");
5356 case Match_UImm26_0:
5357 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5358 "expected 26-bit unsigned immediate");
5360 case Match_SImm32_Relaxed:
5361 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5362 "expected 32-bit signed immediate");
5363 case Match_UImm32_Coerced:
5364 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5365 "expected 32-bit immediate");
5366 case Match_MemSImm9:
5367 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5368 "expected memory with 9-bit signed offset");
5369 case Match_MemSImm10:
5370 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5371 "expected memory with 10-bit signed offset");
5372 case Match_MemSImm10Lsl1:
5373 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5374 "expected memory with 11-bit signed offset and multiple of 2");
5375 case Match_MemSImm10Lsl2:
5376 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5377 "expected memory with 12-bit signed offset and multiple of 4");
5378 case Match_MemSImm10Lsl3:
5379 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5380 "expected memory with 13-bit signed offset and multiple of 8");
5381 case Match_MemSImm11:
5382 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5383 "expected memory with 11-bit signed offset");
5384 case Match_MemSImm12:
5385 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5386 "expected memory with 12-bit signed offset");
5387 case Match_MemSImm16:
5388 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5389 "expected memory with 16-bit signed offset");
5392 llvm_unreachable("Implement any new match types added!");
5395 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5396 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5397 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5398 ") without \".set noat\"");
5401 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5402 if (!AssemblerOptions.back()->isMacro())
5403 Warning(Loc, "macro instruction expanded into multiple instructions");
5407 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5408 SMRange Range, bool ShowColors) {
5409 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5410 Range, SMFixIt(Range, FixMsg),
5414 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5417 CC = StringSwitch<unsigned>(Name)
5419 .Cases("at", "AT", 1)
5453 if (!(isABI_N32() || isABI_N64()))
5456 if (12 <= CC && CC <= 15) {
5457 // Name is one of t4-t7
5458 AsmToken RegTok = getLexer().peekTok();
5459 SMRange RegRange = RegTok.getLocRange();
5461 StringRef FixedName = StringSwitch<StringRef>(Name)
5467 assert(FixedName != "" && "Register name is not one of t4-t7.");
5469 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5470 "Did you mean $" + FixedName + "?", RegRange);
5473 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5474 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5475 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5476 if (8 <= CC && CC <= 11)
5480 CC = StringSwitch<unsigned>(Name)
5492 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5495 CC = StringSwitch<unsigned>(Name)
5496 .Case("hwr_cpunum", 0)
5497 .Case("hwr_synci_step", 1)
5499 .Case("hwr_ccres", 3)
5500 .Case("hwr_ulr", 29)
5506 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5507 if (Name[0] == 'f') {
5508 StringRef NumString = Name.substr(1);
5510 if (NumString.getAsInteger(10, IntVal))
5511 return -1; // This is not an integer.
5512 if (IntVal > 31) // Maximum index for fpu register.
5519 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5520 if (Name.startswith("fcc")) {
5521 StringRef NumString = Name.substr(3);
5523 if (NumString.getAsInteger(10, IntVal))
5524 return -1; // This is not an integer.
5525 if (IntVal > 7) // There are only 8 fcc registers.
5532 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5533 if (Name.startswith("ac")) {
5534 StringRef NumString = Name.substr(2);
5536 if (NumString.getAsInteger(10, IntVal))
5537 return -1; // This is not an integer.
5538 if (IntVal > 3) // There are only 3 acc registers.
5545 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5548 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5557 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5560 CC = StringSwitch<unsigned>(Name)
5563 .Case("msaaccess", 2)
5565 .Case("msamodify", 4)
5566 .Case("msarequest", 5)
5568 .Case("msaunmap", 7)
5574 bool MipsAsmParser::canUseATReg() {
5575 return AssemblerOptions.back()->getATRegIndex() != 0;
5578 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5579 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5581 reportParseError(Loc,
5582 "pseudo-instruction requires $at, which is not available");
5585 unsigned AT = getReg(
5586 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5590 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5591 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5594 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5595 MCAsmParser &Parser = getParser();
5596 DEBUG(dbgs() << "parseOperand\n");
5598 // Check if the current operand has a custom associated parser, if so, try to
5599 // custom parse the operand, or fallback to the general approach.
5600 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5601 if (ResTy == MatchOperand_Success)
5603 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5604 // there was a match, but an error occurred, in which case, just return that
5605 // the operand parsing failed.
5606 if (ResTy == MatchOperand_ParseFail)
5609 DEBUG(dbgs() << ".. Generic Parser\n");
5611 switch (getLexer().getKind()) {
5612 case AsmToken::Dollar: {
5613 // Parse the register.
5614 SMLoc S = Parser.getTok().getLoc();
5616 // Almost all registers have been parsed by custom parsers. There is only
5617 // one exception to this. $zero (and it's alias $0) will reach this point
5618 // for div, divu, and similar instructions because it is not an operand
5619 // to the instruction definition but an explicit register. Special case
5620 // this situation for now.
5621 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5624 // Maybe it is a symbol reference.
5625 StringRef Identifier;
5626 if (Parser.parseIdentifier(Identifier))
5629 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5630 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5631 // Otherwise create a symbol reference.
5633 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5635 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5639 DEBUG(dbgs() << ".. generic integer expression\n");
5642 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5643 if (getParser().parseExpression(Expr))
5646 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5648 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5651 } // switch(getLexer().getKind())
5655 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5656 switch (Expr->getKind()) {
5657 case MCExpr::Constant:
5659 case MCExpr::SymbolRef:
5660 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5661 case MCExpr::Binary:
5662 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
5663 if (!isEvaluated(BE->getLHS()))
5665 return isEvaluated(BE->getRHS());
5668 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5669 case MCExpr::Target:
5675 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5677 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5678 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5679 if (ResTy == MatchOperand_Success) {
5680 assert(Operands.size() == 1);
5681 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5682 StartLoc = Operand.getStartLoc();
5683 EndLoc = Operand.getEndLoc();
5685 // AFAIK, we only support numeric registers and named GPR's in CFI
5687 // Don't worry about eating tokens before failing. Using an unrecognised
5688 // register is a parse error.
5689 if (Operand.isGPRAsmReg()) {
5690 // Resolve to GPR32 or GPR64 appropriately.
5691 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5694 return (RegNo == (unsigned)-1);
5697 assert(Operands.size() == 0);
5698 return (RegNo == (unsigned)-1);
5701 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5705 return getParser().parseParenExprOfDepth(0, Res, S);
5706 return getParser().parseExpression(Res);
5709 OperandMatchResultTy
5710 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5711 MCAsmParser &Parser = getParser();
5712 DEBUG(dbgs() << "parseMemOperand\n");
5713 const MCExpr *IdVal = nullptr;
5715 bool isParenExpr = false;
5716 OperandMatchResultTy Res = MatchOperand_NoMatch;
5717 // First operand is the offset.
5718 S = Parser.getTok().getLoc();
5720 if (getLexer().getKind() == AsmToken::LParen) {
5725 if (getLexer().getKind() != AsmToken::Dollar) {
5726 if (parseMemOffset(IdVal, isParenExpr))
5727 return MatchOperand_ParseFail;
5729 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5730 if (Tok.isNot(AsmToken::LParen)) {
5731 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5732 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5734 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5735 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5736 return MatchOperand_Success;
5738 if (Tok.is(AsmToken::EndOfStatement)) {
5740 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5742 // Zero register assumed, add a memory operand with ZERO as its base.
5743 // "Base" will be managed by k_Memory.
5744 auto Base = MipsOperand::createGPRReg(
5745 0, "0", getContext().getRegisterInfo(), S, E, *this);
5747 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5748 return MatchOperand_Success;
5750 MCBinaryExpr::Opcode Opcode;
5751 // GAS and LLVM treat comparison operators different. GAS will generate -1
5752 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5753 // highly unlikely to be found in a memory offset expression, we don't
5755 switch (Tok.getKind()) {
5756 case AsmToken::Plus:
5757 Opcode = MCBinaryExpr::Add;
5760 case AsmToken::Minus:
5761 Opcode = MCBinaryExpr::Sub;
5764 case AsmToken::Star:
5765 Opcode = MCBinaryExpr::Mul;
5768 case AsmToken::Pipe:
5769 Opcode = MCBinaryExpr::Or;
5773 Opcode = MCBinaryExpr::And;
5776 case AsmToken::LessLess:
5777 Opcode = MCBinaryExpr::Shl;
5780 case AsmToken::GreaterGreater:
5781 Opcode = MCBinaryExpr::LShr;
5784 case AsmToken::Caret:
5785 Opcode = MCBinaryExpr::Xor;
5788 case AsmToken::Slash:
5789 Opcode = MCBinaryExpr::Div;
5792 case AsmToken::Percent:
5793 Opcode = MCBinaryExpr::Mod;
5797 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5798 return MatchOperand_ParseFail;
5800 const MCExpr * NextExpr;
5801 if (getParser().parseExpression(NextExpr))
5802 return MatchOperand_ParseFail;
5803 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5806 Parser.Lex(); // Eat the '(' token.
5809 Res = parseAnyRegister(Operands);
5810 if (Res != MatchOperand_Success)
5813 if (Parser.getTok().isNot(AsmToken::RParen)) {
5814 Error(Parser.getTok().getLoc(), "')' expected");
5815 return MatchOperand_ParseFail;
5818 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5820 Parser.Lex(); // Eat the ')' token.
5823 IdVal = MCConstantExpr::create(0, getContext());
5825 // Replace the register operand with the memory operand.
5826 std::unique_ptr<MipsOperand> op(
5827 static_cast<MipsOperand *>(Operands.back().release()));
5828 // Remove the register from the operands.
5829 // "op" will be managed by k_Memory.
5830 Operands.pop_back();
5831 // Add the memory operand.
5832 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5834 if (IdVal->evaluateAsAbsolute(Imm))
5835 IdVal = MCConstantExpr::create(Imm, getContext());
5836 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5837 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5841 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5842 return MatchOperand_Success;
5845 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5846 MCAsmParser &Parser = getParser();
5847 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5849 SMLoc S = Parser.getTok().getLoc();
5851 if (Sym->isVariable())
5852 Expr = Sym->getVariableValue();
5855 if (Expr->getKind() == MCExpr::SymbolRef) {
5856 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5857 StringRef DefSymbol = Ref->getSymbol().getName();
5858 if (DefSymbol.startswith("$")) {
5859 OperandMatchResultTy ResTy =
5860 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5861 if (ResTy == MatchOperand_Success) {
5864 } else if (ResTy == MatchOperand_ParseFail)
5865 llvm_unreachable("Should never ParseFail");
5873 OperandMatchResultTy
5874 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
5875 StringRef Identifier,
5877 int Index = matchCPURegisterName(Identifier);
5879 Operands.push_back(MipsOperand::createGPRReg(
5880 Index, Identifier, getContext().getRegisterInfo(), S,
5881 getLexer().getLoc(), *this));
5882 return MatchOperand_Success;
5885 Index = matchHWRegsRegisterName(Identifier);
5887 Operands.push_back(MipsOperand::createHWRegsReg(
5888 Index, Identifier, getContext().getRegisterInfo(), S,
5889 getLexer().getLoc(), *this));
5890 return MatchOperand_Success;
5893 Index = matchFPURegisterName(Identifier);
5895 Operands.push_back(MipsOperand::createFGRReg(
5896 Index, Identifier, getContext().getRegisterInfo(), S,
5897 getLexer().getLoc(), *this));
5898 return MatchOperand_Success;
5901 Index = matchFCCRegisterName(Identifier);
5903 Operands.push_back(MipsOperand::createFCCReg(
5904 Index, Identifier, getContext().getRegisterInfo(), S,
5905 getLexer().getLoc(), *this));
5906 return MatchOperand_Success;
5909 Index = matchACRegisterName(Identifier);
5911 Operands.push_back(MipsOperand::createACCReg(
5912 Index, Identifier, getContext().getRegisterInfo(), S,
5913 getLexer().getLoc(), *this));
5914 return MatchOperand_Success;
5917 Index = matchMSA128RegisterName(Identifier);
5919 Operands.push_back(MipsOperand::createMSA128Reg(
5920 Index, Identifier, getContext().getRegisterInfo(), S,
5921 getLexer().getLoc(), *this));
5922 return MatchOperand_Success;
5925 Index = matchMSA128CtrlRegisterName(Identifier);
5927 Operands.push_back(MipsOperand::createMSACtrlReg(
5928 Index, Identifier, getContext().getRegisterInfo(), S,
5929 getLexer().getLoc(), *this));
5930 return MatchOperand_Success;
5933 return MatchOperand_NoMatch;
5936 OperandMatchResultTy
5937 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
5938 MCAsmParser &Parser = getParser();
5939 auto Token = Parser.getLexer().peekTok(false);
5941 if (Token.is(AsmToken::Identifier)) {
5942 DEBUG(dbgs() << ".. identifier\n");
5943 StringRef Identifier = Token.getIdentifier();
5944 OperandMatchResultTy ResTy =
5945 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
5947 } else if (Token.is(AsmToken::Integer)) {
5948 DEBUG(dbgs() << ".. integer\n");
5949 Operands.push_back(MipsOperand::createNumericReg(
5950 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
5951 Token.getLoc(), *this));
5952 return MatchOperand_Success;
5955 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
5957 return MatchOperand_NoMatch;
5960 OperandMatchResultTy
5961 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
5962 MCAsmParser &Parser = getParser();
5963 DEBUG(dbgs() << "parseAnyRegister\n");
5965 auto Token = Parser.getTok();
5967 SMLoc S = Token.getLoc();
5969 if (Token.isNot(AsmToken::Dollar)) {
5970 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
5971 if (Token.is(AsmToken::Identifier)) {
5972 if (searchSymbolAlias(Operands))
5973 return MatchOperand_Success;
5975 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
5976 return MatchOperand_NoMatch;
5978 DEBUG(dbgs() << ".. $\n");
5980 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
5981 if (ResTy == MatchOperand_Success) {
5983 Parser.Lex(); // identifier
5988 OperandMatchResultTy
5989 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
5990 MCAsmParser &Parser = getParser();
5991 DEBUG(dbgs() << "parseJumpTarget\n");
5993 SMLoc S = getLexer().getLoc();
5995 // Registers are a valid target and have priority over symbols.
5996 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5997 if (ResTy != MatchOperand_NoMatch)
6000 // Integers and expressions are acceptable
6001 const MCExpr *Expr = nullptr;
6002 if (Parser.parseExpression(Expr)) {
6003 // We have no way of knowing if a symbol was consumed so we must ParseFail
6004 return MatchOperand_ParseFail;
6007 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6008 return MatchOperand_Success;
6011 OperandMatchResultTy
6012 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6013 MCAsmParser &Parser = getParser();
6014 const MCExpr *IdVal;
6015 // If the first token is '$' we may have register operand.
6016 if (Parser.getTok().is(AsmToken::Dollar))
6017 return MatchOperand_NoMatch;
6018 SMLoc S = Parser.getTok().getLoc();
6019 if (getParser().parseExpression(IdVal))
6020 return MatchOperand_ParseFail;
6021 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6022 assert(MCE && "Unexpected MCExpr type.");
6023 int64_t Val = MCE->getValue();
6024 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6025 Operands.push_back(MipsOperand::CreateImm(
6026 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6027 return MatchOperand_Success;
6030 OperandMatchResultTy
6031 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6032 MCAsmParser &Parser = getParser();
6033 SmallVector<unsigned, 10> Regs;
6035 unsigned PrevReg = Mips::NoRegister;
6036 bool RegRange = false;
6037 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6039 if (Parser.getTok().isNot(AsmToken::Dollar))
6040 return MatchOperand_ParseFail;
6042 SMLoc S = Parser.getTok().getLoc();
6043 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6044 SMLoc E = getLexer().getLoc();
6045 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6046 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6048 // Remove last register operand because registers from register range
6049 // should be inserted first.
6050 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6051 (!isGP64bit() && RegNo == Mips::RA)) {
6052 Regs.push_back(RegNo);
6054 unsigned TmpReg = PrevReg + 1;
6055 while (TmpReg <= RegNo) {
6056 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6057 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6059 Error(E, "invalid register operand");
6060 return MatchOperand_ParseFail;
6064 Regs.push_back(TmpReg++);
6070 if ((PrevReg == Mips::NoRegister) &&
6071 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6072 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6073 Error(E, "$16 or $31 expected");
6074 return MatchOperand_ParseFail;
6075 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6076 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6078 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6079 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6081 Error(E, "invalid register operand");
6082 return MatchOperand_ParseFail;
6083 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6084 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6085 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6087 Error(E, "consecutive register numbers expected");
6088 return MatchOperand_ParseFail;
6091 Regs.push_back(RegNo);
6094 if (Parser.getTok().is(AsmToken::Minus))
6097 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6098 !Parser.getTok().isNot(AsmToken::Comma)) {
6099 Error(E, "',' or '-' expected");
6100 return MatchOperand_ParseFail;
6103 Lex(); // Consume comma or minus
6104 if (Parser.getTok().isNot(AsmToken::Dollar))
6110 SMLoc E = Parser.getTok().getLoc();
6111 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6112 parseMemOperand(Operands);
6113 return MatchOperand_Success;
6116 OperandMatchResultTy
6117 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
6118 MCAsmParser &Parser = getParser();
6120 SMLoc S = Parser.getTok().getLoc();
6121 if (parseAnyRegister(Operands) != MatchOperand_Success)
6122 return MatchOperand_ParseFail;
6124 SMLoc E = Parser.getTok().getLoc();
6125 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
6127 Operands.pop_back();
6128 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
6129 return MatchOperand_Success;
6132 OperandMatchResultTy
6133 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
6134 MCAsmParser &Parser = getParser();
6135 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6136 SmallVector<unsigned, 10> Regs;
6138 if (Parser.getTok().isNot(AsmToken::Dollar))
6139 return MatchOperand_ParseFail;
6141 SMLoc S = Parser.getTok().getLoc();
6143 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6144 return MatchOperand_ParseFail;
6146 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
6147 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6148 Regs.push_back(RegNo);
6150 SMLoc E = Parser.getTok().getLoc();
6151 if (Parser.getTok().isNot(AsmToken::Comma)) {
6152 Error(E, "',' expected");
6153 return MatchOperand_ParseFail;
6159 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6160 return MatchOperand_ParseFail;
6162 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
6163 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6164 Regs.push_back(RegNo);
6166 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6168 return MatchOperand_Success;
6171 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6173 /// ::= '(', register, ')'
6174 /// handle it before we iterate so we don't get tripped up by the lack of
6176 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6177 MCAsmParser &Parser = getParser();
6178 if (getLexer().is(AsmToken::LParen)) {
6180 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6182 if (parseOperand(Operands, Name)) {
6183 SMLoc Loc = getLexer().getLoc();
6184 return Error(Loc, "unexpected token in argument list");
6186 if (Parser.getTok().isNot(AsmToken::RParen)) {
6187 SMLoc Loc = getLexer().getLoc();
6188 return Error(Loc, "unexpected token, expected ')'");
6191 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6197 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6198 /// either one of these.
6199 /// ::= '[', register, ']'
6200 /// ::= '[', integer, ']'
6201 /// handle it before we iterate so we don't get tripped up by the lack of
6203 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6204 OperandVector &Operands) {
6205 MCAsmParser &Parser = getParser();
6206 if (getLexer().is(AsmToken::LBrac)) {
6208 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6210 if (parseOperand(Operands, Name)) {
6211 SMLoc Loc = getLexer().getLoc();
6212 return Error(Loc, "unexpected token in argument list");
6214 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6215 SMLoc Loc = getLexer().getLoc();
6216 return Error(Loc, "unexpected token, expected ']'");
6219 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6225 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6226 SMLoc NameLoc, OperandVector &Operands) {
6227 MCAsmParser &Parser = getParser();
6228 DEBUG(dbgs() << "ParseInstruction\n");
6230 // We have reached first instruction, module directive are now forbidden.
6231 getTargetStreamer().forbidModuleDirective();
6233 // Check if we have valid mnemonic
6234 if (!mnemonicIsValid(Name, 0)) {
6235 return Error(NameLoc, "unknown instruction");
6237 // First operand in MCInst is instruction mnemonic.
6238 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6240 // Read the remaining operands.
6241 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6242 // Read the first operand.
6243 if (parseOperand(Operands, Name)) {
6244 SMLoc Loc = getLexer().getLoc();
6245 return Error(Loc, "unexpected token in argument list");
6247 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6249 // AFAIK, parenthesis suffixes are never on the first operand
6251 while (getLexer().is(AsmToken::Comma)) {
6252 Parser.Lex(); // Eat the comma.
6253 // Parse and remember the operand.
6254 if (parseOperand(Operands, Name)) {
6255 SMLoc Loc = getLexer().getLoc();
6256 return Error(Loc, "unexpected token in argument list");
6258 // Parse bracket and parenthesis suffixes before we iterate
6259 if (getLexer().is(AsmToken::LBrac)) {
6260 if (parseBracketSuffix(Name, Operands))
6262 } else if (getLexer().is(AsmToken::LParen) &&
6263 parseParenSuffix(Name, Operands))
6267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6268 SMLoc Loc = getLexer().getLoc();
6269 return Error(Loc, "unexpected token in argument list");
6271 Parser.Lex(); // Consume the EndOfStatement.
6275 // FIXME: Given that these have the same name, these should both be
6276 // consistent on affecting the Parser.
6277 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6278 SMLoc Loc = getLexer().getLoc();
6279 return Error(Loc, ErrorMsg);
6282 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6283 return Error(Loc, ErrorMsg);
6286 bool MipsAsmParser::parseSetNoAtDirective() {
6287 MCAsmParser &Parser = getParser();
6288 // Line should look like: ".set noat".
6290 // Set the $at register to $0.
6291 AssemblerOptions.back()->setATRegIndex(0);
6293 Parser.Lex(); // Eat "noat".
6295 // If this is not the end of the statement, report an error.
6296 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6297 reportParseError("unexpected token, expected end of statement");
6301 getTargetStreamer().emitDirectiveSetNoAt();
6302 Parser.Lex(); // Consume the EndOfStatement.
6306 bool MipsAsmParser::parseSetAtDirective() {
6307 // Line can be: ".set at", which sets $at to $1
6308 // or ".set at=$reg", which sets $at to $reg.
6309 MCAsmParser &Parser = getParser();
6310 Parser.Lex(); // Eat "at".
6312 if (getLexer().is(AsmToken::EndOfStatement)) {
6313 // No register was specified, so we set $at to $1.
6314 AssemblerOptions.back()->setATRegIndex(1);
6316 getTargetStreamer().emitDirectiveSetAt();
6317 Parser.Lex(); // Consume the EndOfStatement.
6321 if (getLexer().isNot(AsmToken::Equal)) {
6322 reportParseError("unexpected token, expected equals sign");
6325 Parser.Lex(); // Eat "=".
6327 if (getLexer().isNot(AsmToken::Dollar)) {
6328 if (getLexer().is(AsmToken::EndOfStatement)) {
6329 reportParseError("no register specified");
6332 reportParseError("unexpected token, expected dollar sign '$'");
6336 Parser.Lex(); // Eat "$".
6338 // Find out what "reg" is.
6340 const AsmToken &Reg = Parser.getTok();
6341 if (Reg.is(AsmToken::Identifier)) {
6342 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6343 } else if (Reg.is(AsmToken::Integer)) {
6344 AtRegNo = Reg.getIntVal();
6346 reportParseError("unexpected token, expected identifier or integer");
6350 // Check if $reg is a valid register. If it is, set $at to $reg.
6351 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6352 reportParseError("invalid register");
6355 Parser.Lex(); // Eat "reg".
6357 // If this is not the end of the statement, report an error.
6358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6359 reportParseError("unexpected token, expected end of statement");
6363 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6365 Parser.Lex(); // Consume the EndOfStatement.
6369 bool MipsAsmParser::parseSetReorderDirective() {
6370 MCAsmParser &Parser = getParser();
6372 // If this is not the end of the statement, report an error.
6373 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6374 reportParseError("unexpected token, expected end of statement");
6377 AssemblerOptions.back()->setReorder();
6378 getTargetStreamer().emitDirectiveSetReorder();
6379 Parser.Lex(); // Consume the EndOfStatement.
6383 bool MipsAsmParser::parseSetNoReorderDirective() {
6384 MCAsmParser &Parser = getParser();
6386 // If this is not the end of the statement, report an error.
6387 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6388 reportParseError("unexpected token, expected end of statement");
6391 AssemblerOptions.back()->setNoReorder();
6392 getTargetStreamer().emitDirectiveSetNoReorder();
6393 Parser.Lex(); // Consume the EndOfStatement.
6397 bool MipsAsmParser::parseSetMacroDirective() {
6398 MCAsmParser &Parser = getParser();
6400 // If this is not the end of the statement, report an error.
6401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6402 reportParseError("unexpected token, expected end of statement");
6405 AssemblerOptions.back()->setMacro();
6406 getTargetStreamer().emitDirectiveSetMacro();
6407 Parser.Lex(); // Consume the EndOfStatement.
6411 bool MipsAsmParser::parseSetNoMacroDirective() {
6412 MCAsmParser &Parser = getParser();
6414 // If this is not the end of the statement, report an error.
6415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6416 reportParseError("unexpected token, expected end of statement");
6419 if (AssemblerOptions.back()->isReorder()) {
6420 reportParseError("`noreorder' must be set before `nomacro'");
6423 AssemblerOptions.back()->setNoMacro();
6424 getTargetStreamer().emitDirectiveSetNoMacro();
6425 Parser.Lex(); // Consume the EndOfStatement.
6429 bool MipsAsmParser::parseSetMsaDirective() {
6430 MCAsmParser &Parser = getParser();
6433 // If this is not the end of the statement, report an error.
6434 if (getLexer().isNot(AsmToken::EndOfStatement))
6435 return reportParseError("unexpected token, expected end of statement");
6437 setFeatureBits(Mips::FeatureMSA, "msa");
6438 getTargetStreamer().emitDirectiveSetMsa();
6442 bool MipsAsmParser::parseSetNoMsaDirective() {
6443 MCAsmParser &Parser = getParser();
6446 // If this is not the end of the statement, report an error.
6447 if (getLexer().isNot(AsmToken::EndOfStatement))
6448 return reportParseError("unexpected token, expected end of statement");
6450 clearFeatureBits(Mips::FeatureMSA, "msa");
6451 getTargetStreamer().emitDirectiveSetNoMsa();
6455 bool MipsAsmParser::parseSetNoDspDirective() {
6456 MCAsmParser &Parser = getParser();
6457 Parser.Lex(); // Eat "nodsp".
6459 // If this is not the end of the statement, report an error.
6460 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6461 reportParseError("unexpected token, expected end of statement");
6465 clearFeatureBits(Mips::FeatureDSP, "dsp");
6466 getTargetStreamer().emitDirectiveSetNoDsp();
6470 bool MipsAsmParser::parseSetMips16Directive() {
6471 MCAsmParser &Parser = getParser();
6472 Parser.Lex(); // Eat "mips16".
6474 // If this is not the end of the statement, report an error.
6475 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6476 reportParseError("unexpected token, expected end of statement");
6480 setFeatureBits(Mips::FeatureMips16, "mips16");
6481 getTargetStreamer().emitDirectiveSetMips16();
6482 Parser.Lex(); // Consume the EndOfStatement.
6486 bool MipsAsmParser::parseSetNoMips16Directive() {
6487 MCAsmParser &Parser = getParser();
6488 Parser.Lex(); // Eat "nomips16".
6490 // If this is not the end of the statement, report an error.
6491 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6492 reportParseError("unexpected token, expected end of statement");
6496 clearFeatureBits(Mips::FeatureMips16, "mips16");
6497 getTargetStreamer().emitDirectiveSetNoMips16();
6498 Parser.Lex(); // Consume the EndOfStatement.
6502 bool MipsAsmParser::parseSetFpDirective() {
6503 MCAsmParser &Parser = getParser();
6504 MipsABIFlagsSection::FpABIKind FpAbiVal;
6505 // Line can be: .set fp=32
6508 Parser.Lex(); // Eat fp token
6509 AsmToken Tok = Parser.getTok();
6510 if (Tok.isNot(AsmToken::Equal)) {
6511 reportParseError("unexpected token, expected equals sign '='");
6514 Parser.Lex(); // Eat '=' token.
6515 Tok = Parser.getTok();
6517 if (!parseFpABIValue(FpAbiVal, ".set"))
6520 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6521 reportParseError("unexpected token, expected end of statement");
6524 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6525 Parser.Lex(); // Consume the EndOfStatement.
6529 bool MipsAsmParser::parseSetOddSPRegDirective() {
6530 MCAsmParser &Parser = getParser();
6532 Parser.Lex(); // Eat "oddspreg".
6533 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6534 reportParseError("unexpected token, expected end of statement");
6538 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6539 getTargetStreamer().emitDirectiveSetOddSPReg();
6543 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6544 MCAsmParser &Parser = getParser();
6546 Parser.Lex(); // Eat "nooddspreg".
6547 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6548 reportParseError("unexpected token, expected end of statement");
6552 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6553 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6557 bool MipsAsmParser::parseSetMtDirective() {
6558 MCAsmParser &Parser = getParser();
6559 Parser.Lex(); // Eat "mt".
6561 // If this is not the end of the statement, report an error.
6562 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6563 reportParseError("unexpected token, expected end of statement");
6567 setFeatureBits(Mips::FeatureMT, "mt");
6568 getTargetStreamer().emitDirectiveSetMt();
6569 Parser.Lex(); // Consume the EndOfStatement.
6573 bool MipsAsmParser::parseSetNoMtDirective() {
6574 MCAsmParser &Parser = getParser();
6575 Parser.Lex(); // Eat "nomt".
6577 // If this is not the end of the statement, report an error.
6578 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6579 reportParseError("unexpected token, expected end of statement");
6583 clearFeatureBits(Mips::FeatureMT, "mt");
6585 getTargetStreamer().emitDirectiveSetNoMt();
6586 Parser.Lex(); // Consume the EndOfStatement.
6590 bool MipsAsmParser::parseSetPopDirective() {
6591 MCAsmParser &Parser = getParser();
6592 SMLoc Loc = getLexer().getLoc();
6595 if (getLexer().isNot(AsmToken::EndOfStatement))
6596 return reportParseError("unexpected token, expected end of statement");
6598 // Always keep an element on the options "stack" to prevent the user
6599 // from changing the initial options. This is how we remember them.
6600 if (AssemblerOptions.size() == 2)
6601 return reportParseError(Loc, ".set pop with no .set push");
6603 MCSubtargetInfo &STI = copySTI();
6604 AssemblerOptions.pop_back();
6605 setAvailableFeatures(
6606 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6607 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6609 getTargetStreamer().emitDirectiveSetPop();
6613 bool MipsAsmParser::parseSetPushDirective() {
6614 MCAsmParser &Parser = getParser();
6616 if (getLexer().isNot(AsmToken::EndOfStatement))
6617 return reportParseError("unexpected token, expected end of statement");
6619 // Create a copy of the current assembler options environment and push it.
6620 AssemblerOptions.push_back(
6621 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6623 getTargetStreamer().emitDirectiveSetPush();
6627 bool MipsAsmParser::parseSetSoftFloatDirective() {
6628 MCAsmParser &Parser = getParser();
6630 if (getLexer().isNot(AsmToken::EndOfStatement))
6631 return reportParseError("unexpected token, expected end of statement");
6633 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6634 getTargetStreamer().emitDirectiveSetSoftFloat();
6638 bool MipsAsmParser::parseSetHardFloatDirective() {
6639 MCAsmParser &Parser = getParser();
6641 if (getLexer().isNot(AsmToken::EndOfStatement))
6642 return reportParseError("unexpected token, expected end of statement");
6644 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6645 getTargetStreamer().emitDirectiveSetHardFloat();
6649 bool MipsAsmParser::parseSetAssignment() {
6651 const MCExpr *Value;
6652 MCAsmParser &Parser = getParser();
6654 if (Parser.parseIdentifier(Name))
6655 reportParseError("expected identifier after .set");
6657 if (getLexer().isNot(AsmToken::Comma))
6658 return reportParseError("unexpected token, expected comma");
6661 if (Parser.parseExpression(Value))
6662 return reportParseError("expected valid expression after comma");
6664 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6665 Sym->setVariableValue(Value);
6670 bool MipsAsmParser::parseSetMips0Directive() {
6671 MCAsmParser &Parser = getParser();
6673 if (getLexer().isNot(AsmToken::EndOfStatement))
6674 return reportParseError("unexpected token, expected end of statement");
6676 // Reset assembler options to their initial values.
6677 MCSubtargetInfo &STI = copySTI();
6678 setAvailableFeatures(
6679 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6680 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6681 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6683 getTargetStreamer().emitDirectiveSetMips0();
6687 bool MipsAsmParser::parseSetArchDirective() {
6688 MCAsmParser &Parser = getParser();
6690 if (getLexer().isNot(AsmToken::Equal))
6691 return reportParseError("unexpected token, expected equals sign");
6695 if (Parser.parseIdentifier(Arch))
6696 return reportParseError("expected arch identifier");
6698 StringRef ArchFeatureName =
6699 StringSwitch<StringRef>(Arch)
6700 .Case("mips1", "mips1")
6701 .Case("mips2", "mips2")
6702 .Case("mips3", "mips3")
6703 .Case("mips4", "mips4")
6704 .Case("mips5", "mips5")
6705 .Case("mips32", "mips32")
6706 .Case("mips32r2", "mips32r2")
6707 .Case("mips32r3", "mips32r3")
6708 .Case("mips32r5", "mips32r5")
6709 .Case("mips32r6", "mips32r6")
6710 .Case("mips64", "mips64")
6711 .Case("mips64r2", "mips64r2")
6712 .Case("mips64r3", "mips64r3")
6713 .Case("mips64r5", "mips64r5")
6714 .Case("mips64r6", "mips64r6")
6715 .Case("octeon", "cnmips")
6716 .Case("r4000", "mips3") // This is an implementation of Mips3.
6719 if (ArchFeatureName.empty())
6720 return reportParseError("unsupported architecture");
6722 selectArch(ArchFeatureName);
6723 getTargetStreamer().emitDirectiveSetArch(Arch);
6727 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6728 MCAsmParser &Parser = getParser();
6730 if (getLexer().isNot(AsmToken::EndOfStatement))
6731 return reportParseError("unexpected token, expected end of statement");
6735 llvm_unreachable("Unimplemented feature");
6736 case Mips::FeatureDSP:
6737 setFeatureBits(Mips::FeatureDSP, "dsp");
6738 getTargetStreamer().emitDirectiveSetDsp();
6740 case Mips::FeatureMicroMips:
6741 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6742 getTargetStreamer().emitDirectiveSetMicroMips();
6744 case Mips::FeatureMips1:
6745 selectArch("mips1");
6746 getTargetStreamer().emitDirectiveSetMips1();
6748 case Mips::FeatureMips2:
6749 selectArch("mips2");
6750 getTargetStreamer().emitDirectiveSetMips2();
6752 case Mips::FeatureMips3:
6753 selectArch("mips3");
6754 getTargetStreamer().emitDirectiveSetMips3();
6756 case Mips::FeatureMips4:
6757 selectArch("mips4");
6758 getTargetStreamer().emitDirectiveSetMips4();
6760 case Mips::FeatureMips5:
6761 selectArch("mips5");
6762 getTargetStreamer().emitDirectiveSetMips5();
6764 case Mips::FeatureMips32:
6765 selectArch("mips32");
6766 getTargetStreamer().emitDirectiveSetMips32();
6768 case Mips::FeatureMips32r2:
6769 selectArch("mips32r2");
6770 getTargetStreamer().emitDirectiveSetMips32R2();
6772 case Mips::FeatureMips32r3:
6773 selectArch("mips32r3");
6774 getTargetStreamer().emitDirectiveSetMips32R3();
6776 case Mips::FeatureMips32r5:
6777 selectArch("mips32r5");
6778 getTargetStreamer().emitDirectiveSetMips32R5();
6780 case Mips::FeatureMips32r6:
6781 selectArch("mips32r6");
6782 getTargetStreamer().emitDirectiveSetMips32R6();
6784 case Mips::FeatureMips64:
6785 selectArch("mips64");
6786 getTargetStreamer().emitDirectiveSetMips64();
6788 case Mips::FeatureMips64r2:
6789 selectArch("mips64r2");
6790 getTargetStreamer().emitDirectiveSetMips64R2();
6792 case Mips::FeatureMips64r3:
6793 selectArch("mips64r3");
6794 getTargetStreamer().emitDirectiveSetMips64R3();
6796 case Mips::FeatureMips64r5:
6797 selectArch("mips64r5");
6798 getTargetStreamer().emitDirectiveSetMips64R5();
6800 case Mips::FeatureMips64r6:
6801 selectArch("mips64r6");
6802 getTargetStreamer().emitDirectiveSetMips64R6();
6808 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6809 MCAsmParser &Parser = getParser();
6810 if (getLexer().isNot(AsmToken::Comma)) {
6811 SMLoc Loc = getLexer().getLoc();
6812 return Error(Loc, ErrorStr);
6815 Parser.Lex(); // Eat the comma.
6819 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
6820 // In this class, it is only used for .cprestore.
6821 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
6822 // MipsTargetELFStreamer and MipsAsmParser.
6823 bool MipsAsmParser::isPicAndNotNxxAbi() {
6824 return inPicMode() && !(isABI_N32() || isABI_N64());
6827 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
6828 if (AssemblerOptions.back()->isReorder())
6829 Warning(Loc, ".cpload should be inside a noreorder section");
6831 if (inMips16Mode()) {
6832 reportParseError(".cpload is not supported in Mips16 mode");
6836 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
6837 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
6838 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6839 reportParseError("expected register containing function address");
6843 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
6844 if (!RegOpnd.isGPRAsmReg()) {
6845 reportParseError(RegOpnd.getStartLoc(), "invalid register");
6849 // If this is not the end of the statement, report an error.
6850 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6851 reportParseError("unexpected token, expected end of statement");
6855 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
6859 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
6860 MCAsmParser &Parser = getParser();
6862 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
6863 // is used in non-PIC mode.
6865 if (inMips16Mode()) {
6866 reportParseError(".cprestore is not supported in Mips16 mode");
6870 // Get the stack offset value.
6871 const MCExpr *StackOffset;
6872 int64_t StackOffsetVal;
6873 if (Parser.parseExpression(StackOffset)) {
6874 reportParseError("expected stack offset value");
6878 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
6879 reportParseError("stack offset is not an absolute expression");
6883 if (StackOffsetVal < 0) {
6884 Warning(Loc, ".cprestore with negative stack offset has no effect");
6885 IsCpRestoreSet = false;
6887 IsCpRestoreSet = true;
6888 CpRestoreOffset = StackOffsetVal;
6891 // If this is not the end of the statement, report an error.
6892 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6893 reportParseError("unexpected token, expected end of statement");
6897 if (!getTargetStreamer().emitDirectiveCpRestore(
6898 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
6900 Parser.Lex(); // Consume the EndOfStatement.
6904 bool MipsAsmParser::parseDirectiveCPSetup() {
6905 MCAsmParser &Parser = getParser();
6908 bool SaveIsReg = true;
6910 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6911 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6912 if (ResTy == MatchOperand_NoMatch) {
6913 reportParseError("expected register containing function address");
6917 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6918 if (!FuncRegOpnd.isGPRAsmReg()) {
6919 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
6923 FuncReg = FuncRegOpnd.getGPR32Reg();
6926 if (!eatComma("unexpected token, expected comma"))
6929 ResTy = parseAnyRegister(TmpReg);
6930 if (ResTy == MatchOperand_NoMatch) {
6931 const MCExpr *OffsetExpr;
6933 SMLoc ExprLoc = getLexer().getLoc();
6935 if (Parser.parseExpression(OffsetExpr) ||
6936 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
6937 reportParseError(ExprLoc, "expected save register or stack offset");
6944 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6945 if (!SaveOpnd.isGPRAsmReg()) {
6946 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
6949 Save = SaveOpnd.getGPR32Reg();
6952 if (!eatComma("unexpected token, expected comma"))
6956 if (Parser.parseExpression(Expr)) {
6957 reportParseError("expected expression");
6961 if (Expr->getKind() != MCExpr::SymbolRef) {
6962 reportParseError("expected symbol");
6965 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6967 CpSaveLocation = Save;
6968 CpSaveLocationIsRegister = SaveIsReg;
6970 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
6975 bool MipsAsmParser::parseDirectiveCPReturn() {
6976 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
6977 CpSaveLocationIsRegister);
6981 bool MipsAsmParser::parseDirectiveNaN() {
6982 MCAsmParser &Parser = getParser();
6983 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6984 const AsmToken &Tok = Parser.getTok();
6986 if (Tok.getString() == "2008") {
6988 getTargetStreamer().emitDirectiveNaN2008();
6990 } else if (Tok.getString() == "legacy") {
6992 getTargetStreamer().emitDirectiveNaNLegacy();
6996 // If we don't recognize the option passed to the .nan
6997 // directive (e.g. no option or unknown option), emit an error.
6998 reportParseError("invalid option in .nan directive");
7002 bool MipsAsmParser::parseDirectiveSet() {
7003 MCAsmParser &Parser = getParser();
7004 // Get the next token.
7005 const AsmToken &Tok = Parser.getTok();
7007 if (Tok.getString() == "noat") {
7008 return parseSetNoAtDirective();
7009 } else if (Tok.getString() == "at") {
7010 return parseSetAtDirective();
7011 } else if (Tok.getString() == "arch") {
7012 return parseSetArchDirective();
7013 } else if (Tok.getString() == "bopt") {
7014 Warning(Tok.getLoc(), "'bopt' feature is unsupported");
7017 } else if (Tok.getString() == "nobopt") {
7018 // We're already running in nobopt mode, so nothing to do.
7021 } else if (Tok.getString() == "fp") {
7022 return parseSetFpDirective();
7023 } else if (Tok.getString() == "oddspreg") {
7024 return parseSetOddSPRegDirective();
7025 } else if (Tok.getString() == "nooddspreg") {
7026 return parseSetNoOddSPRegDirective();
7027 } else if (Tok.getString() == "pop") {
7028 return parseSetPopDirective();
7029 } else if (Tok.getString() == "push") {
7030 return parseSetPushDirective();
7031 } else if (Tok.getString() == "reorder") {
7032 return parseSetReorderDirective();
7033 } else if (Tok.getString() == "noreorder") {
7034 return parseSetNoReorderDirective();
7035 } else if (Tok.getString() == "macro") {
7036 return parseSetMacroDirective();
7037 } else if (Tok.getString() == "nomacro") {
7038 return parseSetNoMacroDirective();
7039 } else if (Tok.getString() == "mips16") {
7040 return parseSetMips16Directive();
7041 } else if (Tok.getString() == "nomips16") {
7042 return parseSetNoMips16Directive();
7043 } else if (Tok.getString() == "nomicromips") {
7044 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7045 getTargetStreamer().emitDirectiveSetNoMicroMips();
7046 Parser.eatToEndOfStatement();
7048 } else if (Tok.getString() == "micromips") {
7049 return parseSetFeature(Mips::FeatureMicroMips);
7050 } else if (Tok.getString() == "mips0") {
7051 return parseSetMips0Directive();
7052 } else if (Tok.getString() == "mips1") {
7053 return parseSetFeature(Mips::FeatureMips1);
7054 } else if (Tok.getString() == "mips2") {
7055 return parseSetFeature(Mips::FeatureMips2);
7056 } else if (Tok.getString() == "mips3") {
7057 return parseSetFeature(Mips::FeatureMips3);
7058 } else if (Tok.getString() == "mips4") {
7059 return parseSetFeature(Mips::FeatureMips4);
7060 } else if (Tok.getString() == "mips5") {
7061 return parseSetFeature(Mips::FeatureMips5);
7062 } else if (Tok.getString() == "mips32") {
7063 return parseSetFeature(Mips::FeatureMips32);
7064 } else if (Tok.getString() == "mips32r2") {
7065 return parseSetFeature(Mips::FeatureMips32r2);
7066 } else if (Tok.getString() == "mips32r3") {
7067 return parseSetFeature(Mips::FeatureMips32r3);
7068 } else if (Tok.getString() == "mips32r5") {
7069 return parseSetFeature(Mips::FeatureMips32r5);
7070 } else if (Tok.getString() == "mips32r6") {
7071 return parseSetFeature(Mips::FeatureMips32r6);
7072 } else if (Tok.getString() == "mips64") {
7073 return parseSetFeature(Mips::FeatureMips64);
7074 } else if (Tok.getString() == "mips64r2") {
7075 return parseSetFeature(Mips::FeatureMips64r2);
7076 } else if (Tok.getString() == "mips64r3") {
7077 return parseSetFeature(Mips::FeatureMips64r3);
7078 } else if (Tok.getString() == "mips64r5") {
7079 return parseSetFeature(Mips::FeatureMips64r5);
7080 } else if (Tok.getString() == "mips64r6") {
7081 return parseSetFeature(Mips::FeatureMips64r6);
7082 } else if (Tok.getString() == "dsp") {
7083 return parseSetFeature(Mips::FeatureDSP);
7084 } else if (Tok.getString() == "nodsp") {
7085 return parseSetNoDspDirective();
7086 } else if (Tok.getString() == "msa") {
7087 return parseSetMsaDirective();
7088 } else if (Tok.getString() == "nomsa") {
7089 return parseSetNoMsaDirective();
7090 } else if (Tok.getString() == "mt") {
7091 return parseSetMtDirective();
7092 } else if (Tok.getString() == "nomt") {
7093 return parseSetNoMtDirective();
7094 } else if (Tok.getString() == "softfloat") {
7095 return parseSetSoftFloatDirective();
7096 } else if (Tok.getString() == "hardfloat") {
7097 return parseSetHardFloatDirective();
7099 // It is just an identifier, look for an assignment.
7100 parseSetAssignment();
7107 /// parseDataDirective
7108 /// ::= .word [ expression (, expression)* ]
7109 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
7110 MCAsmParser &Parser = getParser();
7111 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7113 const MCExpr *Value;
7114 if (getParser().parseExpression(Value))
7117 getParser().getStreamer().EmitValue(Value, Size);
7119 if (getLexer().is(AsmToken::EndOfStatement))
7122 if (getLexer().isNot(AsmToken::Comma))
7123 return Error(L, "unexpected token, expected comma");
7132 /// parseDirectiveGpWord
7133 /// ::= .gpword local_sym
7134 bool MipsAsmParser::parseDirectiveGpWord() {
7135 MCAsmParser &Parser = getParser();
7136 const MCExpr *Value;
7137 // EmitGPRel32Value requires an expression, so we are using base class
7138 // method to evaluate the expression.
7139 if (getParser().parseExpression(Value))
7141 getParser().getStreamer().EmitGPRel32Value(Value);
7143 if (getLexer().isNot(AsmToken::EndOfStatement))
7144 return Error(getLexer().getLoc(),
7145 "unexpected token, expected end of statement");
7146 Parser.Lex(); // Eat EndOfStatement token.
7150 /// parseDirectiveGpDWord
7151 /// ::= .gpdword local_sym
7152 bool MipsAsmParser::parseDirectiveGpDWord() {
7153 MCAsmParser &Parser = getParser();
7154 const MCExpr *Value;
7155 // EmitGPRel64Value requires an expression, so we are using base class
7156 // method to evaluate the expression.
7157 if (getParser().parseExpression(Value))
7159 getParser().getStreamer().EmitGPRel64Value(Value);
7161 if (getLexer().isNot(AsmToken::EndOfStatement))
7162 return Error(getLexer().getLoc(),
7163 "unexpected token, expected end of statement");
7164 Parser.Lex(); // Eat EndOfStatement token.
7168 /// parseDirectiveDtpRelWord
7169 /// ::= .dtprelword tls_sym
7170 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7171 MCAsmParser &Parser = getParser();
7172 const MCExpr *Value;
7173 // EmitDTPRel32Value requires an expression, so we are using base class
7174 // method to evaluate the expression.
7175 if (getParser().parseExpression(Value))
7177 getParser().getStreamer().EmitDTPRel32Value(Value);
7179 if (getLexer().isNot(AsmToken::EndOfStatement))
7180 return Error(getLexer().getLoc(),
7181 "unexpected token, expected end of statement");
7182 Parser.Lex(); // Eat EndOfStatement token.
7186 /// parseDirectiveDtpRelDWord
7187 /// ::= .dtpreldword tls_sym
7188 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7189 MCAsmParser &Parser = getParser();
7190 const MCExpr *Value;
7191 // EmitDTPRel64Value requires an expression, so we are using base class
7192 // method to evaluate the expression.
7193 if (getParser().parseExpression(Value))
7195 getParser().getStreamer().EmitDTPRel64Value(Value);
7197 if (getLexer().isNot(AsmToken::EndOfStatement))
7198 return Error(getLexer().getLoc(),
7199 "unexpected token, expected end of statement");
7200 Parser.Lex(); // Eat EndOfStatement token.
7204 /// parseDirectiveTpRelWord
7205 /// ::= .tprelword tls_sym
7206 bool MipsAsmParser::parseDirectiveTpRelWord() {
7207 MCAsmParser &Parser = getParser();
7208 const MCExpr *Value;
7209 // EmitTPRel32Value requires an expression, so we are using base class
7210 // method to evaluate the expression.
7211 if (getParser().parseExpression(Value))
7213 getParser().getStreamer().EmitTPRel32Value(Value);
7215 if (getLexer().isNot(AsmToken::EndOfStatement))
7216 return Error(getLexer().getLoc(),
7217 "unexpected token, expected end of statement");
7218 Parser.Lex(); // Eat EndOfStatement token.
7222 /// parseDirectiveTpRelDWord
7223 /// ::= .tpreldword tls_sym
7224 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7225 MCAsmParser &Parser = getParser();
7226 const MCExpr *Value;
7227 // EmitTPRel64Value requires an expression, so we are using base class
7228 // method to evaluate the expression.
7229 if (getParser().parseExpression(Value))
7231 getParser().getStreamer().EmitTPRel64Value(Value);
7233 if (getLexer().isNot(AsmToken::EndOfStatement))
7234 return Error(getLexer().getLoc(),
7235 "unexpected token, expected end of statement");
7236 Parser.Lex(); // Eat EndOfStatement token.
7240 bool MipsAsmParser::parseDirectiveOption() {
7241 MCAsmParser &Parser = getParser();
7242 // Get the option token.
7243 AsmToken Tok = Parser.getTok();
7244 // At the moment only identifiers are supported.
7245 if (Tok.isNot(AsmToken::Identifier)) {
7246 return Error(Parser.getTok().getLoc(),
7247 "unexpected token, expected identifier");
7250 StringRef Option = Tok.getIdentifier();
7252 if (Option == "pic0") {
7253 // MipsAsmParser needs to know if the current PIC mode changes.
7254 IsPicEnabled = false;
7256 getTargetStreamer().emitDirectiveOptionPic0();
7258 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7259 return Error(Parser.getTok().getLoc(),
7260 "unexpected token, expected end of statement");
7265 if (Option == "pic2") {
7266 // MipsAsmParser needs to know if the current PIC mode changes.
7267 IsPicEnabled = true;
7269 getTargetStreamer().emitDirectiveOptionPic2();
7271 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7272 return Error(Parser.getTok().getLoc(),
7273 "unexpected token, expected end of statement");
7279 Warning(Parser.getTok().getLoc(),
7280 "unknown option, expected 'pic0' or 'pic2'");
7281 Parser.eatToEndOfStatement();
7285 /// parseInsnDirective
7287 bool MipsAsmParser::parseInsnDirective() {
7288 // If this is not the end of the statement, report an error.
7289 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7290 reportParseError("unexpected token, expected end of statement");
7294 // The actual label marking happens in
7295 // MipsELFStreamer::createPendingLabelRelocs().
7296 getTargetStreamer().emitDirectiveInsn();
7298 getParser().Lex(); // Eat EndOfStatement token.
7302 /// parseRSectionDirective
7304 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7305 // If this is not the end of the statement, report an error.
7306 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7307 reportParseError("unexpected token, expected end of statement");
7311 MCSection *ELFSection = getContext().getELFSection(
7312 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7313 getParser().getStreamer().SwitchSection(ELFSection);
7315 getParser().Lex(); // Eat EndOfStatement token.
7319 /// parseSSectionDirective
7322 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7323 // If this is not the end of the statement, report an error.
7324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7325 reportParseError("unexpected token, expected end of statement");
7329 MCSection *ELFSection = getContext().getELFSection(
7330 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7331 getParser().getStreamer().SwitchSection(ELFSection);
7333 getParser().Lex(); // Eat EndOfStatement token.
7337 /// parseDirectiveModule
7338 /// ::= .module oddspreg
7339 /// ::= .module nooddspreg
7340 /// ::= .module fp=value
7341 /// ::= .module softfloat
7342 /// ::= .module hardfloat
7344 bool MipsAsmParser::parseDirectiveModule() {
7345 MCAsmParser &Parser = getParser();
7346 MCAsmLexer &Lexer = getLexer();
7347 SMLoc L = Lexer.getLoc();
7349 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7350 // TODO : get a better message.
7351 reportParseError(".module directive must appear before any code");
7356 if (Parser.parseIdentifier(Option)) {
7357 reportParseError("expected .module option identifier");
7361 if (Option == "oddspreg") {
7362 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7364 // Synchronize the abiflags information with the FeatureBits information we
7366 getTargetStreamer().updateABIInfo(*this);
7368 // If printing assembly, use the recently updated abiflags information.
7369 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7370 // emitted at the end).
7371 getTargetStreamer().emitDirectiveModuleOddSPReg();
7373 // If this is not the end of the statement, report an error.
7374 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7375 reportParseError("unexpected token, expected end of statement");
7379 return false; // parseDirectiveModule has finished successfully.
7380 } else if (Option == "nooddspreg") {
7382 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7385 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7387 // Synchronize the abiflags information with the FeatureBits information we
7389 getTargetStreamer().updateABIInfo(*this);
7391 // If printing assembly, use the recently updated abiflags information.
7392 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7393 // emitted at the end).
7394 getTargetStreamer().emitDirectiveModuleOddSPReg();
7396 // If this is not the end of the statement, report an error.
7397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7398 reportParseError("unexpected token, expected end of statement");
7402 return false; // parseDirectiveModule has finished successfully.
7403 } else if (Option == "fp") {
7404 return parseDirectiveModuleFP();
7405 } else if (Option == "softfloat") {
7406 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7408 // Synchronize the ABI Flags information with the FeatureBits information we
7410 getTargetStreamer().updateABIInfo(*this);
7412 // If printing assembly, use the recently updated ABI Flags information.
7413 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7415 getTargetStreamer().emitDirectiveModuleSoftFloat();
7417 // If this is not the end of the statement, report an error.
7418 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7419 reportParseError("unexpected token, expected end of statement");
7423 return false; // parseDirectiveModule has finished successfully.
7424 } else if (Option == "hardfloat") {
7425 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7427 // Synchronize the ABI Flags information with the FeatureBits information we
7429 getTargetStreamer().updateABIInfo(*this);
7431 // If printing assembly, use the recently updated ABI Flags information.
7432 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7434 getTargetStreamer().emitDirectiveModuleHardFloat();
7436 // If this is not the end of the statement, report an error.
7437 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7438 reportParseError("unexpected token, expected end of statement");
7442 return false; // parseDirectiveModule has finished successfully.
7443 } else if (Option == "mt") {
7444 setModuleFeatureBits(Mips::FeatureMT, "mt");
7446 // Synchronize the ABI Flags information with the FeatureBits information we
7448 getTargetStreamer().updateABIInfo(*this);
7450 // If printing assembly, use the recently updated ABI Flags information.
7451 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7453 getTargetStreamer().emitDirectiveModuleMT();
7455 // If this is not the end of the statement, report an error.
7456 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7457 reportParseError("unexpected token, expected end of statement");
7461 return false; // parseDirectiveModule has finished successfully.
7463 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7467 /// parseDirectiveModuleFP
7471 bool MipsAsmParser::parseDirectiveModuleFP() {
7472 MCAsmParser &Parser = getParser();
7473 MCAsmLexer &Lexer = getLexer();
7475 if (Lexer.isNot(AsmToken::Equal)) {
7476 reportParseError("unexpected token, expected equals sign '='");
7479 Parser.Lex(); // Eat '=' token.
7481 MipsABIFlagsSection::FpABIKind FpABI;
7482 if (!parseFpABIValue(FpABI, ".module"))
7485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7486 reportParseError("unexpected token, expected end of statement");
7490 // Synchronize the abiflags information with the FeatureBits information we
7492 getTargetStreamer().updateABIInfo(*this);
7494 // If printing assembly, use the recently updated abiflags information.
7495 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7496 // emitted at the end).
7497 getTargetStreamer().emitDirectiveModuleFP();
7499 Parser.Lex(); // Consume the EndOfStatement.
7503 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7504 StringRef Directive) {
7505 MCAsmParser &Parser = getParser();
7506 MCAsmLexer &Lexer = getLexer();
7507 bool ModuleLevelOptions = Directive == ".module";
7509 if (Lexer.is(AsmToken::Identifier)) {
7510 StringRef Value = Parser.getTok().getString();
7513 if (Value != "xx") {
7514 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7519 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7523 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7524 if (ModuleLevelOptions) {
7525 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7526 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7528 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7529 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7534 if (Lexer.is(AsmToken::Integer)) {
7535 unsigned Value = Parser.getTok().getIntVal();
7538 if (Value != 32 && Value != 64) {
7539 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7545 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7549 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7550 if (ModuleLevelOptions) {
7551 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7552 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7554 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7555 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7558 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7559 if (ModuleLevelOptions) {
7560 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7561 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7563 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7564 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7574 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7575 // This returns false if this function recognizes the directive
7576 // regardless of whether it is successfully handles or reports an
7577 // error. Otherwise it returns true to give the generic parser a
7578 // chance at recognizing it.
7580 MCAsmParser &Parser = getParser();
7581 StringRef IDVal = DirectiveID.getString();
7583 if (IDVal == ".cpload") {
7584 parseDirectiveCpLoad(DirectiveID.getLoc());
7587 if (IDVal == ".cprestore") {
7588 parseDirectiveCpRestore(DirectiveID.getLoc());
7591 if (IDVal == ".dword") {
7592 parseDataDirective(8, DirectiveID.getLoc());
7595 if (IDVal == ".ent") {
7596 StringRef SymbolName;
7598 if (Parser.parseIdentifier(SymbolName)) {
7599 reportParseError("expected identifier after .ent");
7603 // There's an undocumented extension that allows an integer to
7604 // follow the name of the procedure which AFAICS is ignored by GAS.
7605 // Example: .ent foo,2
7606 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7607 if (getLexer().isNot(AsmToken::Comma)) {
7608 // Even though we accept this undocumented extension for compatibility
7609 // reasons, the additional integer argument does not actually change
7610 // the behaviour of the '.ent' directive, so we would like to discourage
7611 // its use. We do this by not referring to the extended version in
7612 // error messages which are not directly related to its use.
7613 reportParseError("unexpected token, expected end of statement");
7616 Parser.Lex(); // Eat the comma.
7617 const MCExpr *DummyNumber;
7618 int64_t DummyNumberVal;
7619 // If the user was explicitly trying to use the extended version,
7620 // we still give helpful extension-related error messages.
7621 if (Parser.parseExpression(DummyNumber)) {
7622 reportParseError("expected number after comma");
7625 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7626 reportParseError("expected an absolute expression after comma");
7631 // If this is not the end of the statement, report an error.
7632 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7633 reportParseError("unexpected token, expected end of statement");
7637 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7639 getTargetStreamer().emitDirectiveEnt(*Sym);
7641 IsCpRestoreSet = false;
7645 if (IDVal == ".end") {
7646 StringRef SymbolName;
7648 if (Parser.parseIdentifier(SymbolName)) {
7649 reportParseError("expected identifier after .end");
7653 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7654 reportParseError("unexpected token, expected end of statement");
7658 if (CurrentFn == nullptr) {
7659 reportParseError(".end used without .ent");
7663 if ((SymbolName != CurrentFn->getName())) {
7664 reportParseError(".end symbol does not match .ent symbol");
7668 getTargetStreamer().emitDirectiveEnd(SymbolName);
7669 CurrentFn = nullptr;
7670 IsCpRestoreSet = false;
7674 if (IDVal == ".frame") {
7675 // .frame $stack_reg, frame_size_in_bytes, $return_reg
7676 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7677 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7678 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7679 reportParseError("expected stack register");
7683 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7684 if (!StackRegOpnd.isGPRAsmReg()) {
7685 reportParseError(StackRegOpnd.getStartLoc(),
7686 "expected general purpose register");
7689 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7691 if (Parser.getTok().is(AsmToken::Comma))
7694 reportParseError("unexpected token, expected comma");
7698 // Parse the frame size.
7699 const MCExpr *FrameSize;
7700 int64_t FrameSizeVal;
7702 if (Parser.parseExpression(FrameSize)) {
7703 reportParseError("expected frame size value");
7707 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
7708 reportParseError("frame size not an absolute expression");
7712 if (Parser.getTok().is(AsmToken::Comma))
7715 reportParseError("unexpected token, expected comma");
7719 // Parse the return register.
7721 ResTy = parseAnyRegister(TmpReg);
7722 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7723 reportParseError("expected return register");
7727 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7728 if (!ReturnRegOpnd.isGPRAsmReg()) {
7729 reportParseError(ReturnRegOpnd.getStartLoc(),
7730 "expected general purpose register");
7734 // If this is not the end of the statement, report an error.
7735 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7736 reportParseError("unexpected token, expected end of statement");
7740 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
7741 ReturnRegOpnd.getGPR32Reg());
7742 IsCpRestoreSet = false;
7746 if (IDVal == ".set") {
7747 parseDirectiveSet();
7751 if (IDVal == ".mask" || IDVal == ".fmask") {
7752 // .mask bitmask, frame_offset
7753 // bitmask: One bit for each register used.
7754 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
7755 // first register is expected to be saved.
7757 // .mask 0x80000000, -4
7758 // .fmask 0x80000000, -4
7761 // Parse the bitmask
7762 const MCExpr *BitMask;
7765 if (Parser.parseExpression(BitMask)) {
7766 reportParseError("expected bitmask value");
7770 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
7771 reportParseError("bitmask not an absolute expression");
7775 if (Parser.getTok().is(AsmToken::Comma))
7778 reportParseError("unexpected token, expected comma");
7782 // Parse the frame_offset
7783 const MCExpr *FrameOffset;
7784 int64_t FrameOffsetVal;
7786 if (Parser.parseExpression(FrameOffset)) {
7787 reportParseError("expected frame offset value");
7791 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
7792 reportParseError("frame offset not an absolute expression");
7796 // If this is not the end of the statement, report an error.
7797 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7798 reportParseError("unexpected token, expected end of statement");
7802 if (IDVal == ".mask")
7803 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
7805 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
7809 if (IDVal == ".nan")
7810 return parseDirectiveNaN();
7812 if (IDVal == ".gpword") {
7813 parseDirectiveGpWord();
7817 if (IDVal == ".gpdword") {
7818 parseDirectiveGpDWord();
7822 if (IDVal == ".dtprelword") {
7823 parseDirectiveDtpRelWord();
7827 if (IDVal == ".dtpreldword") {
7828 parseDirectiveDtpRelDWord();
7832 if (IDVal == ".tprelword") {
7833 parseDirectiveTpRelWord();
7837 if (IDVal == ".tpreldword") {
7838 parseDirectiveTpRelDWord();
7842 if (IDVal == ".word") {
7843 parseDataDirective(4, DirectiveID.getLoc());
7847 if (IDVal == ".hword") {
7848 parseDataDirective(2, DirectiveID.getLoc());
7852 if (IDVal == ".option") {
7853 parseDirectiveOption();
7857 if (IDVal == ".abicalls") {
7858 getTargetStreamer().emitDirectiveAbiCalls();
7859 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7860 Error(Parser.getTok().getLoc(),
7861 "unexpected token, expected end of statement");
7866 if (IDVal == ".cpsetup") {
7867 parseDirectiveCPSetup();
7870 if (IDVal == ".cpreturn") {
7871 parseDirectiveCPReturn();
7874 if (IDVal == ".module") {
7875 parseDirectiveModule();
7878 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
7879 parseInternalDirectiveReallowModule();
7882 if (IDVal == ".insn") {
7883 parseInsnDirective();
7886 if (IDVal == ".rdata") {
7887 parseRSectionDirective(".rodata");
7890 if (IDVal == ".sbss") {
7891 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
7894 if (IDVal == ".sdata") {
7895 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
7902 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
7903 // If this is not the end of the statement, report an error.
7904 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7905 reportParseError("unexpected token, expected end of statement");
7909 getTargetStreamer().reallowModuleDirective();
7911 getParser().Lex(); // Eat EndOfStatement token.
7915 extern "C" void LLVMInitializeMipsAsmParser() {
7916 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
7917 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
7918 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
7919 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
7922 #define GET_REGISTER_MATCHER
7923 #define GET_MATCHER_IMPLEMENTATION
7924 #include "MipsGenAsmMatcher.inc"
7926 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
7927 // Find the appropriate table for this asm variant.
7928 const MatchEntry *Start, *End;
7929 switch (VariantID) {
7930 default: llvm_unreachable("invalid variant!");
7931 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
7933 // Search the table.
7934 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
7935 return MnemonicRange.first != MnemonicRange.second;