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 Match_RequiresPosSizeRange0_32,
470 Match_RequiresPosSizeRange33_64,
471 Match_RequiresPosSizeUImm6,
472 #define GET_OPERAND_DIAGNOSTIC_TYPES
473 #include "MipsGenAsmMatcher.inc"
474 #undef GET_OPERAND_DIAGNOSTIC_TYPES
477 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
478 const MCInstrInfo &MII, const MCTargetOptions &Options)
479 : MCTargetAsmParser(Options, sti, MII),
480 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
481 sti.getCPU(), Options)) {
482 MCAsmParserExtension::Initialize(parser);
484 parser.addAliasForDirective(".asciiz", ".asciz");
486 // Initialize the set of available features.
487 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
489 // Remember the initial assembler options. The user can not modify these.
490 AssemblerOptions.push_back(
491 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
493 // Create an assembler options environment for the user to modify.
494 AssemblerOptions.push_back(
495 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
497 getTargetStreamer().updateABIInfo(*this);
499 if (!isABI_O32() && !useOddSPReg() != 0)
500 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
504 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
506 IsCpRestoreSet = false;
507 CpRestoreOffset = -1;
509 const Triple &TheTriple = sti.getTargetTriple();
510 if ((TheTriple.getArch() == Triple::mips) ||
511 (TheTriple.getArch() == Triple::mips64))
512 IsLittleEndian = false;
514 IsLittleEndian = true;
516 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
517 report_fatal_error("microMIPS64R6 is not supported", false);
520 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
521 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
523 bool isGP64bit() const {
524 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
527 bool isFP64bit() const {
528 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
531 const MipsABIInfo &getABI() const { return ABI; }
532 bool isABI_N32() const { return ABI.IsN32(); }
533 bool isABI_N64() const { return ABI.IsN64(); }
534 bool isABI_O32() const { return ABI.IsO32(); }
535 bool isABI_FPXX() const {
536 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
539 bool useOddSPReg() const {
540 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
543 bool inMicroMipsMode() const {
544 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
547 bool hasMips1() const {
548 return getSTI().getFeatureBits()[Mips::FeatureMips1];
551 bool hasMips2() const {
552 return getSTI().getFeatureBits()[Mips::FeatureMips2];
555 bool hasMips3() const {
556 return getSTI().getFeatureBits()[Mips::FeatureMips3];
559 bool hasMips4() const {
560 return getSTI().getFeatureBits()[Mips::FeatureMips4];
563 bool hasMips5() const {
564 return getSTI().getFeatureBits()[Mips::FeatureMips5];
567 bool hasMips32() const {
568 return getSTI().getFeatureBits()[Mips::FeatureMips32];
571 bool hasMips64() const {
572 return getSTI().getFeatureBits()[Mips::FeatureMips64];
575 bool hasMips32r2() const {
576 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
579 bool hasMips64r2() const {
580 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
583 bool hasMips32r3() const {
584 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
587 bool hasMips64r3() const {
588 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
591 bool hasMips32r5() const {
592 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
595 bool hasMips64r5() const {
596 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
599 bool hasMips32r6() const {
600 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
603 bool hasMips64r6() const {
604 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
607 bool hasDSP() const {
608 return getSTI().getFeatureBits()[Mips::FeatureDSP];
611 bool hasDSPR2() const {
612 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
615 bool hasDSPR3() const {
616 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
619 bool hasMSA() const {
620 return getSTI().getFeatureBits()[Mips::FeatureMSA];
623 bool hasCnMips() const {
624 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
631 bool inMips16Mode() const {
632 return getSTI().getFeatureBits()[Mips::FeatureMips16];
635 bool useTraps() const {
636 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
639 bool useSoftFloat() const {
640 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
643 return getSTI().getFeatureBits()[Mips::FeatureMT];
646 /// Warn if RegIndex is the same as the current AT.
647 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
649 void warnIfNoMacro(SMLoc Loc);
651 bool isLittle() const { return IsLittleEndian; }
653 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
654 AsmToken::TokenKind OperatorToken,
655 MCContext &Ctx) override {
656 switch(OperatorToken) {
658 llvm_unreachable("Unknown token");
660 case AsmToken::PercentCall16:
661 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
662 case AsmToken::PercentCall_Hi:
663 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
664 case AsmToken::PercentCall_Lo:
665 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
666 case AsmToken::PercentDtprel_Hi:
667 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
668 case AsmToken::PercentDtprel_Lo:
669 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
670 case AsmToken::PercentGot:
671 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
672 case AsmToken::PercentGot_Disp:
673 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
674 case AsmToken::PercentGot_Hi:
675 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
676 case AsmToken::PercentGot_Lo:
677 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
678 case AsmToken::PercentGot_Ofst:
679 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
680 case AsmToken::PercentGot_Page:
681 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
682 case AsmToken::PercentGottprel:
683 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
684 case AsmToken::PercentGp_Rel:
685 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
686 case AsmToken::PercentHi:
687 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
688 case AsmToken::PercentHigher:
689 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
690 case AsmToken::PercentHighest:
691 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
692 case AsmToken::PercentLo:
693 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
694 case AsmToken::PercentNeg:
695 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
696 case AsmToken::PercentPcrel_Hi:
697 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
698 case AsmToken::PercentPcrel_Lo:
699 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
700 case AsmToken::PercentTlsgd:
701 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
702 case AsmToken::PercentTlsldm:
703 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
704 case AsmToken::PercentTprel_Hi:
705 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
706 case AsmToken::PercentTprel_Lo:
707 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
712 /// MipsOperand - Instances of this class represent a parsed Mips machine
714 class MipsOperand : public MCParsedAsmOperand {
716 /// Broad categories of register classes
717 /// The exact class is finalized by the render method.
719 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
720 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
722 RegKind_FCC = 4, /// FCC
723 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
724 RegKind_MSACtrl = 16, /// MSA control registers
725 RegKind_COP2 = 32, /// COP2
726 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
728 RegKind_CCR = 128, /// CCR
729 RegKind_HWRegs = 256, /// HWRegs
730 RegKind_COP3 = 512, /// COP3
731 RegKind_COP0 = 1024, /// COP0
732 /// Potentially any (e.g. $1)
733 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
734 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
735 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
740 k_Immediate, /// An immediate (possibly involving symbol references)
741 k_Memory, /// Base + Offset Memory Address
742 k_RegisterIndex, /// A register index in one or more RegKind.
743 k_Token, /// A simple token
744 k_RegList, /// A physical register list
745 k_RegPair /// A pair of physical register
749 MipsOperand(KindTy K, MipsAsmParser &Parser)
750 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
752 ~MipsOperand() override {
761 case k_RegisterIndex:
769 /// For diagnostics, and checking the assembler temporary
770 MipsAsmParser &AsmParser;
778 unsigned Index; /// Index into the register class
779 RegKind Kind; /// Bitfield of the kinds it could possibly be
780 struct Token Tok; /// The input token this operand originated from.
781 const MCRegisterInfo *RegInfo;
794 SmallVector<unsigned, 10> *List;
799 struct RegIdxOp RegIdx;
802 struct RegListOp RegList;
805 SMLoc StartLoc, EndLoc;
807 /// Internal constructor for register kinds
808 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
810 const MCRegisterInfo *RegInfo,
812 MipsAsmParser &Parser) {
813 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
814 Op->RegIdx.Index = Index;
815 Op->RegIdx.RegInfo = RegInfo;
816 Op->RegIdx.Kind = RegKind;
817 Op->RegIdx.Tok.Data = Str.data();
818 Op->RegIdx.Tok.Length = Str.size();
825 /// Coerce the register to GPR32 and return the real register for the current
827 unsigned getGPR32Reg() const {
828 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
829 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
830 unsigned ClassID = Mips::GPR32RegClassID;
831 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
834 /// Coerce the register to GPR32 and return the real register for the current
836 unsigned getGPRMM16Reg() const {
837 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
838 unsigned ClassID = Mips::GPR32RegClassID;
839 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
842 /// Coerce the register to GPR64 and return the real register for the current
844 unsigned getGPR64Reg() const {
845 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
846 unsigned ClassID = Mips::GPR64RegClassID;
847 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
851 /// Coerce the register to AFGR64 and return the real register for the current
853 unsigned getAFGR64Reg() const {
854 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
855 if (RegIdx.Index % 2 != 0)
856 AsmParser.Warning(StartLoc, "Float register should be even.");
857 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
858 .getRegister(RegIdx.Index / 2);
861 /// Coerce the register to FGR64 and return the real register for the current
863 unsigned getFGR64Reg() const {
864 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
865 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
866 .getRegister(RegIdx.Index);
869 /// Coerce the register to FGR32 and return the real register for the current
871 unsigned getFGR32Reg() const {
872 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
873 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
874 .getRegister(RegIdx.Index);
877 /// Coerce the register to FGRH32 and return the real register for the current
879 unsigned getFGRH32Reg() const {
880 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
881 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
882 .getRegister(RegIdx.Index);
885 /// Coerce the register to FCC and return the real register for the current
887 unsigned getFCCReg() const {
888 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
889 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
890 .getRegister(RegIdx.Index);
893 /// Coerce the register to MSA128 and return the real register for the current
895 unsigned getMSA128Reg() const {
896 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
897 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
899 unsigned ClassID = Mips::MSA128BRegClassID;
900 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
903 /// Coerce the register to MSACtrl and return the real register for the
905 unsigned getMSACtrlReg() const {
906 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
907 unsigned ClassID = Mips::MSACtrlRegClassID;
908 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
911 /// Coerce the register to COP0 and return the real register for the
913 unsigned getCOP0Reg() const {
914 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
915 unsigned ClassID = Mips::COP0RegClassID;
916 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
919 /// Coerce the register to COP2 and return the real register for the
921 unsigned getCOP2Reg() const {
922 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
923 unsigned ClassID = Mips::COP2RegClassID;
924 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
927 /// Coerce the register to COP3 and return the real register for the
929 unsigned getCOP3Reg() const {
930 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
931 unsigned ClassID = Mips::COP3RegClassID;
932 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
935 /// Coerce the register to ACC64DSP and return the real register for the
937 unsigned getACC64DSPReg() const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
939 unsigned ClassID = Mips::ACC64DSPRegClassID;
940 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
943 /// Coerce the register to HI32DSP and return the real register for the
945 unsigned getHI32DSPReg() const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
947 unsigned ClassID = Mips::HI32DSPRegClassID;
948 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
951 /// Coerce the register to LO32DSP and return the real register for the
953 unsigned getLO32DSPReg() const {
954 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
955 unsigned ClassID = Mips::LO32DSPRegClassID;
956 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
959 /// Coerce the register to CCR and return the real register for the
961 unsigned getCCRReg() const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
963 unsigned ClassID = Mips::CCRRegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
967 /// Coerce the register to HWRegs and return the real register for the
969 unsigned getHWRegsReg() const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
971 unsigned ClassID = Mips::HWRegsRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
976 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
977 // Add as immediate when possible. Null MCExpr = 0.
979 Inst.addOperand(MCOperand::createImm(0));
980 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
981 Inst.addOperand(MCOperand::createImm(CE->getValue()));
983 Inst.addOperand(MCOperand::createExpr(Expr));
986 void addRegOperands(MCInst &Inst, unsigned N) const {
987 llvm_unreachable("Use a custom parser instead");
990 /// Render the operand to an MCInst as a GPR32
991 /// Asserts if the wrong number of operands are requested, or the operand
992 /// is not a k_RegisterIndex compatible with RegKind_GPR
993 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
994 assert(N == 1 && "Invalid number of operands!");
995 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
998 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
999 assert(N == 1 && "Invalid number of operands!");
1000 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1003 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1004 assert(N == 1 && "Invalid number of operands!");
1005 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1008 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1009 assert(N == 1 && "Invalid number of operands!");
1010 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1013 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1014 assert(N == 1 && "Invalid number of operands!");
1015 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1018 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1019 assert(N == 1 && "Invalid number of operands!");
1020 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1023 /// Render the operand to an MCInst as a GPR64
1024 /// Asserts if the wrong number of operands are requested, or the operand
1025 /// is not a k_RegisterIndex compatible with RegKind_GPR
1026 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1027 assert(N == 1 && "Invalid number of operands!");
1028 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1031 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1032 assert(N == 1 && "Invalid number of operands!");
1033 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1036 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1037 assert(N == 1 && "Invalid number of operands!");
1038 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1041 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1042 assert(N == 1 && "Invalid number of operands!");
1043 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1046 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1047 assert(N == 1 && "Invalid number of operands!");
1048 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1051 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1052 assert(N == 1 && "Invalid number of operands!");
1053 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1054 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1055 // FIXME: This should propagate failure up to parseStatement.
1056 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1057 AsmParser.getParser().printError(
1058 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1062 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1063 assert(N == 1 && "Invalid number of operands!");
1064 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1065 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1066 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1067 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1071 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1072 assert(N == 1 && "Invalid number of operands!");
1073 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1076 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1077 assert(N == 1 && "Invalid number of operands!");
1078 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1081 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1082 assert(N == 1 && "Invalid number of operands!");
1083 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1086 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1087 assert(N == 1 && "Invalid number of operands!");
1088 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1091 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1096 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1097 assert(N == 1 && "Invalid number of operands!");
1098 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1101 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1102 assert(N == 1 && "Invalid number of operands!");
1103 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1106 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1107 assert(N == 1 && "Invalid number of operands!");
1108 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1111 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1112 assert(N == 1 && "Invalid number of operands!");
1113 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1116 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1117 assert(N == 1 && "Invalid number of operands!");
1118 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1121 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1122 assert(N == 1 && "Invalid number of operands!");
1123 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1126 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1127 assert(N == 1 && "Invalid number of operands!");
1128 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1131 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1132 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1133 assert(N == 1 && "Invalid number of operands!");
1134 uint64_t Imm = getConstantImm() - Offset;
1135 Imm &= (1ULL << Bits) - 1;
1137 Imm += AdjustOffset;
1138 Inst.addOperand(MCOperand::createImm(Imm));
1141 template <unsigned Bits>
1142 void addSImmOperands(MCInst &Inst, unsigned N) const {
1143 if (isImm() && !isConstantImm()) {
1144 addExpr(Inst, getImm());
1147 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1150 template <unsigned Bits>
1151 void addUImmOperands(MCInst &Inst, unsigned N) const {
1152 if (isImm() && !isConstantImm()) {
1153 addExpr(Inst, getImm());
1156 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1159 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1160 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1161 assert(N == 1 && "Invalid number of operands!");
1162 int64_t Imm = getConstantImm() - Offset;
1163 Imm = SignExtend64<Bits>(Imm);
1165 Imm += AdjustOffset;
1166 Inst.addOperand(MCOperand::createImm(Imm));
1169 void addImmOperands(MCInst &Inst, unsigned N) const {
1170 assert(N == 1 && "Invalid number of operands!");
1171 const MCExpr *Expr = getImm();
1172 addExpr(Inst, Expr);
1175 void addMemOperands(MCInst &Inst, unsigned N) const {
1176 assert(N == 2 && "Invalid number of operands!");
1178 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1179 ? getMemBase()->getGPR64Reg()
1180 : getMemBase()->getGPR32Reg()));
1182 const MCExpr *Expr = getMemOff();
1183 addExpr(Inst, Expr);
1186 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1187 assert(N == 2 && "Invalid number of operands!");
1189 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1191 const MCExpr *Expr = getMemOff();
1192 addExpr(Inst, Expr);
1195 void addRegListOperands(MCInst &Inst, unsigned N) const {
1196 assert(N == 1 && "Invalid number of operands!");
1198 for (auto RegNo : getRegList())
1199 Inst.addOperand(MCOperand::createReg(RegNo));
1202 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1203 assert(N == 2 && "Invalid number of operands!");
1204 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1205 unsigned RegNo = getRegPair();
1206 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1207 Inst.addOperand(MCOperand::createReg(
1208 RegIdx.RegInfo->getRegClass(
1209 AsmParser.getABI().AreGprs64bit()
1210 ? Mips::GPR64RegClassID
1211 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1212 Inst.addOperand(MCOperand::createReg(
1213 RegIdx.RegInfo->getRegClass(
1214 AsmParser.getABI().AreGprs64bit()
1215 ? Mips::GPR64RegClassID
1216 : Mips::GPR32RegClassID).getRegister(RegNo)));
1219 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1220 assert(N == 2 && "Invalid number of operands!");
1221 for (auto RegNo : getRegList())
1222 Inst.addOperand(MCOperand::createReg(RegNo));
1225 bool isReg() const override {
1226 // As a special case until we sort out the definition of div/divu, accept
1227 // $0/$zero here so that MCK_ZERO works correctly.
1228 return isGPRAsmReg() && RegIdx.Index == 0;
1231 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1232 bool isImm() const override { return Kind == k_Immediate; }
1234 bool isConstantImm() const {
1236 return isImm() && getImm()->evaluateAsAbsolute(Res);
1239 bool isConstantImmz() const {
1240 return isConstantImm() && getConstantImm() == 0;
1243 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1244 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1247 template <unsigned Bits> bool isSImm() const {
1248 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1251 template <unsigned Bits> bool isUImm() const {
1252 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1255 template <unsigned Bits> bool isAnyImm() const {
1256 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1257 isUInt<Bits>(getConstantImm()))
1261 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1262 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1265 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1266 return isConstantImm() && getConstantImm() >= Bottom &&
1267 getConstantImm() <= Top;
1270 bool isToken() const override {
1271 // Note: It's not possible to pretend that other operand kinds are tokens.
1272 // The matcher emitter checks tokens first.
1273 return Kind == k_Token;
1276 bool isMem() const override { return Kind == k_Memory; }
1278 bool isConstantMemOff() const {
1279 return isMem() && isa<MCConstantExpr>(getMemOff());
1282 // Allow relocation operators.
1283 // FIXME: This predicate and others need to look through binary expressions
1284 // and determine whether a Value is a constant or not.
1285 template <unsigned Bits, unsigned ShiftAmount = 0>
1286 bool isMemWithSimmOffset() const {
1289 if (!getMemBase()->isGPRAsmReg())
1291 if (isa<MCTargetExpr>(getMemOff()) ||
1292 (isConstantMemOff() &&
1293 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1296 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1297 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1300 bool isMemWithGRPMM16Base() const {
1301 return isMem() && getMemBase()->isMM16AsmReg();
1304 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1305 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1306 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1309 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1310 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1311 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1312 && (getMemBase()->getGPR32Reg() == Mips::SP);
1315 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1316 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1317 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1318 && (getMemBase()->getGPR32Reg() == Mips::GP);
1321 template <unsigned Bits, unsigned ShiftLeftAmount>
1322 bool isScaledUImm() const {
1323 return isConstantImm() &&
1324 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1327 template <unsigned Bits, unsigned ShiftLeftAmount>
1328 bool isScaledSImm() const {
1329 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1331 // Operand can also be a symbol or symbol plus offset in case of relocations.
1332 if (Kind != k_Immediate)
1335 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1336 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1339 bool isRegList16() const {
1343 int Size = RegList.List->size();
1344 if (Size < 2 || Size > 5)
1347 unsigned R0 = RegList.List->front();
1348 unsigned R1 = RegList.List->back();
1349 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1350 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1353 int PrevReg = *RegList.List->begin();
1354 for (int i = 1; i < Size - 1; i++) {
1355 int Reg = (*(RegList.List))[i];
1356 if ( Reg != PrevReg + 1)
1364 bool isInvNum() const { return Kind == k_Immediate; }
1366 bool isLSAImm() const {
1367 if (!isConstantImm())
1369 int64_t Val = getConstantImm();
1370 return 1 <= Val && Val <= 4;
1373 bool isRegList() const { return Kind == k_RegList; }
1375 bool isMovePRegPair() const {
1376 if (Kind != k_RegList || RegList.List->size() != 2)
1379 unsigned R0 = RegList.List->front();
1380 unsigned R1 = RegList.List->back();
1382 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1383 (R0 == Mips::A1 && R1 == Mips::A3) ||
1384 (R0 == Mips::A2 && R1 == Mips::A3) ||
1385 (R0 == Mips::A0 && R1 == Mips::S5) ||
1386 (R0 == Mips::A0 && R1 == Mips::S6) ||
1387 (R0 == Mips::A0 && R1 == Mips::A1) ||
1388 (R0 == Mips::A0 && R1 == Mips::A2) ||
1389 (R0 == Mips::A0 && R1 == Mips::A3) ||
1390 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1391 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1392 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1393 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1394 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1395 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1396 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1397 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1403 StringRef getToken() const {
1404 assert(Kind == k_Token && "Invalid access!");
1405 return StringRef(Tok.Data, Tok.Length);
1408 bool isRegPair() const {
1409 return Kind == k_RegPair && RegIdx.Index <= 30;
1412 unsigned getReg() const override {
1413 // As a special case until we sort out the definition of div/divu, accept
1414 // $0/$zero here so that MCK_ZERO works correctly.
1415 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1416 RegIdx.Kind & RegKind_GPR)
1417 return getGPR32Reg(); // FIXME: GPR64 too
1419 llvm_unreachable("Invalid access!");
1423 const MCExpr *getImm() const {
1424 assert((Kind == k_Immediate) && "Invalid access!");
1428 int64_t getConstantImm() const {
1429 const MCExpr *Val = getImm();
1431 (void)Val->evaluateAsAbsolute(Value);
1435 MipsOperand *getMemBase() const {
1436 assert((Kind == k_Memory) && "Invalid access!");
1440 const MCExpr *getMemOff() const {
1441 assert((Kind == k_Memory) && "Invalid access!");
1445 int64_t getConstantMemOff() const {
1446 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1449 const SmallVectorImpl<unsigned> &getRegList() const {
1450 assert((Kind == k_RegList) && "Invalid access!");
1451 return *(RegList.List);
1454 unsigned getRegPair() const {
1455 assert((Kind == k_RegPair) && "Invalid access!");
1456 return RegIdx.Index;
1459 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1460 MipsAsmParser &Parser) {
1461 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1462 Op->Tok.Data = Str.data();
1463 Op->Tok.Length = Str.size();
1469 /// Create a numeric register (e.g. $1). The exact register remains
1470 /// unresolved until an instruction successfully matches
1471 static std::unique_ptr<MipsOperand>
1472 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1473 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1474 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1475 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1478 /// Create a register that is definitely a GPR.
1479 /// This is typically only used for named registers such as $gp.
1480 static std::unique_ptr<MipsOperand>
1481 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1482 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1483 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1486 /// Create a register that is definitely a FGR.
1487 /// This is typically only used for named registers such as $f0.
1488 static std::unique_ptr<MipsOperand>
1489 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1490 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1491 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1494 /// Create a register that is definitely a HWReg.
1495 /// This is typically only used for named registers such as $hwr_cpunum.
1496 static std::unique_ptr<MipsOperand>
1497 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1498 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1499 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1502 /// Create a register that is definitely an FCC.
1503 /// This is typically only used for named registers such as $fcc0.
1504 static std::unique_ptr<MipsOperand>
1505 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1506 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1507 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1510 /// Create a register that is definitely an ACC.
1511 /// This is typically only used for named registers such as $ac0.
1512 static std::unique_ptr<MipsOperand>
1513 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1514 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1515 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1518 /// Create a register that is definitely an MSA128.
1519 /// This is typically only used for named registers such as $w0.
1520 static std::unique_ptr<MipsOperand>
1521 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1522 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1523 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1526 /// Create a register that is definitely an MSACtrl.
1527 /// This is typically only used for named registers such as $msaaccess.
1528 static std::unique_ptr<MipsOperand>
1529 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1530 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1531 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1534 static std::unique_ptr<MipsOperand>
1535 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1536 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1543 static std::unique_ptr<MipsOperand>
1544 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1545 SMLoc E, MipsAsmParser &Parser) {
1546 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1547 Op->Mem.Base = Base.release();
1554 static std::unique_ptr<MipsOperand>
1555 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1556 MipsAsmParser &Parser) {
1557 assert(Regs.size() > 0 && "Empty list not allowed");
1559 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1560 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1561 Op->StartLoc = StartLoc;
1562 Op->EndLoc = EndLoc;
1566 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1568 MipsAsmParser &Parser) {
1569 auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
1570 Op->RegIdx.Index = MOP.RegIdx.Index;
1571 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1572 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1578 bool isGPRZeroAsmReg() const {
1579 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1582 bool isGPRNonZeroAsmReg() const {
1583 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1587 bool isGPRAsmReg() const {
1588 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1591 bool isMM16AsmReg() const {
1592 if (!(isRegIdx() && RegIdx.Kind))
1594 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1595 || RegIdx.Index == 16 || RegIdx.Index == 17);
1598 bool isMM16AsmRegZero() const {
1599 if (!(isRegIdx() && RegIdx.Kind))
1601 return (RegIdx.Index == 0 ||
1602 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1603 RegIdx.Index == 17);
1606 bool isMM16AsmRegMoveP() const {
1607 if (!(isRegIdx() && RegIdx.Kind))
1609 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1610 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1613 bool isFGRAsmReg() const {
1614 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1615 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1618 bool isStrictlyFGRAsmReg() const {
1619 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1620 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1623 bool isHWRegsAsmReg() const {
1624 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1627 bool isCCRAsmReg() const {
1628 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1631 bool isFCCAsmReg() const {
1632 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1634 return RegIdx.Index <= 7;
1637 bool isACCAsmReg() const {
1638 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1641 bool isCOP0AsmReg() const {
1642 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1645 bool isCOP2AsmReg() const {
1646 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1649 bool isCOP3AsmReg() const {
1650 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1653 bool isMSA128AsmReg() const {
1654 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1657 bool isMSACtrlAsmReg() const {
1658 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1661 /// getStartLoc - Get the location of the first token of this operand.
1662 SMLoc getStartLoc() const override { return StartLoc; }
1663 /// getEndLoc - Get the location of the last token of this operand.
1664 SMLoc getEndLoc() const override { return EndLoc; }
1666 void print(raw_ostream &OS) const override {
1675 Mem.Base->print(OS);
1680 case k_RegisterIndex:
1681 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1682 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1689 for (auto Reg : (*RegList.List))
1694 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1699 bool isValidForTie(const MipsOperand &Other) const {
1700 if (Kind != Other.Kind)
1705 llvm_unreachable("Unexpected kind");
1707 case k_RegisterIndex: {
1708 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1709 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1710 return Token == OtherToken;
1714 }; // class MipsOperand
1716 } // end anonymous namespace
1720 extern const MCInstrDesc MipsInsts[];
1722 } // end namespace llvm
1724 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1725 return MipsInsts[Opcode];
1728 static bool hasShortDelaySlot(unsigned Opcode) {
1731 case Mips::JALRS_MM:
1732 case Mips::JALRS16_MM:
1733 case Mips::BGEZALS_MM:
1734 case Mips::BLTZALS_MM:
1741 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1742 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1743 return &SRExpr->getSymbol();
1746 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1747 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1748 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1759 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1760 return getSingleMCSymbol(UExpr->getSubExpr());
1765 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1766 if (isa<MCSymbolRefExpr>(Expr))
1769 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1770 return countMCSymbolRefExpr(BExpr->getLHS()) +
1771 countMCSymbolRefExpr(BExpr->getRHS());
1773 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1774 return countMCSymbolRefExpr(UExpr->getSubExpr());
1779 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1781 const MCSubtargetInfo *STI) {
1782 MipsTargetStreamer &TOut = getTargetStreamer();
1783 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1784 bool ExpandedJalSym = false;
1788 if (MCID.isBranch() || MCID.isCall()) {
1789 const unsigned Opcode = Inst.getOpcode();
1799 assert(hasCnMips() && "instruction only valid for octeon cpus");
1806 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1807 Offset = Inst.getOperand(2);
1808 if (!Offset.isImm())
1809 break; // We'll deal with this situation later on when applying fixups.
1810 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1811 return Error(IDLoc, "branch target out of range");
1812 if (OffsetToAlignment(Offset.getImm(),
1813 1LL << (inMicroMipsMode() ? 1 : 2)))
1814 return Error(IDLoc, "branch to misaligned address");
1828 case Mips::BGEZAL_MM:
1829 case Mips::BLTZAL_MM:
1832 case Mips::BC1EQZC_MMR6:
1833 case Mips::BC1NEZC_MMR6:
1834 case Mips::BC2EQZC_MMR6:
1835 case Mips::BC2NEZC_MMR6:
1836 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1837 Offset = Inst.getOperand(1);
1838 if (!Offset.isImm())
1839 break; // We'll deal with this situation later on when applying fixups.
1840 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1841 return Error(IDLoc, "branch target out of range");
1842 if (OffsetToAlignment(Offset.getImm(),
1843 1LL << (inMicroMipsMode() ? 1 : 2)))
1844 return Error(IDLoc, "branch to misaligned address");
1846 case Mips::BGEC: case Mips::BGEC_MMR6:
1847 case Mips::BLTC: case Mips::BLTC_MMR6:
1848 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1849 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1850 case Mips::BEQC: case Mips::BEQC_MMR6:
1851 case Mips::BNEC: case Mips::BNEC_MMR6:
1852 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1853 Offset = Inst.getOperand(2);
1854 if (!Offset.isImm())
1855 break; // We'll deal with this situation later on when applying fixups.
1856 if (!isIntN(18, Offset.getImm()))
1857 return Error(IDLoc, "branch target out of range");
1858 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1859 return Error(IDLoc, "branch to misaligned address");
1861 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1862 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1863 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1864 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1865 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1866 Offset = Inst.getOperand(1);
1867 if (!Offset.isImm())
1868 break; // We'll deal with this situation later on when applying fixups.
1869 if (!isIntN(18, Offset.getImm()))
1870 return Error(IDLoc, "branch target out of range");
1871 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1872 return Error(IDLoc, "branch to misaligned address");
1874 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1875 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1876 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1877 Offset = Inst.getOperand(1);
1878 if (!Offset.isImm())
1879 break; // We'll deal with this situation later on when applying fixups.
1880 if (!isIntN(23, Offset.getImm()))
1881 return Error(IDLoc, "branch target out of range");
1882 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1883 return Error(IDLoc, "branch to misaligned address");
1885 case Mips::BEQZ16_MM:
1886 case Mips::BEQZC16_MMR6:
1887 case Mips::BNEZ16_MM:
1888 case Mips::BNEZC16_MMR6:
1889 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1890 Offset = Inst.getOperand(1);
1891 if (!Offset.isImm())
1892 break; // We'll deal with this situation later on when applying fixups.
1893 if (!isInt<8>(Offset.getImm()))
1894 return Error(IDLoc, "branch target out of range");
1895 if (OffsetToAlignment(Offset.getImm(), 2LL))
1896 return Error(IDLoc, "branch to misaligned address");
1901 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1902 // We still accept it but it is a normal nop.
1903 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1904 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1905 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1910 const unsigned Opcode = Inst.getOpcode();
1922 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1923 // The offset is handled above
1924 Opnd = Inst.getOperand(1);
1926 return Error(IDLoc, "expected immediate operand kind");
1927 Imm = Opnd.getImm();
1928 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1929 Opcode == Mips::BBIT1 ? 63 : 31))
1930 return Error(IDLoc, "immediate operand value out of range");
1932 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1934 Inst.getOperand(1).setImm(Imm - 32);
1940 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1941 Opnd = Inst.getOperand(2);
1943 return Error(IDLoc, "expected immediate operand kind");
1944 Imm = Opnd.getImm();
1945 if (!isInt<10>(Imm))
1946 return Error(IDLoc, "immediate operand value out of range");
1951 // Warn on division by zero. We're checking here as all instructions get
1952 // processed here, not just the macros that need expansion.
1954 // The MIPS backend models most of the divison instructions and macros as
1955 // three operand instructions. The pre-R6 divide instructions however have
1956 // two operands and explicitly define HI/LO as part of the instruction,
1957 // not in the operands.
1958 unsigned FirstOp = 1;
1959 unsigned SecondOp = 2;
1960 switch (Inst.getOpcode()) {
1963 case Mips::SDivIMacro:
1964 case Mips::UDivIMacro:
1965 case Mips::DSDivIMacro:
1966 case Mips::DUDivIMacro:
1967 if (Inst.getOperand(2).getImm() == 0) {
1968 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1969 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1970 Warning(IDLoc, "dividing zero by zero");
1972 Warning(IDLoc, "division by zero");
1984 case Mips::SDivMacro:
1985 case Mips::DSDivMacro:
1986 case Mips::UDivMacro:
1987 case Mips::DUDivMacro:
1992 case Mips::DIVU_MMR6:
1993 case Mips::DIV_MMR6:
1994 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1995 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1996 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1997 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1998 Warning(IDLoc, "dividing zero by zero");
2000 Warning(IDLoc, "division by zero");
2005 // For PIC code convert unconditional jump to unconditional branch.
2006 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2009 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2010 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2011 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2012 BInst.addOperand(Inst.getOperand(0));
2016 // This expansion is not in a function called by tryExpandInstruction()
2017 // because the pseudo-instruction doesn't have a distinct opcode.
2018 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2020 warnIfNoMacro(IDLoc);
2022 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2024 // We can do this expansion if there's only 1 symbol in the argument
2026 if (countMCSymbolRefExpr(JalExpr) > 1)
2027 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2029 // FIXME: This is checking the expression can be handled by the later stages
2030 // of the assembler. We ought to leave it to those later stages.
2031 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2033 // FIXME: Add support for label+offset operands (currently causes an error).
2034 // FIXME: Add support for forward-declared local symbols.
2035 // FIXME: Add expansion for when the LargeGOT option is enabled.
2036 if (JalSym->isInSection() || JalSym->isTemporary() ||
2037 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2039 // If it's a local symbol and the O32 ABI is being used, we expand to:
2041 // R_(MICRO)MIPS_GOT16 label
2042 // addiu $25, $25, 0
2043 // R_(MICRO)MIPS_LO16 label
2045 const MCExpr *Got16RelocExpr =
2046 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2047 const MCExpr *Lo16RelocExpr =
2048 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2050 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2051 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2052 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2053 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2054 } else if (isABI_N32() || isABI_N64()) {
2055 // If it's a local symbol and the N32/N64 ABIs are being used,
2057 // lw/ld $25, 0($gp)
2058 // R_(MICRO)MIPS_GOT_DISP label
2060 const MCExpr *GotDispRelocExpr =
2061 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2063 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2064 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2068 // If it's an external/weak symbol, we expand to:
2069 // lw/ld $25, 0($gp)
2070 // R_(MICRO)MIPS_CALL16 label
2072 const MCExpr *Call16RelocExpr =
2073 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2075 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2076 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2080 if (IsCpRestoreSet && inMicroMipsMode())
2081 JalrInst.setOpcode(Mips::JALRS_MM);
2083 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2084 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2085 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2087 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
2088 // This relocation is supposed to be an optimization hint for the linker
2089 // and is not necessary for correctness.
2092 ExpandedJalSym = true;
2095 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2096 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2097 // Check the offset of memory operand, if it is a symbol
2098 // reference or immediate we may have to expand instructions.
2099 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2100 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2101 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2102 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2103 MCOperand &Op = Inst.getOperand(i);
2105 int MemOffset = Op.getImm();
2106 if (MemOffset < -32768 || MemOffset > 32767) {
2107 // Offset can't exceed 16bit value.
2108 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
2109 return getParser().hasPendingError();
2111 } else if (Op.isExpr()) {
2112 const MCExpr *Expr = Op.getExpr();
2113 if (Expr->getKind() == MCExpr::SymbolRef) {
2114 const MCSymbolRefExpr *SR =
2115 static_cast<const MCSymbolRefExpr *>(Expr);
2116 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2118 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2119 return getParser().hasPendingError();
2121 } else if (!isEvaluated(Expr)) {
2122 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2123 return getParser().hasPendingError();
2130 if (inMicroMipsMode()) {
2131 if (MCID.mayLoad()) {
2132 // Try to create 16-bit GP relative load instruction.
2133 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2134 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2135 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2136 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2137 MCOperand &Op = Inst.getOperand(i);
2139 int MemOffset = Op.getImm();
2140 MCOperand &DstReg = Inst.getOperand(0);
2141 MCOperand &BaseReg = Inst.getOperand(1);
2142 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2143 getContext().getRegisterInfo()->getRegClass(
2144 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2145 (BaseReg.getReg() == Mips::GP ||
2146 BaseReg.getReg() == Mips::GP_64)) {
2148 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2157 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2162 switch (Inst.getOpcode()) {
2165 case Mips::ADDIUSP_MM:
2166 Opnd = Inst.getOperand(0);
2168 return Error(IDLoc, "expected immediate operand kind");
2169 Imm = Opnd.getImm();
2170 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2172 return Error(IDLoc, "immediate operand value out of range");
2174 case Mips::SLL16_MM:
2175 case Mips::SRL16_MM:
2176 Opnd = Inst.getOperand(2);
2178 return Error(IDLoc, "expected immediate operand kind");
2179 Imm = Opnd.getImm();
2180 if (Imm < 1 || Imm > 8)
2181 return Error(IDLoc, "immediate operand value out of range");
2184 Opnd = Inst.getOperand(1);
2186 return Error(IDLoc, "expected immediate operand kind");
2187 Imm = Opnd.getImm();
2188 if (Imm < -1 || Imm > 126)
2189 return Error(IDLoc, "immediate operand value out of range");
2191 case Mips::ADDIUR2_MM:
2192 Opnd = Inst.getOperand(2);
2194 return Error(IDLoc, "expected immediate operand kind");
2195 Imm = Opnd.getImm();
2196 if (!(Imm == 1 || Imm == -1 ||
2197 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2198 return Error(IDLoc, "immediate operand value out of range");
2200 case Mips::ANDI16_MM:
2201 Opnd = Inst.getOperand(2);
2203 return Error(IDLoc, "expected immediate operand kind");
2204 Imm = Opnd.getImm();
2205 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2206 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2207 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2208 return Error(IDLoc, "immediate operand value out of range");
2210 case Mips::LBU16_MM:
2211 Opnd = Inst.getOperand(2);
2213 return Error(IDLoc, "expected immediate operand kind");
2214 Imm = Opnd.getImm();
2215 if (Imm < -1 || Imm > 14)
2216 return Error(IDLoc, "immediate operand value out of range");
2219 case Mips::SB16_MMR6:
2220 Opnd = Inst.getOperand(2);
2222 return Error(IDLoc, "expected immediate operand kind");
2223 Imm = Opnd.getImm();
2224 if (Imm < 0 || Imm > 15)
2225 return Error(IDLoc, "immediate operand value out of range");
2227 case Mips::LHU16_MM:
2229 case Mips::SH16_MMR6:
2230 Opnd = Inst.getOperand(2);
2232 return Error(IDLoc, "expected immediate operand kind");
2233 Imm = Opnd.getImm();
2234 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2235 return Error(IDLoc, "immediate operand value out of range");
2239 case Mips::SW16_MMR6:
2240 Opnd = Inst.getOperand(2);
2242 return Error(IDLoc, "expected immediate operand kind");
2243 Imm = Opnd.getImm();
2244 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2245 return Error(IDLoc, "immediate operand value out of range");
2247 case Mips::ADDIUPC_MM:
2248 MCOperand Opnd = Inst.getOperand(1);
2250 return Error(IDLoc, "expected immediate operand kind");
2251 int Imm = Opnd.getImm();
2252 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2253 return Error(IDLoc, "immediate operand value out of range");
2258 bool FillDelaySlot =
2259 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2261 TOut.emitDirectiveSetNoReorder();
2263 MacroExpanderResultTy ExpandResult =
2264 tryExpandInstruction(Inst, IDLoc, Out, STI);
2265 switch (ExpandResult) {
2267 Out.EmitInstruction(Inst, *STI);
2275 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2276 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2277 if (inMicroMipsMode()) {
2278 TOut.setUsesMicroMips();
2279 TOut.updateABIInfo(*this);
2282 // If this instruction has a delay slot and .set reorder is active,
2283 // emit a NOP after it.
2284 if (FillDelaySlot) {
2285 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2286 TOut.emitDirectiveSetReorder();
2289 if ((Inst.getOpcode() == Mips::JalOneReg ||
2290 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2291 isPicAndNotNxxAbi()) {
2292 if (IsCpRestoreSet) {
2293 // We need a NOP between the JALR and the LW:
2294 // If .set reorder has been used, we've already emitted a NOP.
2295 // If .set noreorder has been used, we need to emit a NOP at this point.
2296 if (!AssemblerOptions.back()->isReorder())
2297 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2300 // Load the $gp from the stack.
2301 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2303 Warning(IDLoc, "no .cprestore used in PIC mode");
2309 MipsAsmParser::MacroExpanderResultTy
2310 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2311 const MCSubtargetInfo *STI) {
2312 switch (Inst.getOpcode()) {
2314 return MER_NotAMacro;
2315 case Mips::LoadImm32:
2316 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2317 case Mips::LoadImm64:
2318 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2319 case Mips::LoadAddrImm32:
2320 case Mips::LoadAddrImm64:
2321 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2322 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2323 "expected immediate operand kind");
2325 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2327 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2331 case Mips::LoadAddrReg32:
2332 case Mips::LoadAddrReg64:
2333 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2334 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2335 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2336 "expected immediate operand kind");
2338 return expandLoadAddress(Inst.getOperand(0).getReg(),
2339 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2340 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2344 case Mips::B_MM_Pseudo:
2345 case Mips::B_MMR6_Pseudo:
2346 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2350 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2352 case Mips::JalOneReg:
2353 case Mips::JalTwoReg:
2354 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2357 case Mips::BEQLImmMacro:
2358 case Mips::BNELImmMacro:
2359 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2376 case Mips::BLTImmMacro:
2377 case Mips::BLEImmMacro:
2378 case Mips::BGEImmMacro:
2379 case Mips::BGTImmMacro:
2380 case Mips::BLTUImmMacro:
2381 case Mips::BLEUImmMacro:
2382 case Mips::BGEUImmMacro:
2383 case Mips::BGTUImmMacro:
2384 case Mips::BLTLImmMacro:
2385 case Mips::BLELImmMacro:
2386 case Mips::BGELImmMacro:
2387 case Mips::BGTLImmMacro:
2388 case Mips::BLTULImmMacro:
2389 case Mips::BLEULImmMacro:
2390 case Mips::BGEULImmMacro:
2391 case Mips::BGTULImmMacro:
2392 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2393 case Mips::SDivMacro:
2394 case Mips::SDivIMacro:
2395 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2397 case Mips::DSDivMacro:
2398 case Mips::DSDivIMacro:
2399 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2401 case Mips::UDivMacro:
2402 case Mips::UDivIMacro:
2403 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2405 case Mips::DUDivMacro:
2406 case Mips::DUDivIMacro:
2407 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2409 case Mips::PseudoTRUNC_W_S:
2410 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2412 case Mips::PseudoTRUNC_W_D32:
2413 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2415 case Mips::PseudoTRUNC_W_D:
2416 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2419 case Mips::LoadImmSingleGPR:
2420 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2423 case Mips::LoadImmSingleFGR:
2424 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2427 case Mips::LoadImmDoubleGPR:
2428 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2431 case Mips::LoadImmDoubleFGR:
2432 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2435 case Mips::LoadImmDoubleFGR_32:
2436 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2440 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2442 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2444 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2447 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2449 case Mips::NORImm64:
2450 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2451 case Mips::SLTImm64:
2452 if (isInt<16>(Inst.getOperand(2).getImm())) {
2453 Inst.setOpcode(Mips::SLTi64);
2454 return MER_NotAMacro;
2456 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2457 case Mips::SLTUImm64:
2458 if (isInt<16>(Inst.getOperand(2).getImm())) {
2459 Inst.setOpcode(Mips::SLTiu64);
2460 return MER_NotAMacro;
2462 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2463 case Mips::ADDi: case Mips::ADDi_MM:
2464 case Mips::ADDiu: case Mips::ADDiu_MM:
2465 case Mips::SLTi: case Mips::SLTi_MM:
2466 case Mips::SLTiu: case Mips::SLTiu_MM:
2467 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2468 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2469 int64_t ImmValue = Inst.getOperand(2).getImm();
2470 if (isInt<16>(ImmValue))
2471 return MER_NotAMacro;
2472 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2475 return MER_NotAMacro;
2476 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2477 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2478 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2479 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2480 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2481 int64_t ImmValue = Inst.getOperand(2).getImm();
2482 if (isUInt<16>(ImmValue))
2483 return MER_NotAMacro;
2484 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2487 return MER_NotAMacro;
2490 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2496 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2499 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2500 case Mips::ABSMacro:
2501 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2502 case Mips::MULImmMacro:
2503 case Mips::DMULImmMacro:
2504 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2505 case Mips::MULOMacro:
2506 case Mips::DMULOMacro:
2507 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2508 case Mips::MULOUMacro:
2509 case Mips::DMULOUMacro:
2510 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2511 case Mips::DMULMacro:
2512 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2515 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2516 Inst.getOpcode() == Mips::LDMacro)
2519 case Mips::SEQMacro:
2520 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2521 case Mips::SEQIMacro:
2522 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2523 case Mips::MFTC0: case Mips::MTTC0:
2524 case Mips::MFTGPR: case Mips::MTTGPR:
2525 case Mips::MFTLO: case Mips::MTTLO:
2526 case Mips::MFTHI: case Mips::MTTHI:
2527 case Mips::MFTACX: case Mips::MTTACX:
2528 case Mips::MFTDSP: case Mips::MTTDSP:
2529 case Mips::MFTC1: case Mips::MTTC1:
2530 case Mips::MFTHC1: case Mips::MTTHC1:
2531 case Mips::CFTC1: case Mips::CTTC1:
2532 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2538 const MCSubtargetInfo *STI) {
2539 MipsTargetStreamer &TOut = getTargetStreamer();
2541 // Create a JALR instruction which is going to replace the pseudo-JAL.
2543 JalrInst.setLoc(IDLoc);
2544 const MCOperand FirstRegOp = Inst.getOperand(0);
2545 const unsigned Opcode = Inst.getOpcode();
2547 if (Opcode == Mips::JalOneReg) {
2548 // jal $rs => jalr $rs
2549 if (IsCpRestoreSet && inMicroMipsMode()) {
2550 JalrInst.setOpcode(Mips::JALRS16_MM);
2551 JalrInst.addOperand(FirstRegOp);
2552 } else if (inMicroMipsMode()) {
2553 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2554 JalrInst.addOperand(FirstRegOp);
2556 JalrInst.setOpcode(Mips::JALR);
2557 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2558 JalrInst.addOperand(FirstRegOp);
2560 } else if (Opcode == Mips::JalTwoReg) {
2561 // jal $rd, $rs => jalr $rd, $rs
2562 if (IsCpRestoreSet && inMicroMipsMode())
2563 JalrInst.setOpcode(Mips::JALRS_MM);
2565 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2566 JalrInst.addOperand(FirstRegOp);
2567 const MCOperand SecondRegOp = Inst.getOperand(1);
2568 JalrInst.addOperand(SecondRegOp);
2570 Out.EmitInstruction(JalrInst, *STI);
2572 // If .set reorder is active and branch instruction has a delay slot,
2573 // emit a NOP after it.
2574 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2575 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2576 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2582 /// Can the value be represented by a unsigned N-bit value and a shift left?
2583 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2584 unsigned BitNum = findFirstSet(x);
2586 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2589 /// Load (or add) an immediate into a register.
2591 /// @param ImmValue The immediate to load.
2592 /// @param DstReg The register that will hold the immediate.
2593 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2594 /// for a simple initialization.
2595 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2596 /// @param IsAddress True if the immediate represents an address. False if it
2598 /// @param IDLoc Location of the immediate in the source file.
2599 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2600 unsigned SrcReg, bool Is32BitImm,
2601 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2602 const MCSubtargetInfo *STI) {
2603 MipsTargetStreamer &TOut = getTargetStreamer();
2605 if (!Is32BitImm && !isGP64bit()) {
2606 Error(IDLoc, "instruction requires a 64-bit architecture");
2611 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2612 // Sign extend up to 64-bit so that the predicates match the hardware
2613 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2615 ImmValue = SignExtend64<32>(ImmValue);
2617 Error(IDLoc, "instruction requires a 32-bit immediate");
2622 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2623 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2625 bool UseSrcReg = false;
2626 if (SrcReg != Mips::NoRegister)
2629 unsigned TmpReg = DstReg;
2631 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2632 // At this point we need AT to perform the expansions and we exit if it is
2634 unsigned ATReg = getATReg(IDLoc);
2640 if (isInt<16>(ImmValue)) {
2644 // This doesn't quite follow the usual ABI expectations for N32 but matches
2645 // traditional assembler behaviour. N32 would normally use addiu for both
2646 // integers and addresses.
2647 if (IsAddress && !Is32BitImm) {
2648 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2652 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2656 if (isUInt<16>(ImmValue)) {
2657 unsigned TmpReg = DstReg;
2658 if (SrcReg == DstReg) {
2659 TmpReg = getATReg(IDLoc);
2664 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2666 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2670 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2671 warnIfNoMacro(IDLoc);
2673 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2674 uint16_t Bits15To0 = ImmValue & 0xffff;
2675 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2676 // Traditional behaviour seems to special case this particular value. It's
2677 // not clear why other masks are handled differently.
2678 if (ImmValue == 0xffffffff) {
2679 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2680 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2682 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2686 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2688 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2689 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2691 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2693 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2697 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2699 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2701 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2705 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2707 Error(IDLoc, "instruction requires a 32-bit immediate");
2711 // Traditionally, these immediates are shifted as little as possible and as
2712 // such we align the most significant bit to bit 15 of our temporary.
2713 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2714 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2715 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2716 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2717 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2718 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2721 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2726 warnIfNoMacro(IDLoc);
2728 // The remaining case is packed with a sequence of dsll and ori with zeros
2729 // being omitted and any neighbouring dsll's being coalesced.
2730 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2732 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2733 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2737 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2738 // skip it and defer the shift to the next chunk.
2739 unsigned ShiftCarriedForwards = 16;
2740 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2741 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2743 if (ImmChunk != 0) {
2744 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2745 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2746 ShiftCarriedForwards = 0;
2749 ShiftCarriedForwards += 16;
2751 ShiftCarriedForwards -= 16;
2753 // Finish any remaining shifts left by trailing zeros.
2754 if (ShiftCarriedForwards)
2755 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2758 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2763 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2764 MCStreamer &Out, const MCSubtargetInfo *STI) {
2765 const MCOperand &ImmOp = Inst.getOperand(1);
2766 assert(ImmOp.isImm() && "expected immediate operand kind");
2767 const MCOperand &DstRegOp = Inst.getOperand(0);
2768 assert(DstRegOp.isReg() && "expected register operand kind");
2770 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2771 Is32BitImm, false, IDLoc, Out, STI))
2777 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2778 const MCOperand &Offset,
2779 bool Is32BitAddress, SMLoc IDLoc,
2781 const MCSubtargetInfo *STI) {
2782 // la can't produce a usable address when addresses are 64-bit.
2783 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2784 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2785 // We currently can't do this because we depend on the equality
2786 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2787 Error(IDLoc, "la used to load 64-bit address");
2788 // Continue as if we had 'dla' instead.
2789 Is32BitAddress = false;
2793 // dla requires 64-bit addresses.
2794 if (!Is32BitAddress && !hasMips3()) {
2795 Error(IDLoc, "instruction requires a 64-bit architecture");
2799 if (!Offset.isImm())
2800 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2801 Is32BitAddress, IDLoc, Out, STI);
2803 if (!ABI.ArePtrs64bit()) {
2804 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2805 Is32BitAddress = true;
2808 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2812 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2813 unsigned DstReg, unsigned SrcReg,
2814 bool Is32BitSym, SMLoc IDLoc,
2816 const MCSubtargetInfo *STI) {
2817 // FIXME: These expansions do not respect -mxgot.
2818 MipsTargetStreamer &TOut = getTargetStreamer();
2819 bool UseSrcReg = SrcReg != Mips::NoRegister;
2820 warnIfNoMacro(IDLoc);
2822 if (inPicMode() && ABI.IsO32()) {
2824 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2825 Error(IDLoc, "expected relocatable expression");
2828 if (Res.getSymB() != nullptr) {
2829 Error(IDLoc, "expected relocatable expression with only one symbol");
2833 // The case where the result register is $25 is somewhat special. If the
2834 // symbol in the final relocation is external and not modified with a
2835 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2836 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2837 Res.getConstant() == 0 &&
2838 !(Res.getSymA()->getSymbol().isInSection() ||
2839 Res.getSymA()->getSymbol().isTemporary() ||
2840 (Res.getSymA()->getSymbol().isELF() &&
2841 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2843 const MCExpr *CallExpr =
2844 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2845 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2846 MCOperand::createExpr(CallExpr), IDLoc, STI);
2850 // The remaining cases are:
2851 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2852 // >addiu $tmp, $tmp, %lo(offset)
2853 // >addiu $rd, $tmp, $rs
2854 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2855 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2856 // >addiu $rd, $tmp, $rs
2857 // The addiu's marked with a '>' may be omitted if they are redundant. If
2858 // this happens then the last instruction must use $rd as the result
2860 const MipsMCExpr *GotExpr =
2861 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2862 const MCExpr *LoExpr = nullptr;
2863 if (Res.getSymA()->getSymbol().isInSection() ||
2864 Res.getSymA()->getSymbol().isTemporary())
2865 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2866 else if (Res.getConstant() != 0) {
2867 // External symbols fully resolve the symbol with just the %got(symbol)
2868 // but we must still account for any offset to the symbol for expressions
2870 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2873 unsigned TmpReg = DstReg;
2875 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2877 // If $rs is the same as $rd, we need to use AT.
2878 // If it is not available we exit.
2879 unsigned ATReg = getATReg(IDLoc);
2885 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2886 MCOperand::createExpr(GotExpr), IDLoc, STI);
2889 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2893 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2898 if (inPicMode() && ABI.ArePtrs64bit()) {
2900 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2901 Error(IDLoc, "expected relocatable expression");
2904 if (Res.getSymB() != nullptr) {
2905 Error(IDLoc, "expected relocatable expression with only one symbol");
2909 // The case where the result register is $25 is somewhat special. If the
2910 // symbol in the final relocation is external and not modified with a
2911 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2912 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2913 Res.getConstant() == 0 &&
2914 !(Res.getSymA()->getSymbol().isInSection() ||
2915 Res.getSymA()->getSymbol().isTemporary() ||
2916 (Res.getSymA()->getSymbol().isELF() &&
2917 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2919 const MCExpr *CallExpr =
2920 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2921 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2922 MCOperand::createExpr(CallExpr), IDLoc, STI);
2926 // The remaining cases are:
2927 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2928 // >daddiu $tmp, $tmp, offset
2929 // >daddu $rd, $tmp, $rs
2930 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2931 // this happens then the last instruction must use $rd as the result
2933 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2936 const MCExpr *LoExpr = nullptr;
2937 if (Res.getConstant() != 0) {
2938 // Symbols fully resolve with just the %got_disp(symbol) but we
2939 // must still account for any offset to the symbol for
2940 // expressions like symbol+8.
2941 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2943 // FIXME: Offsets greater than 16 bits are not yet implemented.
2944 // FIXME: The correct range is a 32-bit sign-extended number.
2945 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2946 Error(IDLoc, "macro instruction uses large offset, which is not "
2947 "currently supported");
2952 unsigned TmpReg = DstReg;
2954 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2956 // If $rs is the same as $rd, we need to use AT.
2957 // If it is not available we exit.
2958 unsigned ATReg = getATReg(IDLoc);
2964 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
2965 MCOperand::createExpr(GotExpr), IDLoc, STI);
2968 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2972 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2977 const MipsMCExpr *HiExpr =
2978 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2979 const MipsMCExpr *LoExpr =
2980 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2982 // This is the 64-bit symbol address expansion.
2983 if (ABI.ArePtrs64bit() && isGP64bit()) {
2984 // We need AT for the 64-bit expansion in the cases where the optional
2985 // source register is the destination register and for the superscalar
2988 // If it is not available we exit if the destination is the same as the
2991 const MipsMCExpr *HighestExpr =
2992 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2993 const MipsMCExpr *HigherExpr =
2994 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2997 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
2999 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3000 unsigned ATReg = getATReg(IDLoc);
3002 // If $rs is the same as $rd:
3003 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3004 // daddiu $at, $at, %higher(sym)
3005 // dsll $at, $at, 16
3006 // daddiu $at, $at, %hi(sym)
3007 // dsll $at, $at, 16
3008 // daddiu $at, $at, %lo(sym)
3009 // daddu $rd, $at, $rd
3010 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3012 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3013 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3014 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3015 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3017 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3018 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3020 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3023 } else if (canUseATReg() && !RdRegIsRsReg) {
3024 unsigned ATReg = getATReg(IDLoc);
3026 // If the $rs is different from $rd or if $rs isn't specified and we
3027 // have $at available:
3028 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3029 // lui $at, %hi(sym)
3030 // daddiu $rd, $rd, %higher(sym)
3031 // daddiu $at, $at, %lo(sym)
3032 // dsll32 $rd, $rd, 0
3033 // daddu $rd, $rd, $at
3034 // (daddu $rd, $rd, $rs)
3036 // Which is preferred for superscalar issue.
3037 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3039 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3040 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3041 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3042 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3044 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3045 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3047 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3050 } else if (!canUseATReg() && !RdRegIsRsReg) {
3051 // Otherwise, synthesize the address in the destination register
3053 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3054 // daddiu $rd, $rd, %higher(sym)
3055 // dsll $rd, $rd, 16
3056 // daddiu $rd, $rd, %hi(sym)
3057 // dsll $rd, $rd, 16
3058 // daddiu $rd, $rd, %lo(sym)
3059 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3061 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3062 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3063 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3064 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3065 MCOperand::createExpr(HiExpr), IDLoc, STI);
3066 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3067 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3068 MCOperand::createExpr(LoExpr), IDLoc, STI);
3070 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3074 // We have a case where SrcReg == DstReg and we don't have $at
3075 // available. We can't expand this case, so error out appropriately.
3076 assert(SrcReg == DstReg && !canUseATReg() &&
3077 "Could have expanded dla but didn't?");
3078 reportParseError(IDLoc,
3079 "pseudo-instruction requires $at, which is not available");
3084 // And now, the 32-bit symbol address expansion:
3085 // If $rs is the same as $rd:
3086 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3087 // ori $at, $at, %lo(sym)
3088 // addu $rd, $at, $rd
3089 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3090 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3091 // ori $rd, $rd, %lo(sym)
3092 // (addu $rd, $rd, $rs)
3093 unsigned TmpReg = DstReg;
3095 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3096 // If $rs is the same as $rd, we need to use AT.
3097 // If it is not available we exit.
3098 unsigned ATReg = getATReg(IDLoc);
3104 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3105 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3109 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3112 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3117 // Each double-precision register DO-D15 overlaps with two of the single
3118 // precision registers F0-F31. As an example, all of the following hold true:
3119 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3120 static unsigned nextReg(unsigned Reg) {
3121 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3122 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3124 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3125 case Mips::ZERO: return Mips::AT;
3126 case Mips::AT: return Mips::V0;
3127 case Mips::V0: return Mips::V1;
3128 case Mips::V1: return Mips::A0;
3129 case Mips::A0: return Mips::A1;
3130 case Mips::A1: return Mips::A2;
3131 case Mips::A2: return Mips::A3;
3132 case Mips::A3: return Mips::T0;
3133 case Mips::T0: return Mips::T1;
3134 case Mips::T1: return Mips::T2;
3135 case Mips::T2: return Mips::T3;
3136 case Mips::T3: return Mips::T4;
3137 case Mips::T4: return Mips::T5;
3138 case Mips::T5: return Mips::T6;
3139 case Mips::T6: return Mips::T7;
3140 case Mips::T7: return Mips::S0;
3141 case Mips::S0: return Mips::S1;
3142 case Mips::S1: return Mips::S2;
3143 case Mips::S2: return Mips::S3;
3144 case Mips::S3: return Mips::S4;
3145 case Mips::S4: return Mips::S5;
3146 case Mips::S5: return Mips::S6;
3147 case Mips::S6: return Mips::S7;
3148 case Mips::S7: return Mips::T8;
3149 case Mips::T8: return Mips::T9;
3150 case Mips::T9: return Mips::K0;
3151 case Mips::K0: return Mips::K1;
3152 case Mips::K1: return Mips::GP;
3153 case Mips::GP: return Mips::SP;
3154 case Mips::SP: return Mips::FP;
3155 case Mips::FP: return Mips::RA;
3156 case Mips::RA: return Mips::ZERO;
3157 case Mips::D0: return Mips::F1;
3158 case Mips::D1: return Mips::F3;
3159 case Mips::D2: return Mips::F5;
3160 case Mips::D3: return Mips::F7;
3161 case Mips::D4: return Mips::F9;
3162 case Mips::D5: return Mips::F11;
3163 case Mips::D6: return Mips::F13;
3164 case Mips::D7: return Mips::F15;
3165 case Mips::D8: return Mips::F17;
3166 case Mips::D9: return Mips::F19;
3167 case Mips::D10: return Mips::F21;
3168 case Mips::D11: return Mips::F23;
3169 case Mips::D12: return Mips::F25;
3170 case Mips::D13: return Mips::F27;
3171 case Mips::D14: return Mips::F29;
3172 case Mips::D15: return Mips::F31;
3176 // FIXME: This method is too general. In principle we should compute the number
3177 // of instructions required to synthesize the immediate inline compared to
3178 // synthesizing the address inline and relying on non .text sections.
3179 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3180 // likely to yield a much larger benefit as we have to synthesize a 64bit
3181 // address to load a 64 bit value.
3182 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3184 unsigned ATReg = getATReg(IDLoc);
3189 const MCExpr *GotSym =
3190 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3191 const MipsMCExpr *GotExpr =
3192 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3194 if(isABI_O32() || isABI_N32()) {
3195 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3197 } else { //isABI_N64()
3198 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3201 } else { //!IsPicEnabled
3202 const MCExpr *HiSym =
3203 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3204 const MipsMCExpr *HiExpr =
3205 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3207 // FIXME: This is technically correct but gives a different result to gas,
3208 // but gas is incomplete there (it has a fixme noting it doesn't work with
3209 // 64-bit addresses).
3210 // FIXME: With -msym32 option, the address expansion for N64 should probably
3211 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3212 // symbol's value is considered sign extended.
3213 if(isABI_O32() || isABI_N32()) {
3214 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3215 } else { //isABI_N64()
3216 const MCExpr *HighestSym =
3217 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3218 const MipsMCExpr *HighestExpr =
3219 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3220 const MCExpr *HigherSym =
3221 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3222 const MipsMCExpr *HigherExpr =
3223 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3225 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3227 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3228 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3229 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3230 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3232 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3238 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3239 bool Is64FPU, SMLoc IDLoc,
3241 const MCSubtargetInfo *STI) {
3242 MipsTargetStreamer &TOut = getTargetStreamer();
3243 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3244 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3245 "Invalid instruction operand.");
3247 unsigned FirstReg = Inst.getOperand(0).getReg();
3248 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3250 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3251 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3252 // exponent field), convert it to double (e.g. 1 to 1.0)
3253 if ((HiImmOp64 & 0x7ff00000) == 0) {
3254 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3255 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3258 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3259 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3262 // Conversion of a double in an uint64_t to a float in a uint32_t,
3263 // retaining the bit pattern of a float.
3265 double doubleImm = BitsToDouble(ImmOp64);
3266 float tmp_float = static_cast<float>(doubleImm);
3267 ImmOp32 = FloatToBits(tmp_float);
3270 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3275 unsigned ATReg = getATReg(IDLoc);
3278 if (LoImmOp64 == 0) {
3279 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3282 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3286 MCSection *CS = getStreamer().getCurrentSectionOnly();
3287 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3288 // where appropriate.
3289 MCSection *ReadOnlySection = getContext().getELFSection(
3290 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3292 MCSymbol *Sym = getContext().createTempSymbol();
3293 const MCExpr *LoSym =
3294 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3295 const MipsMCExpr *LoExpr =
3296 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3298 getStreamer().SwitchSection(ReadOnlySection);
3299 getStreamer().EmitLabel(Sym, IDLoc);
3300 getStreamer().EmitIntValue(ImmOp32, 4);
3301 getStreamer().SwitchSection(CS);
3303 if(emitPartialAddress(TOut, IDLoc, Sym))
3305 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3306 MCOperand::createExpr(LoExpr), IDLoc, STI);
3312 unsigned ATReg = getATReg(IDLoc);
3317 if (LoImmOp64 == 0) {
3318 if(isABI_N32() || isABI_N64()) {
3319 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3324 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3328 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3335 MCSection *CS = getStreamer().getCurrentSectionOnly();
3336 MCSection *ReadOnlySection = getContext().getELFSection(
3337 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3339 MCSymbol *Sym = getContext().createTempSymbol();
3340 const MCExpr *LoSym =
3341 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3342 const MipsMCExpr *LoExpr =
3343 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3345 getStreamer().SwitchSection(ReadOnlySection);
3346 getStreamer().EmitLabel(Sym, IDLoc);
3347 getStreamer().EmitIntValue(HiImmOp64, 4);
3348 getStreamer().EmitIntValue(LoImmOp64, 4);
3349 getStreamer().SwitchSection(CS);
3351 if(emitPartialAddress(TOut, IDLoc, Sym))
3354 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3355 MCOperand::createExpr(LoExpr), IDLoc, STI);
3357 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3358 MCOperand::createExpr(LoExpr), IDLoc, STI);
3360 if(isABI_N32() || isABI_N64())
3361 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3363 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3364 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3367 } else { // if(!IsGPR && !IsSingle)
3368 if ((LoImmOp64 == 0) &&
3369 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3370 // FIXME: In the case where the constant is zero, we can load the
3371 // register directly from the zero register.
3372 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3375 if (isABI_N32() || isABI_N64())
3376 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3377 else if (hasMips32r2()) {
3378 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3379 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3381 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3382 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3387 MCSection *CS = getStreamer().getCurrentSectionOnly();
3388 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3389 // where appropriate.
3390 MCSection *ReadOnlySection = getContext().getELFSection(
3391 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3393 MCSymbol *Sym = getContext().createTempSymbol();
3394 const MCExpr *LoSym =
3395 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3396 const MipsMCExpr *LoExpr =
3397 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3399 getStreamer().SwitchSection(ReadOnlySection);
3400 getStreamer().EmitLabel(Sym, IDLoc);
3401 getStreamer().EmitIntValue(HiImmOp64, 4);
3402 getStreamer().EmitIntValue(LoImmOp64, 4);
3403 getStreamer().SwitchSection(CS);
3405 if(emitPartialAddress(TOut, IDLoc, Sym))
3407 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3408 MCOperand::createExpr(LoExpr), IDLoc, STI);
3413 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3415 const MCSubtargetInfo *STI) {
3416 MipsTargetStreamer &TOut = getTargetStreamer();
3418 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3419 "unexpected number of operands");
3421 MCOperand Offset = Inst.getOperand(0);
3422 if (Offset.isExpr()) {
3424 Inst.setOpcode(Mips::BEQ_MM);
3425 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3426 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3427 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3429 assert(Offset.isImm() && "expected immediate operand kind");
3430 if (isInt<11>(Offset.getImm())) {
3431 // If offset fits into 11 bits then this instruction becomes microMIPS
3432 // 16-bit unconditional branch instruction.
3433 if (inMicroMipsMode())
3434 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3436 if (!isInt<17>(Offset.getImm()))
3437 return Error(IDLoc, "branch target out of range");
3438 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3439 return Error(IDLoc, "branch to misaligned address");
3441 Inst.setOpcode(Mips::BEQ_MM);
3442 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3443 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3444 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3447 Out.EmitInstruction(Inst, *STI);
3449 // If .set reorder is active and branch instruction has a delay slot,
3450 // emit a NOP after it.
3451 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3452 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3453 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3458 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3459 const MCSubtargetInfo *STI) {
3460 MipsTargetStreamer &TOut = getTargetStreamer();
3461 const MCOperand &DstRegOp = Inst.getOperand(0);
3462 assert(DstRegOp.isReg() && "expected register operand kind");
3464 const MCOperand &ImmOp = Inst.getOperand(1);
3465 assert(ImmOp.isImm() && "expected immediate operand kind");
3467 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3468 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3469 "expected immediate or expression operand");
3471 bool IsLikely = false;
3473 unsigned OpCode = 0;
3474 switch(Inst.getOpcode()) {
3481 case Mips::BEQLImmMacro:
3482 OpCode = Mips::BEQL;
3485 case Mips::BNELImmMacro:
3486 OpCode = Mips::BNEL;
3490 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3494 int64_t ImmValue = ImmOp.getImm();
3495 if (ImmValue == 0) {
3497 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3498 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3499 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3501 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3504 warnIfNoMacro(IDLoc);
3506 unsigned ATReg = getATReg(IDLoc);
3510 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3515 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3516 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3517 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3519 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3524 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3525 const MCSubtargetInfo *STI, bool IsLoad,
3528 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3531 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3534 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3535 const MCSubtargetInfo *STI, bool IsImmOpnd) {
3536 MipsTargetStreamer &TOut = getTargetStreamer();
3538 unsigned DstReg = Inst.getOperand(0).getReg();
3539 unsigned BaseReg = Inst.getOperand(1).getReg();
3541 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3542 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3543 unsigned DstRegClassID =
3544 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3545 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3546 (DstRegClassID == Mips::GPR64RegClassID);
3549 // Try to use DstReg as the temporary.
3550 if (IsGPR && (BaseReg != DstReg)) {
3551 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3552 Inst.getOperand(2).getImm(), DstReg, IDLoc,
3557 // At this point we need AT to perform the expansions and we exit if it is
3559 unsigned ATReg = getATReg(IDLoc);
3563 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3564 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
3568 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3569 MCOperand LoOperand = MCOperand::createExpr(
3570 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3571 MCOperand HiOperand = MCOperand::createExpr(
3572 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3574 // Try to use DstReg as the temporary.
3575 if (IsGPR && (BaseReg != DstReg)) {
3576 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3577 LoOperand, DstReg, IDLoc, STI);
3581 // At this point we need AT to perform the expansions and we exit if it is
3583 unsigned ATReg = getATReg(IDLoc);
3587 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3588 LoOperand, ATReg, IDLoc, STI);
3591 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3592 const MCSubtargetInfo *STI,
3594 MipsTargetStreamer &TOut = getTargetStreamer();
3596 unsigned SrcReg = Inst.getOperand(0).getReg();
3597 unsigned BaseReg = Inst.getOperand(1).getReg();
3600 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
3601 Inst.getOperand(2).getImm(),
3602 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
3606 unsigned ATReg = getATReg(IDLoc);
3610 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3611 MCOperand LoOperand = MCOperand::createExpr(
3612 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3613 MCOperand HiOperand = MCOperand::createExpr(
3614 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3615 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
3616 LoOperand, ATReg, IDLoc, STI);
3619 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3621 const MCSubtargetInfo *STI) {
3622 unsigned OpNum = Inst.getNumOperands();
3623 unsigned Opcode = Inst.getOpcode();
3624 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3626 assert(Inst.getOperand(OpNum - 1).isImm() &&
3627 Inst.getOperand(OpNum - 2).isReg() &&
3628 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3630 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3631 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3632 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3633 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3634 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3635 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3636 // It can be implemented as SWM16 or LWM16 instruction.
3637 if (inMicroMipsMode() && hasMips32r6())
3638 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3640 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3643 Inst.setOpcode(NewOpcode);
3644 Out.EmitInstruction(Inst, *STI);
3648 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3650 const MCSubtargetInfo *STI) {
3651 MipsTargetStreamer &TOut = getTargetStreamer();
3652 bool EmittedNoMacroWarning = false;
3653 unsigned PseudoOpcode = Inst.getOpcode();
3654 unsigned SrcReg = Inst.getOperand(0).getReg();
3655 const MCOperand &TrgOp = Inst.getOperand(1);
3656 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3658 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3659 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3663 TrgReg = TrgOp.getReg();
3664 else if (TrgOp.isImm()) {
3665 warnIfNoMacro(IDLoc);
3666 EmittedNoMacroWarning = true;
3668 TrgReg = getATReg(IDLoc);
3672 switch(PseudoOpcode) {
3674 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3675 case Mips::BLTImmMacro:
3676 PseudoOpcode = Mips::BLT;
3678 case Mips::BLEImmMacro:
3679 PseudoOpcode = Mips::BLE;
3681 case Mips::BGEImmMacro:
3682 PseudoOpcode = Mips::BGE;
3684 case Mips::BGTImmMacro:
3685 PseudoOpcode = Mips::BGT;
3687 case Mips::BLTUImmMacro:
3688 PseudoOpcode = Mips::BLTU;
3690 case Mips::BLEUImmMacro:
3691 PseudoOpcode = Mips::BLEU;
3693 case Mips::BGEUImmMacro:
3694 PseudoOpcode = Mips::BGEU;
3696 case Mips::BGTUImmMacro:
3697 PseudoOpcode = Mips::BGTU;
3699 case Mips::BLTLImmMacro:
3700 PseudoOpcode = Mips::BLTL;
3702 case Mips::BLELImmMacro:
3703 PseudoOpcode = Mips::BLEL;
3705 case Mips::BGELImmMacro:
3706 PseudoOpcode = Mips::BGEL;
3708 case Mips::BGTLImmMacro:
3709 PseudoOpcode = Mips::BGTL;
3711 case Mips::BLTULImmMacro:
3712 PseudoOpcode = Mips::BLTUL;
3714 case Mips::BLEULImmMacro:
3715 PseudoOpcode = Mips::BLEUL;
3717 case Mips::BGEULImmMacro:
3718 PseudoOpcode = Mips::BGEUL;
3720 case Mips::BGTULImmMacro:
3721 PseudoOpcode = Mips::BGTUL;
3725 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3726 false, IDLoc, Out, STI))
3730 switch (PseudoOpcode) {
3735 AcceptsEquality = false;
3736 ReverseOrderSLT = false;
3737 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3738 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3739 ZeroSrcOpcode = Mips::BGTZ;
3740 ZeroTrgOpcode = Mips::BLTZ;
3746 AcceptsEquality = true;
3747 ReverseOrderSLT = true;
3748 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3749 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3750 ZeroSrcOpcode = Mips::BGEZ;
3751 ZeroTrgOpcode = Mips::BLEZ;
3757 AcceptsEquality = true;
3758 ReverseOrderSLT = false;
3759 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3760 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3761 ZeroSrcOpcode = Mips::BLEZ;
3762 ZeroTrgOpcode = Mips::BGEZ;
3768 AcceptsEquality = false;
3769 ReverseOrderSLT = true;
3770 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3771 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3772 ZeroSrcOpcode = Mips::BLTZ;
3773 ZeroTrgOpcode = Mips::BGTZ;
3776 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3779 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3780 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3781 if (IsSrcRegZero && IsTrgRegZero) {
3782 // FIXME: All of these Opcode-specific if's are needed for compatibility
3783 // with GAS' behaviour. However, they may not generate the most efficient
3784 // code in some circumstances.
3785 if (PseudoOpcode == Mips::BLT) {
3786 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3790 if (PseudoOpcode == Mips::BLE) {
3791 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3793 Warning(IDLoc, "branch is always taken");
3796 if (PseudoOpcode == Mips::BGE) {
3797 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3799 Warning(IDLoc, "branch is always taken");
3802 if (PseudoOpcode == Mips::BGT) {
3803 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3807 if (PseudoOpcode == Mips::BGTU) {
3808 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3809 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3812 if (AcceptsEquality) {
3813 // If both registers are $0 and the pseudo-branch accepts equality, it
3814 // will always be taken, so we emit an unconditional branch.
3815 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3816 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3817 Warning(IDLoc, "branch is always taken");
3820 // If both registers are $0 and the pseudo-branch does not accept
3821 // equality, it will never be taken, so we don't have to emit anything.
3824 if (IsSrcRegZero || IsTrgRegZero) {
3825 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3826 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3827 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3828 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3829 // the pseudo-branch will never be taken, so we don't emit anything.
3830 // This only applies to unsigned pseudo-branches.
3833 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3834 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3835 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3836 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3837 // the pseudo-branch will always be taken, so we emit an unconditional
3839 // This only applies to unsigned pseudo-branches.
3840 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3841 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3842 Warning(IDLoc, "branch is always taken");
3846 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3847 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3848 // the pseudo-branch will be taken only when the non-zero register is
3849 // different from 0, so we emit a BNEZ.
3851 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3852 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3853 // the pseudo-branch will be taken only when the non-zero register is
3854 // equal to 0, so we emit a BEQZ.
3856 // Because only BLEU and BGEU branch on equality, we can use the
3857 // AcceptsEquality variable to decide when to emit the BEQZ.
3858 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3859 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3860 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3863 // If we have a signed pseudo-branch and one of the registers is $0,
3864 // we can use an appropriate compare-to-zero branch. We select which one
3865 // to use in the switch statement above.
3866 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3867 IsSrcRegZero ? TrgReg : SrcReg,
3868 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3872 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3873 // expansions. If it is not available, we return.
3874 unsigned ATRegNum = getATReg(IDLoc);
3878 if (!EmittedNoMacroWarning)
3879 warnIfNoMacro(IDLoc);
3881 // SLT fits well with 2 of our 4 pseudo-branches:
3882 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3883 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3884 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3885 // This is accomplished by using a BNEZ with the result of the SLT.
3887 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3888 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3889 // Because only BGE and BLE branch on equality, we can use the
3890 // AcceptsEquality variable to decide when to emit the BEQZ.
3891 // Note that the order of the SLT arguments doesn't change between
3894 // The same applies to the unsigned variants, except that SLTu is used
3896 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3897 ReverseOrderSLT ? TrgReg : SrcReg,
3898 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3900 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3901 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3902 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3907 // Expand a integer division macro.
3909 // Notably we don't have to emit a warning when encountering $rt as the $zero
3910 // register, or 0 as an immediate. processInstruction() has already done that.
3912 // The destination register can only be $zero when expanding (S)DivIMacro or
3915 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3916 const MCSubtargetInfo *STI, const bool IsMips64,
3917 const bool Signed) {
3918 MipsTargetStreamer &TOut = getTargetStreamer();
3920 warnIfNoMacro(IDLoc);
3922 const MCOperand &RdRegOp = Inst.getOperand(0);
3923 assert(RdRegOp.isReg() && "expected register operand kind");
3924 unsigned RdReg = RdRegOp.getReg();
3926 const MCOperand &RsRegOp = Inst.getOperand(1);
3927 assert(RsRegOp.isReg() && "expected register operand kind");
3928 unsigned RsReg = RsRegOp.getReg();
3933 const MCOperand &RtOp = Inst.getOperand(2);
3934 assert((RtOp.isReg() || RtOp.isImm()) &&
3935 "expected register or immediate operand kind");
3937 RtReg = RtOp.getReg();
3939 ImmValue = RtOp.getImm();
3946 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3947 ZeroReg = Mips::ZERO_64;
3950 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3951 ZeroReg = Mips::ZERO;
3955 bool UseTraps = useTraps();
3958 unsigned ATReg = getATReg(IDLoc);
3962 if (ImmValue == 0) {
3964 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3966 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3970 if (ImmValue == 1) {
3971 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3973 } else if (Signed && ImmValue == -1) {
3974 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3977 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
3978 false, Inst.getLoc(), Out, STI))
3980 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
3981 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3987 // If the macro expansion of (d)div(u) would always trap or break, insert
3988 // the trap/break and exit. This gives a different result to GAS. GAS has
3989 // an inconsistency/missed optimization in that not all cases are handled
3990 // equivalently. As the observed behaviour is the same, we're ok.
3991 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3993 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3996 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4000 // Temporary label for first branch traget
4001 MCContext &Context = TOut.getStreamer().getContext();
4006 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4008 // Branch to the li instruction.
4009 BrTarget = Context.createTempSymbol();
4010 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4011 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4014 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4017 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4021 TOut.getStreamer().EmitLabel(BrTarget);
4023 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4027 unsigned ATReg = getATReg(IDLoc);
4032 TOut.getStreamer().EmitLabel(BrTarget);
4034 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4036 // Temporary label for the second branch target.
4037 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4038 MCOperand LabelOpEnd =
4039 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4041 // Branch to the mflo instruction.
4042 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4045 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4046 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
4048 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4052 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4054 // Branch to the mflo instruction.
4055 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4056 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
4057 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4060 TOut.getStreamer().EmitLabel(BrTargetEnd);
4061 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
4065 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4066 SMLoc IDLoc, MCStreamer &Out,
4067 const MCSubtargetInfo *STI) {
4068 MipsTargetStreamer &TOut = getTargetStreamer();
4070 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4071 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4072 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4074 unsigned FirstReg = Inst.getOperand(0).getReg();
4075 unsigned SecondReg = Inst.getOperand(1).getReg();
4076 unsigned ThirdReg = Inst.getOperand(2).getReg();
4078 if (hasMips1() && !hasMips2()) {
4079 unsigned ATReg = getATReg(IDLoc);
4082 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4083 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4084 TOut.emitNop(IDLoc, STI);
4085 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4086 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4087 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4088 TOut.emitNop(IDLoc, STI);
4089 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4091 FirstReg, SecondReg, IDLoc, STI);
4092 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4093 TOut.emitNop(IDLoc, STI);
4097 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4099 FirstReg, SecondReg, IDLoc, STI);
4104 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4105 MCStreamer &Out, const MCSubtargetInfo *STI) {
4106 if (hasMips32r6() || hasMips64r6()) {
4107 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4110 const MCOperand &DstRegOp = Inst.getOperand(0);
4111 assert(DstRegOp.isReg() && "expected register operand kind");
4112 const MCOperand &SrcRegOp = Inst.getOperand(1);
4113 assert(SrcRegOp.isReg() && "expected register operand kind");
4114 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4115 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4117 MipsTargetStreamer &TOut = getTargetStreamer();
4118 unsigned DstReg = DstRegOp.getReg();
4119 unsigned SrcReg = SrcRegOp.getReg();
4120 int64_t OffsetValue = OffsetImmOp.getImm();
4122 // NOTE: We always need AT for ULHU, as it is always used as the source
4123 // register for one of the LBu's.
4124 warnIfNoMacro(IDLoc);
4125 unsigned ATReg = getATReg(IDLoc);
4129 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4130 if (IsLargeOffset) {
4131 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4136 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4137 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4139 std::swap(FirstOffset, SecondOffset);
4141 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4142 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4144 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4145 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4147 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4148 FirstOffset, IDLoc, STI);
4149 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4150 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4151 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4156 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4157 const MCSubtargetInfo *STI) {
4158 if (hasMips32r6() || hasMips64r6()) {
4159 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4162 const MCOperand &DstRegOp = Inst.getOperand(0);
4163 assert(DstRegOp.isReg() && "expected register operand kind");
4164 const MCOperand &SrcRegOp = Inst.getOperand(1);
4165 assert(SrcRegOp.isReg() && "expected register operand kind");
4166 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4167 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4169 MipsTargetStreamer &TOut = getTargetStreamer();
4170 unsigned DstReg = DstRegOp.getReg();
4171 unsigned SrcReg = SrcRegOp.getReg();
4172 int64_t OffsetValue = OffsetImmOp.getImm();
4174 warnIfNoMacro(IDLoc);
4175 unsigned ATReg = getATReg(IDLoc);
4179 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4180 if (IsLargeOffset) {
4181 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4186 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4187 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4189 std::swap(FirstOffset, SecondOffset);
4191 if (IsLargeOffset) {
4192 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4193 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4194 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4195 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4196 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4197 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4199 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4200 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4201 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4207 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4208 const MCSubtargetInfo *STI) {
4209 if (hasMips32r6() || hasMips64r6()) {
4210 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4213 const MCOperand &DstRegOp = Inst.getOperand(0);
4214 assert(DstRegOp.isReg() && "expected register operand kind");
4215 const MCOperand &SrcRegOp = Inst.getOperand(1);
4216 assert(SrcRegOp.isReg() && "expected register operand kind");
4217 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4218 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4220 MipsTargetStreamer &TOut = getTargetStreamer();
4221 unsigned DstReg = DstRegOp.getReg();
4222 unsigned SrcReg = SrcRegOp.getReg();
4223 int64_t OffsetValue = OffsetImmOp.getImm();
4225 // Compute left/right load/store offsets.
4226 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4227 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4228 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4230 std::swap(LxlOffset, LxrOffset);
4232 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4233 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4234 unsigned TmpReg = SrcReg;
4235 if (IsLargeOffset || DoMove) {
4236 warnIfNoMacro(IDLoc);
4237 TmpReg = getATReg(IDLoc);
4242 if (IsLargeOffset) {
4243 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4249 std::swap(DstReg, TmpReg);
4251 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4252 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4253 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4254 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4257 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4262 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4264 const MCSubtargetInfo *STI) {
4265 MipsTargetStreamer &TOut = getTargetStreamer();
4267 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4268 assert(Inst.getOperand(0).isReg() &&
4269 Inst.getOperand(1).isReg() &&
4270 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4272 unsigned ATReg = Mips::NoRegister;
4273 unsigned FinalDstReg = Mips::NoRegister;
4274 unsigned DstReg = Inst.getOperand(0).getReg();
4275 unsigned SrcReg = Inst.getOperand(1).getReg();
4276 int64_t ImmValue = Inst.getOperand(2).getImm();
4278 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4280 unsigned FinalOpcode = Inst.getOpcode();
4282 if (DstReg == SrcReg) {
4283 ATReg = getATReg(Inst.getLoc());
4286 FinalDstReg = DstReg;
4290 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
4291 switch (FinalOpcode) {
4293 llvm_unreachable("unimplemented expansion");
4295 FinalOpcode = Mips::ADD;
4298 FinalOpcode = Mips::ADDu;
4301 FinalOpcode = Mips::AND;
4304 FinalOpcode = Mips::NOR;
4307 FinalOpcode = Mips::OR;
4310 FinalOpcode = Mips::SLT;
4313 FinalOpcode = Mips::SLTu;
4316 FinalOpcode = Mips::XOR;
4319 FinalOpcode = Mips::ADD_MM;
4321 case Mips::ADDiu_MM:
4322 FinalOpcode = Mips::ADDu_MM;
4325 FinalOpcode = Mips::AND_MM;
4328 FinalOpcode = Mips::OR_MM;
4331 FinalOpcode = Mips::SLT_MM;
4333 case Mips::SLTiu_MM:
4334 FinalOpcode = Mips::SLTu_MM;
4337 FinalOpcode = Mips::XOR_MM;
4340 FinalOpcode = Mips::AND64;
4342 case Mips::NORImm64:
4343 FinalOpcode = Mips::NOR64;
4346 FinalOpcode = Mips::OR64;
4348 case Mips::SLTImm64:
4349 FinalOpcode = Mips::SLT64;
4351 case Mips::SLTUImm64:
4352 FinalOpcode = Mips::SLTu64;
4355 FinalOpcode = Mips::XOR64;
4359 if (FinalDstReg == Mips::NoRegister)
4360 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4362 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4368 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4369 const MCSubtargetInfo *STI) {
4370 MipsTargetStreamer &TOut = getTargetStreamer();
4371 unsigned ATReg = Mips::NoRegister;
4372 unsigned DReg = Inst.getOperand(0).getReg();
4373 unsigned SReg = Inst.getOperand(1).getReg();
4374 unsigned TReg = Inst.getOperand(2).getReg();
4375 unsigned TmpReg = DReg;
4377 unsigned FirstShift = Mips::NOP;
4378 unsigned SecondShift = Mips::NOP;
4380 if (hasMips32r2()) {
4382 TmpReg = getATReg(Inst.getLoc());
4387 if (Inst.getOpcode() == Mips::ROL) {
4388 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4389 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4393 if (Inst.getOpcode() == Mips::ROR) {
4394 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4402 switch (Inst.getOpcode()) {
4404 llvm_unreachable("unexpected instruction opcode");
4406 FirstShift = Mips::SRLV;
4407 SecondShift = Mips::SLLV;
4410 FirstShift = Mips::SLLV;
4411 SecondShift = Mips::SRLV;
4415 ATReg = getATReg(Inst.getLoc());
4419 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4420 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4421 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4422 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4430 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4432 const MCSubtargetInfo *STI) {
4433 MipsTargetStreamer &TOut = getTargetStreamer();
4434 unsigned ATReg = Mips::NoRegister;
4435 unsigned DReg = Inst.getOperand(0).getReg();
4436 unsigned SReg = Inst.getOperand(1).getReg();
4437 int64_t ImmValue = Inst.getOperand(2).getImm();
4439 unsigned FirstShift = Mips::NOP;
4440 unsigned SecondShift = Mips::NOP;
4442 if (hasMips32r2()) {
4443 if (Inst.getOpcode() == Mips::ROLImm) {
4444 uint64_t MaxShift = 32;
4445 uint64_t ShiftValue = ImmValue;
4447 ShiftValue = MaxShift - ImmValue;
4448 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4452 if (Inst.getOpcode() == Mips::RORImm) {
4453 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4461 if (ImmValue == 0) {
4462 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4466 switch (Inst.getOpcode()) {
4468 llvm_unreachable("unexpected instruction opcode");
4470 FirstShift = Mips::SLL;
4471 SecondShift = Mips::SRL;
4474 FirstShift = Mips::SRL;
4475 SecondShift = Mips::SLL;
4479 ATReg = getATReg(Inst.getLoc());
4483 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4484 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4485 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4493 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4494 const MCSubtargetInfo *STI) {
4495 MipsTargetStreamer &TOut = getTargetStreamer();
4496 unsigned ATReg = Mips::NoRegister;
4497 unsigned DReg = Inst.getOperand(0).getReg();
4498 unsigned SReg = Inst.getOperand(1).getReg();
4499 unsigned TReg = Inst.getOperand(2).getReg();
4500 unsigned TmpReg = DReg;
4502 unsigned FirstShift = Mips::NOP;
4503 unsigned SecondShift = Mips::NOP;
4505 if (hasMips64r2()) {
4506 if (TmpReg == SReg) {
4507 TmpReg = getATReg(Inst.getLoc());
4512 if (Inst.getOpcode() == Mips::DROL) {
4513 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4514 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4518 if (Inst.getOpcode() == Mips::DROR) {
4519 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4527 switch (Inst.getOpcode()) {
4529 llvm_unreachable("unexpected instruction opcode");
4531 FirstShift = Mips::DSRLV;
4532 SecondShift = Mips::DSLLV;
4535 FirstShift = Mips::DSLLV;
4536 SecondShift = Mips::DSRLV;
4540 ATReg = getATReg(Inst.getLoc());
4544 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4545 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4546 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4547 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4555 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4557 const MCSubtargetInfo *STI) {
4558 MipsTargetStreamer &TOut = getTargetStreamer();
4559 unsigned ATReg = Mips::NoRegister;
4560 unsigned DReg = Inst.getOperand(0).getReg();
4561 unsigned SReg = Inst.getOperand(1).getReg();
4562 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4564 unsigned FirstShift = Mips::NOP;
4565 unsigned SecondShift = Mips::NOP;
4569 if (hasMips64r2()) {
4570 unsigned FinalOpcode = Mips::NOP;
4572 FinalOpcode = Mips::DROTR;
4573 else if (ImmValue % 32 == 0)
4574 FinalOpcode = Mips::DROTR32;
4575 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4576 if (Inst.getOpcode() == Mips::DROLImm)
4577 FinalOpcode = Mips::DROTR32;
4579 FinalOpcode = Mips::DROTR;
4580 } else if (ImmValue >= 33) {
4581 if (Inst.getOpcode() == Mips::DROLImm)
4582 FinalOpcode = Mips::DROTR;
4584 FinalOpcode = Mips::DROTR32;
4587 uint64_t ShiftValue = ImmValue % 32;
4588 if (Inst.getOpcode() == Mips::DROLImm)
4589 ShiftValue = (32 - ImmValue % 32) % 32;
4591 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4597 if (ImmValue == 0) {
4598 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4602 switch (Inst.getOpcode()) {
4604 llvm_unreachable("unexpected instruction opcode");
4606 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4607 FirstShift = Mips::DSLL;
4608 SecondShift = Mips::DSRL32;
4610 if (ImmValue == 32) {
4611 FirstShift = Mips::DSLL32;
4612 SecondShift = Mips::DSRL32;
4614 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4615 FirstShift = Mips::DSLL32;
4616 SecondShift = Mips::DSRL;
4620 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4621 FirstShift = Mips::DSRL;
4622 SecondShift = Mips::DSLL32;
4624 if (ImmValue == 32) {
4625 FirstShift = Mips::DSRL32;
4626 SecondShift = Mips::DSLL32;
4628 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4629 FirstShift = Mips::DSRL32;
4630 SecondShift = Mips::DSLL;
4635 ATReg = getATReg(Inst.getLoc());
4639 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4640 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4641 Inst.getLoc(), STI);
4642 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4650 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4651 const MCSubtargetInfo *STI) {
4652 MipsTargetStreamer &TOut = getTargetStreamer();
4653 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4654 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4656 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4657 if (FirstRegOp != SecondRegOp)
4658 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4660 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4661 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4666 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4667 const MCSubtargetInfo *STI) {
4668 MipsTargetStreamer &TOut = getTargetStreamer();
4669 unsigned ATReg = Mips::NoRegister;
4670 unsigned DstReg = Inst.getOperand(0).getReg();
4671 unsigned SrcReg = Inst.getOperand(1).getReg();
4672 int32_t ImmValue = Inst.getOperand(2).getImm();
4674 ATReg = getATReg(IDLoc);
4678 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, STI);
4680 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4681 SrcReg, ATReg, IDLoc, STI);
4683 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4688 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4689 const MCSubtargetInfo *STI) {
4690 MipsTargetStreamer &TOut = getTargetStreamer();
4691 unsigned ATReg = Mips::NoRegister;
4692 unsigned DstReg = Inst.getOperand(0).getReg();
4693 unsigned SrcReg = Inst.getOperand(1).getReg();
4694 unsigned TmpReg = Inst.getOperand(2).getReg();
4696 ATReg = getATReg(Inst.getLoc());
4700 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4701 SrcReg, TmpReg, IDLoc, STI);
4703 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4705 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4706 DstReg, DstReg, 0x1F, IDLoc, STI);
4708 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4711 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4713 MCContext & Context = TOut.getStreamer().getContext();
4714 MCSymbol * BrTarget = Context.createTempSymbol();
4716 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4718 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4719 if (AssemblerOptions.back()->isReorder())
4720 TOut.emitNop(IDLoc, STI);
4721 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4723 TOut.getStreamer().EmitLabel(BrTarget);
4725 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4730 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4731 const MCSubtargetInfo *STI) {
4732 MipsTargetStreamer &TOut = getTargetStreamer();
4733 unsigned ATReg = Mips::NoRegister;
4734 unsigned DstReg = Inst.getOperand(0).getReg();
4735 unsigned SrcReg = Inst.getOperand(1).getReg();
4736 unsigned TmpReg = Inst.getOperand(2).getReg();
4738 ATReg = getATReg(IDLoc);
4742 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4743 SrcReg, TmpReg, IDLoc, STI);
4745 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4746 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4748 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4750 MCContext & Context = TOut.getStreamer().getContext();
4751 MCSymbol * BrTarget = Context.createTempSymbol();
4753 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4755 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4756 if (AssemblerOptions.back()->isReorder())
4757 TOut.emitNop(IDLoc, STI);
4758 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4760 TOut.getStreamer().EmitLabel(BrTarget);
4766 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4767 const MCSubtargetInfo *STI) {
4768 MipsTargetStreamer &TOut = getTargetStreamer();
4769 unsigned DstReg = Inst.getOperand(0).getReg();
4770 unsigned SrcReg = Inst.getOperand(1).getReg();
4771 unsigned TmpReg = Inst.getOperand(2).getReg();
4773 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4774 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4779 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4780 // lw $<reg+1>>, offset+4($reg2)'
4781 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4782 // sw $<reg+1>>, offset+4($reg2)'
4784 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4786 const MCSubtargetInfo *STI,
4791 warnIfNoMacro(IDLoc);
4793 MipsTargetStreamer &TOut = getTargetStreamer();
4794 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4795 unsigned FirstReg = Inst.getOperand(0).getReg();
4796 unsigned SecondReg = nextReg(FirstReg);
4797 unsigned BaseReg = Inst.getOperand(1).getReg();
4801 warnIfRegIndexIsAT(FirstReg, IDLoc);
4803 assert(Inst.getOperand(2).isImm() &&
4804 "Offset for load macro is not immediate!");
4806 MCOperand &FirstOffset = Inst.getOperand(2);
4807 signed NextOffset = FirstOffset.getImm() + 4;
4808 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4810 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4813 // For loads, clobber the base register with the second load instead of the
4814 // first if the BaseReg == FirstReg.
4815 if (FirstReg != BaseReg || !IsLoad) {
4816 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4817 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4819 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4820 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4826 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4827 const MCSubtargetInfo *STI) {
4829 warnIfNoMacro(IDLoc);
4830 MipsTargetStreamer &TOut = getTargetStreamer();
4832 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4833 Inst.getOperand(2).getReg() != Mips::ZERO) {
4834 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4835 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4837 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4838 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4843 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4844 Reg = Inst.getOperand(2).getReg();
4846 Reg = Inst.getOperand(1).getReg();
4848 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4852 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4853 const MCSubtargetInfo *STI) {
4854 warnIfNoMacro(IDLoc);
4855 MipsTargetStreamer &TOut = getTargetStreamer();
4858 int64_t Imm = Inst.getOperand(2).getImm();
4859 unsigned Reg = Inst.getOperand(1).getReg();
4862 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4863 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4867 if (Reg == Mips::ZERO) {
4868 Warning(IDLoc, "comparison is always false");
4869 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4870 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4874 if (Imm > -0x8000 && Imm < 0) {
4876 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4881 if (!isUInt<16>(Imm)) {
4882 unsigned ATReg = getATReg(IDLoc);
4886 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4890 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4891 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4892 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4893 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4897 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4899 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4900 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4904 // Map the DSP accumulator and control register to the corresponding gpr
4905 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
4906 // do not map the DSP registers contigously to gpr registers.
4907 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
4908 switch (Inst.getOpcode()) {
4911 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4921 llvm_unreachable("Unknown register for 'mttr' alias!");
4925 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4935 llvm_unreachable("Unknown register for 'mttr' alias!");
4939 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4949 llvm_unreachable("Unknown register for 'mttr' alias!");
4955 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
4959 // Map the floating point register operand to the corresponding register
4961 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
4962 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
4963 case Mips::F0: return Mips::ZERO;
4964 case Mips::F1: return Mips::AT;
4965 case Mips::F2: return Mips::V0;
4966 case Mips::F3: return Mips::V1;
4967 case Mips::F4: return Mips::A0;
4968 case Mips::F5: return Mips::A1;
4969 case Mips::F6: return Mips::A2;
4970 case Mips::F7: return Mips::A3;
4971 case Mips::F8: return Mips::T0;
4972 case Mips::F9: return Mips::T1;
4973 case Mips::F10: return Mips::T2;
4974 case Mips::F11: return Mips::T3;
4975 case Mips::F12: return Mips::T4;
4976 case Mips::F13: return Mips::T5;
4977 case Mips::F14: return Mips::T6;
4978 case Mips::F15: return Mips::T7;
4979 case Mips::F16: return Mips::S0;
4980 case Mips::F17: return Mips::S1;
4981 case Mips::F18: return Mips::S2;
4982 case Mips::F19: return Mips::S3;
4983 case Mips::F20: return Mips::S4;
4984 case Mips::F21: return Mips::S5;
4985 case Mips::F22: return Mips::S6;
4986 case Mips::F23: return Mips::S7;
4987 case Mips::F24: return Mips::T8;
4988 case Mips::F25: return Mips::T9;
4989 case Mips::F26: return Mips::K0;
4990 case Mips::F27: return Mips::K1;
4991 case Mips::F28: return Mips::GP;
4992 case Mips::F29: return Mips::SP;
4993 case Mips::F30: return Mips::FP;
4994 case Mips::F31: return Mips::RA;
4995 default: llvm_unreachable("Unknown register for mttc1 alias!");
4999 // Map the coprocessor operand the corresponding gpr register operand.
5000 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5001 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5002 case Mips::COP00: return Mips::ZERO;
5003 case Mips::COP01: return Mips::AT;
5004 case Mips::COP02: return Mips::V0;
5005 case Mips::COP03: return Mips::V1;
5006 case Mips::COP04: return Mips::A0;
5007 case Mips::COP05: return Mips::A1;
5008 case Mips::COP06: return Mips::A2;
5009 case Mips::COP07: return Mips::A3;
5010 case Mips::COP08: return Mips::T0;
5011 case Mips::COP09: return Mips::T1;
5012 case Mips::COP010: return Mips::T2;
5013 case Mips::COP011: return Mips::T3;
5014 case Mips::COP012: return Mips::T4;
5015 case Mips::COP013: return Mips::T5;
5016 case Mips::COP014: return Mips::T6;
5017 case Mips::COP015: return Mips::T7;
5018 case Mips::COP016: return Mips::S0;
5019 case Mips::COP017: return Mips::S1;
5020 case Mips::COP018: return Mips::S2;
5021 case Mips::COP019: return Mips::S3;
5022 case Mips::COP020: return Mips::S4;
5023 case Mips::COP021: return Mips::S5;
5024 case Mips::COP022: return Mips::S6;
5025 case Mips::COP023: return Mips::S7;
5026 case Mips::COP024: return Mips::T8;
5027 case Mips::COP025: return Mips::T9;
5028 case Mips::COP026: return Mips::K0;
5029 case Mips::COP027: return Mips::K1;
5030 case Mips::COP028: return Mips::GP;
5031 case Mips::COP029: return Mips::SP;
5032 case Mips::COP030: return Mips::FP;
5033 case Mips::COP031: return Mips::RA;
5034 default: llvm_unreachable("Unknown register for mttc0 alias!");
5038 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5039 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5040 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5041 const MCSubtargetInfo *STI) {
5042 MipsTargetStreamer &TOut = getTargetStreamer();
5047 bool IsMFTR = false;
5048 switch (Inst.getOpcode()) {
5054 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5055 sel = Inst.getOperand(2).getImm();
5061 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5073 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5081 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5088 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5095 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5099 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5102 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5103 : Inst.getOperand(0).getReg());
5105 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5111 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5112 const OperandVector &Operands) {
5113 switch (Inst.getOpcode()) {
5115 return Match_Success;
5118 if (static_cast<MipsOperand &>(*Operands[1])
5119 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5120 return Match_Success;
5121 return Match_RequiresSameSrcAndDst;
5125 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5126 switch (Inst.getOpcode()) {
5127 // As described by the MIPSR6 spec, daui must not use the zero operand for
5128 // its source operand.
5130 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5131 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5132 return Match_RequiresNoZeroRegister;
5133 return Match_Success;
5134 // As described by the Mips32r2 spec, the registers Rd and Rs for
5135 // jalr.hb must be different.
5136 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5137 // and registers Rd and Base for microMIPS lwp instruction
5139 case Mips::JALR_HB64:
5140 case Mips::JALRC_HB_MMR6:
5141 case Mips::JALRC_MMR6:
5142 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5143 return Match_RequiresDifferentSrcAndDst;
5144 return Match_Success;
5146 case Mips::LWP_MMR6:
5147 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5148 return Match_RequiresDifferentSrcAndDst;
5149 return Match_Success;
5151 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5152 return Match_NonZeroOperandForSync;
5153 return Match_Success;
5154 // As described the MIPSR6 spec, the compact branches that compare registers
5156 // a) Not use the zero register.
5157 // b) Not use the same register twice.
5158 // c) rs < rt for bnec, beqc.
5159 // NB: For this case, the encoding will swap the operands as their
5160 // ordering doesn't matter. GAS performs this transformation too.
5161 // Hence, that constraint does not have to be enforced.
5163 // The compact branches that branch iff the signed addition of two registers
5164 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5165 // operand swapping. They do not have restriction of using the zero register.
5166 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5167 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5168 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5169 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5170 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5171 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5178 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5179 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5180 return Match_RequiresNoZeroRegister;
5181 return Match_Success;
5182 case Mips::BGEC: case Mips::BGEC_MMR6:
5183 case Mips::BLTC: case Mips::BLTC_MMR6:
5184 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5185 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5186 case Mips::BEQC: case Mips::BEQC_MMR6:
5187 case Mips::BNEC: case Mips::BNEC_MMR6:
5194 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5195 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5196 return Match_RequiresNoZeroRegister;
5197 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5198 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5199 return Match_RequiresNoZeroRegister;
5200 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5201 return Match_RequiresDifferentOperands;
5202 return Match_Success;
5204 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5205 "Operands must be immediates for dins!");
5206 const signed Pos = Inst.getOperand(2).getImm();
5207 const signed Size = Inst.getOperand(3).getImm();
5208 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5209 return Match_RequiresPosSizeRange0_32;
5210 return Match_Success;
5214 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5215 "Operands must be immediates for dinsm/dinsu!");
5216 const signed Pos = Inst.getOperand(2).getImm();
5217 const signed Size = Inst.getOperand(3).getImm();
5218 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5219 return Match_RequiresPosSizeRange33_64;
5220 return Match_Success;
5223 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5224 "Operands must be immediates for DEXTM!");
5225 const signed Pos = Inst.getOperand(2).getImm();
5226 const signed Size = Inst.getOperand(3).getImm();
5227 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5228 return Match_RequiresPosSizeUImm6;
5229 return Match_Success;
5233 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5234 "Operands must be immediates for dextm/dextu!");
5235 const signed Pos = Inst.getOperand(2).getImm();
5236 const signed Size = Inst.getOperand(3).getImm();
5237 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5238 return Match_RequiresPosSizeRange33_64;
5239 return Match_Success;
5243 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5244 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5245 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5246 return Match_NoFCCRegisterForCurrentISA;
5248 return Match_Success;
5252 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5253 uint64_t ErrorInfo) {
5254 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5255 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5256 if (ErrorLoc == SMLoc())
5263 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5264 OperandVector &Operands,
5266 uint64_t &ErrorInfo,
5267 bool MatchingInlineAsm) {
5269 unsigned MatchResult =
5270 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5272 switch (MatchResult) {
5274 if (processInstruction(Inst, IDLoc, Out, STI))
5277 case Match_MissingFeature:
5278 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5280 case Match_InvalidOperand: {
5281 SMLoc ErrorLoc = IDLoc;
5282 if (ErrorInfo != ~0ULL) {
5283 if (ErrorInfo >= Operands.size())
5284 return Error(IDLoc, "too few operands for instruction");
5286 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5287 if (ErrorLoc == SMLoc())
5291 return Error(ErrorLoc, "invalid operand for instruction");
5293 case Match_NonZeroOperandForSync:
5294 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5295 case Match_MnemonicFail:
5296 return Error(IDLoc, "invalid instruction");
5297 case Match_RequiresDifferentSrcAndDst:
5298 return Error(IDLoc, "source and destination must be different");
5299 case Match_RequiresDifferentOperands:
5300 return Error(IDLoc, "registers must be different");
5301 case Match_RequiresNoZeroRegister:
5302 return Error(IDLoc, "invalid operand ($zero) for instruction");
5303 case Match_RequiresSameSrcAndDst:
5304 return Error(IDLoc, "source and destination must match");
5305 case Match_NoFCCRegisterForCurrentISA:
5306 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5307 "non-zero fcc register doesn't exist in current ISA level");
5309 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5311 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5312 "expected 1-bit unsigned immediate");
5314 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5315 "expected 2-bit unsigned immediate");
5317 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5318 "expected immediate in range 1 .. 4");
5320 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5321 "expected 3-bit unsigned immediate");
5323 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5324 "expected 4-bit unsigned immediate");
5326 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5327 "expected 4-bit signed immediate");
5329 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5330 "expected 5-bit unsigned immediate");
5332 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5333 "expected 5-bit signed immediate");
5335 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5336 "expected immediate in range 1 .. 32");
5337 case Match_UImm5_32:
5338 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5339 "expected immediate in range 32 .. 63");
5340 case Match_UImm5_33:
5341 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5342 "expected immediate in range 33 .. 64");
5343 case Match_UImm5_0_Report_UImm6:
5344 // This is used on UImm5 operands that have a corresponding UImm5_32
5345 // operand to avoid confusing the user.
5346 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5347 "expected 6-bit unsigned immediate");
5348 case Match_UImm5_Lsl2:
5349 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5350 "expected both 7-bit unsigned immediate and multiple of 4");
5351 case Match_UImmRange2_64:
5352 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5353 "expected immediate in range 2 .. 64");
5355 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5356 "expected 6-bit unsigned immediate");
5357 case Match_UImm6_Lsl2:
5358 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5359 "expected both 8-bit unsigned immediate and multiple of 4");
5361 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5362 "expected 6-bit signed immediate");
5364 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5365 "expected 7-bit unsigned immediate");
5366 case Match_UImm7_N1:
5367 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5368 "expected immediate in range -1 .. 126");
5369 case Match_SImm7_Lsl2:
5370 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5371 "expected both 9-bit signed immediate and multiple of 4");
5373 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5374 "expected 8-bit unsigned immediate");
5375 case Match_UImm10_0:
5376 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5377 "expected 10-bit unsigned immediate");
5378 case Match_SImm10_0:
5379 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5380 "expected 10-bit signed immediate");
5381 case Match_SImm11_0:
5382 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5383 "expected 11-bit signed immediate");
5385 case Match_UImm16_Relaxed:
5386 case Match_UImm16_AltRelaxed:
5387 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5388 "expected 16-bit unsigned immediate");
5390 case Match_SImm16_Relaxed:
5391 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5392 "expected 16-bit signed immediate");
5393 case Match_SImm19_Lsl2:
5394 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5395 "expected both 19-bit signed immediate and multiple of 4");
5396 case Match_UImm20_0:
5397 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5398 "expected 20-bit unsigned immediate");
5399 case Match_UImm26_0:
5400 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5401 "expected 26-bit unsigned immediate");
5403 case Match_SImm32_Relaxed:
5404 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5405 "expected 32-bit signed immediate");
5406 case Match_UImm32_Coerced:
5407 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5408 "expected 32-bit immediate");
5409 case Match_MemSImm9:
5410 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5411 "expected memory with 9-bit signed offset");
5412 case Match_MemSImm10:
5413 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5414 "expected memory with 10-bit signed offset");
5415 case Match_MemSImm10Lsl1:
5416 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5417 "expected memory with 11-bit signed offset and multiple of 2");
5418 case Match_MemSImm10Lsl2:
5419 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5420 "expected memory with 12-bit signed offset and multiple of 4");
5421 case Match_MemSImm10Lsl3:
5422 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5423 "expected memory with 13-bit signed offset and multiple of 8");
5424 case Match_MemSImm11:
5425 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5426 "expected memory with 11-bit signed offset");
5427 case Match_MemSImm12:
5428 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5429 "expected memory with 12-bit signed offset");
5430 case Match_MemSImm16:
5431 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5432 "expected memory with 16-bit signed offset");
5433 case Match_RequiresPosSizeRange0_32: {
5434 SMLoc ErrorStart = Operands[3]->getStartLoc();
5435 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5436 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5437 SMRange(ErrorStart, ErrorEnd));
5439 case Match_RequiresPosSizeUImm6: {
5440 SMLoc ErrorStart = Operands[3]->getStartLoc();
5441 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5442 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5443 SMRange(ErrorStart, ErrorEnd));
5445 case Match_RequiresPosSizeRange33_64: {
5446 SMLoc ErrorStart = Operands[3]->getStartLoc();
5447 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5448 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5449 SMRange(ErrorStart, ErrorEnd));
5453 llvm_unreachable("Implement any new match types added!");
5456 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5457 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5458 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5459 ") without \".set noat\"");
5462 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5463 if (!AssemblerOptions.back()->isMacro())
5464 Warning(Loc, "macro instruction expanded into multiple instructions");
5468 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5469 SMRange Range, bool ShowColors) {
5470 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5471 Range, SMFixIt(Range, FixMsg),
5475 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5478 CC = StringSwitch<unsigned>(Name)
5480 .Cases("at", "AT", 1)
5514 if (!(isABI_N32() || isABI_N64()))
5517 if (12 <= CC && CC <= 15) {
5518 // Name is one of t4-t7
5519 AsmToken RegTok = getLexer().peekTok();
5520 SMRange RegRange = RegTok.getLocRange();
5522 StringRef FixedName = StringSwitch<StringRef>(Name)
5528 assert(FixedName != "" && "Register name is not one of t4-t7.");
5530 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5531 "Did you mean $" + FixedName + "?", RegRange);
5534 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5535 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5536 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5537 if (8 <= CC && CC <= 11)
5541 CC = StringSwitch<unsigned>(Name)
5553 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5556 CC = StringSwitch<unsigned>(Name)
5557 .Case("hwr_cpunum", 0)
5558 .Case("hwr_synci_step", 1)
5560 .Case("hwr_ccres", 3)
5561 .Case("hwr_ulr", 29)
5567 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5568 if (Name[0] == 'f') {
5569 StringRef NumString = Name.substr(1);
5571 if (NumString.getAsInteger(10, IntVal))
5572 return -1; // This is not an integer.
5573 if (IntVal > 31) // Maximum index for fpu register.
5580 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5581 if (Name.startswith("fcc")) {
5582 StringRef NumString = Name.substr(3);
5584 if (NumString.getAsInteger(10, IntVal))
5585 return -1; // This is not an integer.
5586 if (IntVal > 7) // There are only 8 fcc registers.
5593 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5594 if (Name.startswith("ac")) {
5595 StringRef NumString = Name.substr(2);
5597 if (NumString.getAsInteger(10, IntVal))
5598 return -1; // This is not an integer.
5599 if (IntVal > 3) // There are only 3 acc registers.
5606 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5609 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5618 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5621 CC = StringSwitch<unsigned>(Name)
5624 .Case("msaaccess", 2)
5626 .Case("msamodify", 4)
5627 .Case("msarequest", 5)
5629 .Case("msaunmap", 7)
5635 bool MipsAsmParser::canUseATReg() {
5636 return AssemblerOptions.back()->getATRegIndex() != 0;
5639 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5640 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5642 reportParseError(Loc,
5643 "pseudo-instruction requires $at, which is not available");
5646 unsigned AT = getReg(
5647 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5651 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5652 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5655 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5656 MCAsmParser &Parser = getParser();
5657 DEBUG(dbgs() << "parseOperand\n");
5659 // Check if the current operand has a custom associated parser, if so, try to
5660 // custom parse the operand, or fallback to the general approach.
5661 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5662 if (ResTy == MatchOperand_Success)
5664 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5665 // there was a match, but an error occurred, in which case, just return that
5666 // the operand parsing failed.
5667 if (ResTy == MatchOperand_ParseFail)
5670 DEBUG(dbgs() << ".. Generic Parser\n");
5672 switch (getLexer().getKind()) {
5673 case AsmToken::Dollar: {
5674 // Parse the register.
5675 SMLoc S = Parser.getTok().getLoc();
5677 // Almost all registers have been parsed by custom parsers. There is only
5678 // one exception to this. $zero (and it's alias $0) will reach this point
5679 // for div, divu, and similar instructions because it is not an operand
5680 // to the instruction definition but an explicit register. Special case
5681 // this situation for now.
5682 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5685 // Maybe it is a symbol reference.
5686 StringRef Identifier;
5687 if (Parser.parseIdentifier(Identifier))
5690 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5691 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5692 // Otherwise create a symbol reference.
5694 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5696 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5700 DEBUG(dbgs() << ".. generic integer expression\n");
5703 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5704 if (getParser().parseExpression(Expr))
5707 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5709 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5712 } // switch(getLexer().getKind())
5716 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5717 switch (Expr->getKind()) {
5718 case MCExpr::Constant:
5720 case MCExpr::SymbolRef:
5721 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5722 case MCExpr::Binary: {
5723 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
5724 if (!isEvaluated(BE->getLHS()))
5726 return isEvaluated(BE->getRHS());
5729 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5730 case MCExpr::Target:
5736 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5738 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5739 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5740 if (ResTy == MatchOperand_Success) {
5741 assert(Operands.size() == 1);
5742 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5743 StartLoc = Operand.getStartLoc();
5744 EndLoc = Operand.getEndLoc();
5746 // AFAIK, we only support numeric registers and named GPR's in CFI
5748 // Don't worry about eating tokens before failing. Using an unrecognised
5749 // register is a parse error.
5750 if (Operand.isGPRAsmReg()) {
5751 // Resolve to GPR32 or GPR64 appropriately.
5752 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5755 return (RegNo == (unsigned)-1);
5758 assert(Operands.size() == 0);
5759 return (RegNo == (unsigned)-1);
5762 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5766 return getParser().parseParenExprOfDepth(0, Res, S);
5767 return getParser().parseExpression(Res);
5770 OperandMatchResultTy
5771 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5772 MCAsmParser &Parser = getParser();
5773 DEBUG(dbgs() << "parseMemOperand\n");
5774 const MCExpr *IdVal = nullptr;
5776 bool isParenExpr = false;
5777 OperandMatchResultTy Res = MatchOperand_NoMatch;
5778 // First operand is the offset.
5779 S = Parser.getTok().getLoc();
5781 if (getLexer().getKind() == AsmToken::LParen) {
5786 if (getLexer().getKind() != AsmToken::Dollar) {
5787 if (parseMemOffset(IdVal, isParenExpr))
5788 return MatchOperand_ParseFail;
5790 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5791 if (Tok.isNot(AsmToken::LParen)) {
5792 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5793 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5795 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5796 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5797 return MatchOperand_Success;
5799 if (Tok.is(AsmToken::EndOfStatement)) {
5801 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5803 // Zero register assumed, add a memory operand with ZERO as its base.
5804 // "Base" will be managed by k_Memory.
5805 auto Base = MipsOperand::createGPRReg(
5806 0, "0", getContext().getRegisterInfo(), S, E, *this);
5808 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5809 return MatchOperand_Success;
5811 MCBinaryExpr::Opcode Opcode;
5812 // GAS and LLVM treat comparison operators different. GAS will generate -1
5813 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5814 // highly unlikely to be found in a memory offset expression, we don't
5816 switch (Tok.getKind()) {
5817 case AsmToken::Plus:
5818 Opcode = MCBinaryExpr::Add;
5821 case AsmToken::Minus:
5822 Opcode = MCBinaryExpr::Sub;
5825 case AsmToken::Star:
5826 Opcode = MCBinaryExpr::Mul;
5829 case AsmToken::Pipe:
5830 Opcode = MCBinaryExpr::Or;
5834 Opcode = MCBinaryExpr::And;
5837 case AsmToken::LessLess:
5838 Opcode = MCBinaryExpr::Shl;
5841 case AsmToken::GreaterGreater:
5842 Opcode = MCBinaryExpr::LShr;
5845 case AsmToken::Caret:
5846 Opcode = MCBinaryExpr::Xor;
5849 case AsmToken::Slash:
5850 Opcode = MCBinaryExpr::Div;
5853 case AsmToken::Percent:
5854 Opcode = MCBinaryExpr::Mod;
5858 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5859 return MatchOperand_ParseFail;
5861 const MCExpr * NextExpr;
5862 if (getParser().parseExpression(NextExpr))
5863 return MatchOperand_ParseFail;
5864 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5867 Parser.Lex(); // Eat the '(' token.
5870 Res = parseAnyRegister(Operands);
5871 if (Res != MatchOperand_Success)
5874 if (Parser.getTok().isNot(AsmToken::RParen)) {
5875 Error(Parser.getTok().getLoc(), "')' expected");
5876 return MatchOperand_ParseFail;
5879 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5881 Parser.Lex(); // Eat the ')' token.
5884 IdVal = MCConstantExpr::create(0, getContext());
5886 // Replace the register operand with the memory operand.
5887 std::unique_ptr<MipsOperand> op(
5888 static_cast<MipsOperand *>(Operands.back().release()));
5889 // Remove the register from the operands.
5890 // "op" will be managed by k_Memory.
5891 Operands.pop_back();
5892 // Add the memory operand.
5893 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5895 if (IdVal->evaluateAsAbsolute(Imm))
5896 IdVal = MCConstantExpr::create(Imm, getContext());
5897 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5898 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5902 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5903 return MatchOperand_Success;
5906 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5907 MCAsmParser &Parser = getParser();
5908 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5910 SMLoc S = Parser.getTok().getLoc();
5912 if (Sym->isVariable())
5913 Expr = Sym->getVariableValue();
5916 if (Expr->getKind() == MCExpr::SymbolRef) {
5917 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5918 StringRef DefSymbol = Ref->getSymbol().getName();
5919 if (DefSymbol.startswith("$")) {
5920 OperandMatchResultTy ResTy =
5921 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5922 if (ResTy == MatchOperand_Success) {
5925 } else if (ResTy == MatchOperand_ParseFail)
5926 llvm_unreachable("Should never ParseFail");
5934 OperandMatchResultTy
5935 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
5936 StringRef Identifier,
5938 int Index = matchCPURegisterName(Identifier);
5940 Operands.push_back(MipsOperand::createGPRReg(
5941 Index, Identifier, getContext().getRegisterInfo(), S,
5942 getLexer().getLoc(), *this));
5943 return MatchOperand_Success;
5946 Index = matchHWRegsRegisterName(Identifier);
5948 Operands.push_back(MipsOperand::createHWRegsReg(
5949 Index, Identifier, getContext().getRegisterInfo(), S,
5950 getLexer().getLoc(), *this));
5951 return MatchOperand_Success;
5954 Index = matchFPURegisterName(Identifier);
5956 Operands.push_back(MipsOperand::createFGRReg(
5957 Index, Identifier, getContext().getRegisterInfo(), S,
5958 getLexer().getLoc(), *this));
5959 return MatchOperand_Success;
5962 Index = matchFCCRegisterName(Identifier);
5964 Operands.push_back(MipsOperand::createFCCReg(
5965 Index, Identifier, getContext().getRegisterInfo(), S,
5966 getLexer().getLoc(), *this));
5967 return MatchOperand_Success;
5970 Index = matchACRegisterName(Identifier);
5972 Operands.push_back(MipsOperand::createACCReg(
5973 Index, Identifier, getContext().getRegisterInfo(), S,
5974 getLexer().getLoc(), *this));
5975 return MatchOperand_Success;
5978 Index = matchMSA128RegisterName(Identifier);
5980 Operands.push_back(MipsOperand::createMSA128Reg(
5981 Index, Identifier, getContext().getRegisterInfo(), S,
5982 getLexer().getLoc(), *this));
5983 return MatchOperand_Success;
5986 Index = matchMSA128CtrlRegisterName(Identifier);
5988 Operands.push_back(MipsOperand::createMSACtrlReg(
5989 Index, Identifier, getContext().getRegisterInfo(), S,
5990 getLexer().getLoc(), *this));
5991 return MatchOperand_Success;
5994 return MatchOperand_NoMatch;
5997 OperandMatchResultTy
5998 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
5999 MCAsmParser &Parser = getParser();
6000 auto Token = Parser.getLexer().peekTok(false);
6002 if (Token.is(AsmToken::Identifier)) {
6003 DEBUG(dbgs() << ".. identifier\n");
6004 StringRef Identifier = Token.getIdentifier();
6005 OperandMatchResultTy ResTy =
6006 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6008 } else if (Token.is(AsmToken::Integer)) {
6009 DEBUG(dbgs() << ".. integer\n");
6010 Operands.push_back(MipsOperand::createNumericReg(
6011 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
6012 Token.getLoc(), *this));
6013 return MatchOperand_Success;
6016 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
6018 return MatchOperand_NoMatch;
6021 OperandMatchResultTy
6022 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6023 MCAsmParser &Parser = getParser();
6024 DEBUG(dbgs() << "parseAnyRegister\n");
6026 auto Token = Parser.getTok();
6028 SMLoc S = Token.getLoc();
6030 if (Token.isNot(AsmToken::Dollar)) {
6031 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6032 if (Token.is(AsmToken::Identifier)) {
6033 if (searchSymbolAlias(Operands))
6034 return MatchOperand_Success;
6036 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6037 return MatchOperand_NoMatch;
6039 DEBUG(dbgs() << ".. $\n");
6041 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6042 if (ResTy == MatchOperand_Success) {
6044 Parser.Lex(); // identifier
6049 OperandMatchResultTy
6050 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6051 MCAsmParser &Parser = getParser();
6052 DEBUG(dbgs() << "parseJumpTarget\n");
6054 SMLoc S = getLexer().getLoc();
6056 // Registers are a valid target and have priority over symbols.
6057 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6058 if (ResTy != MatchOperand_NoMatch)
6061 // Integers and expressions are acceptable
6062 const MCExpr *Expr = nullptr;
6063 if (Parser.parseExpression(Expr)) {
6064 // We have no way of knowing if a symbol was consumed so we must ParseFail
6065 return MatchOperand_ParseFail;
6068 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6069 return MatchOperand_Success;
6072 OperandMatchResultTy
6073 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6074 MCAsmParser &Parser = getParser();
6075 const MCExpr *IdVal;
6076 // If the first token is '$' we may have register operand. We have to reject
6077 // cases where it is not a register. Complicating the matter is that
6078 // register names are not reserved across all ABIs.
6079 // Peek past the dollar to see if it's a register name for this ABI.
6080 SMLoc S = Parser.getTok().getLoc();
6081 if (Parser.getTok().is(AsmToken::Dollar)) {
6082 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6083 ? MatchOperand_ParseFail
6084 : MatchOperand_NoMatch;
6086 if (getParser().parseExpression(IdVal))
6087 return MatchOperand_ParseFail;
6088 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6090 return MatchOperand_NoMatch;
6091 int64_t Val = MCE->getValue();
6092 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6093 Operands.push_back(MipsOperand::CreateImm(
6094 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6095 return MatchOperand_Success;
6098 OperandMatchResultTy
6099 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6100 MCAsmParser &Parser = getParser();
6101 SmallVector<unsigned, 10> Regs;
6103 unsigned PrevReg = Mips::NoRegister;
6104 bool RegRange = false;
6105 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6107 if (Parser.getTok().isNot(AsmToken::Dollar))
6108 return MatchOperand_ParseFail;
6110 SMLoc S = Parser.getTok().getLoc();
6111 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6112 SMLoc E = getLexer().getLoc();
6113 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6114 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6116 // Remove last register operand because registers from register range
6117 // should be inserted first.
6118 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6119 (!isGP64bit() && RegNo == Mips::RA)) {
6120 Regs.push_back(RegNo);
6122 unsigned TmpReg = PrevReg + 1;
6123 while (TmpReg <= RegNo) {
6124 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6125 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6127 Error(E, "invalid register operand");
6128 return MatchOperand_ParseFail;
6132 Regs.push_back(TmpReg++);
6138 if ((PrevReg == Mips::NoRegister) &&
6139 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6140 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6141 Error(E, "$16 or $31 expected");
6142 return MatchOperand_ParseFail;
6143 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6144 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6146 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6147 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6149 Error(E, "invalid register operand");
6150 return MatchOperand_ParseFail;
6151 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6152 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6153 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6155 Error(E, "consecutive register numbers expected");
6156 return MatchOperand_ParseFail;
6159 Regs.push_back(RegNo);
6162 if (Parser.getTok().is(AsmToken::Minus))
6165 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6166 !Parser.getTok().isNot(AsmToken::Comma)) {
6167 Error(E, "',' or '-' expected");
6168 return MatchOperand_ParseFail;
6171 Lex(); // Consume comma or minus
6172 if (Parser.getTok().isNot(AsmToken::Dollar))
6178 SMLoc E = Parser.getTok().getLoc();
6179 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6180 parseMemOperand(Operands);
6181 return MatchOperand_Success;
6184 OperandMatchResultTy
6185 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
6186 MCAsmParser &Parser = getParser();
6188 SMLoc S = Parser.getTok().getLoc();
6189 if (parseAnyRegister(Operands) != MatchOperand_Success)
6190 return MatchOperand_ParseFail;
6192 SMLoc E = Parser.getTok().getLoc();
6193 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
6195 Operands.pop_back();
6196 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
6197 return MatchOperand_Success;
6200 OperandMatchResultTy
6201 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
6202 MCAsmParser &Parser = getParser();
6203 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6204 SmallVector<unsigned, 10> Regs;
6206 if (Parser.getTok().isNot(AsmToken::Dollar))
6207 return MatchOperand_ParseFail;
6209 SMLoc S = Parser.getTok().getLoc();
6211 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6212 return MatchOperand_ParseFail;
6214 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
6215 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6216 Regs.push_back(RegNo);
6218 SMLoc E = Parser.getTok().getLoc();
6219 if (Parser.getTok().isNot(AsmToken::Comma)) {
6220 Error(E, "',' expected");
6221 return MatchOperand_ParseFail;
6227 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6228 return MatchOperand_ParseFail;
6230 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
6231 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6232 Regs.push_back(RegNo);
6234 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6236 return MatchOperand_Success;
6239 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6241 /// ::= '(', register, ')'
6242 /// handle it before we iterate so we don't get tripped up by the lack of
6244 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6245 MCAsmParser &Parser = getParser();
6246 if (getLexer().is(AsmToken::LParen)) {
6248 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6250 if (parseOperand(Operands, Name)) {
6251 SMLoc Loc = getLexer().getLoc();
6252 return Error(Loc, "unexpected token in argument list");
6254 if (Parser.getTok().isNot(AsmToken::RParen)) {
6255 SMLoc Loc = getLexer().getLoc();
6256 return Error(Loc, "unexpected token, expected ')'");
6259 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6265 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6266 /// either one of these.
6267 /// ::= '[', register, ']'
6268 /// ::= '[', integer, ']'
6269 /// handle it before we iterate so we don't get tripped up by the lack of
6271 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6272 OperandVector &Operands) {
6273 MCAsmParser &Parser = getParser();
6274 if (getLexer().is(AsmToken::LBrac)) {
6276 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6278 if (parseOperand(Operands, Name)) {
6279 SMLoc Loc = getLexer().getLoc();
6280 return Error(Loc, "unexpected token in argument list");
6282 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6283 SMLoc Loc = getLexer().getLoc();
6284 return Error(Loc, "unexpected token, expected ']'");
6287 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6293 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6294 SMLoc NameLoc, OperandVector &Operands) {
6295 MCAsmParser &Parser = getParser();
6296 DEBUG(dbgs() << "ParseInstruction\n");
6298 // We have reached first instruction, module directive are now forbidden.
6299 getTargetStreamer().forbidModuleDirective();
6301 // Check if we have valid mnemonic
6302 if (!mnemonicIsValid(Name, 0)) {
6303 return Error(NameLoc, "unknown instruction");
6305 // First operand in MCInst is instruction mnemonic.
6306 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6308 // Read the remaining operands.
6309 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6310 // Read the first operand.
6311 if (parseOperand(Operands, Name)) {
6312 SMLoc Loc = getLexer().getLoc();
6313 return Error(Loc, "unexpected token in argument list");
6315 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6317 // AFAIK, parenthesis suffixes are never on the first operand
6319 while (getLexer().is(AsmToken::Comma)) {
6320 Parser.Lex(); // Eat the comma.
6321 // Parse and remember the operand.
6322 if (parseOperand(Operands, Name)) {
6323 SMLoc Loc = getLexer().getLoc();
6324 return Error(Loc, "unexpected token in argument list");
6326 // Parse bracket and parenthesis suffixes before we iterate
6327 if (getLexer().is(AsmToken::LBrac)) {
6328 if (parseBracketSuffix(Name, Operands))
6330 } else if (getLexer().is(AsmToken::LParen) &&
6331 parseParenSuffix(Name, Operands))
6335 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6336 SMLoc Loc = getLexer().getLoc();
6337 return Error(Loc, "unexpected token in argument list");
6339 Parser.Lex(); // Consume the EndOfStatement.
6343 // FIXME: Given that these have the same name, these should both be
6344 // consistent on affecting the Parser.
6345 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6346 SMLoc Loc = getLexer().getLoc();
6347 return Error(Loc, ErrorMsg);
6350 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6351 return Error(Loc, ErrorMsg);
6354 bool MipsAsmParser::parseSetNoAtDirective() {
6355 MCAsmParser &Parser = getParser();
6356 // Line should look like: ".set noat".
6358 // Set the $at register to $0.
6359 AssemblerOptions.back()->setATRegIndex(0);
6361 Parser.Lex(); // Eat "noat".
6363 // If this is not the end of the statement, report an error.
6364 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6365 reportParseError("unexpected token, expected end of statement");
6369 getTargetStreamer().emitDirectiveSetNoAt();
6370 Parser.Lex(); // Consume the EndOfStatement.
6374 bool MipsAsmParser::parseSetAtDirective() {
6375 // Line can be: ".set at", which sets $at to $1
6376 // or ".set at=$reg", which sets $at to $reg.
6377 MCAsmParser &Parser = getParser();
6378 Parser.Lex(); // Eat "at".
6380 if (getLexer().is(AsmToken::EndOfStatement)) {
6381 // No register was specified, so we set $at to $1.
6382 AssemblerOptions.back()->setATRegIndex(1);
6384 getTargetStreamer().emitDirectiveSetAt();
6385 Parser.Lex(); // Consume the EndOfStatement.
6389 if (getLexer().isNot(AsmToken::Equal)) {
6390 reportParseError("unexpected token, expected equals sign");
6393 Parser.Lex(); // Eat "=".
6395 if (getLexer().isNot(AsmToken::Dollar)) {
6396 if (getLexer().is(AsmToken::EndOfStatement)) {
6397 reportParseError("no register specified");
6400 reportParseError("unexpected token, expected dollar sign '$'");
6404 Parser.Lex(); // Eat "$".
6406 // Find out what "reg" is.
6408 const AsmToken &Reg = Parser.getTok();
6409 if (Reg.is(AsmToken::Identifier)) {
6410 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6411 } else if (Reg.is(AsmToken::Integer)) {
6412 AtRegNo = Reg.getIntVal();
6414 reportParseError("unexpected token, expected identifier or integer");
6418 // Check if $reg is a valid register. If it is, set $at to $reg.
6419 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6420 reportParseError("invalid register");
6423 Parser.Lex(); // Eat "reg".
6425 // If this is not the end of the statement, report an error.
6426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6427 reportParseError("unexpected token, expected end of statement");
6431 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6433 Parser.Lex(); // Consume the EndOfStatement.
6437 bool MipsAsmParser::parseSetReorderDirective() {
6438 MCAsmParser &Parser = getParser();
6440 // If this is not the end of the statement, report an error.
6441 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6442 reportParseError("unexpected token, expected end of statement");
6445 AssemblerOptions.back()->setReorder();
6446 getTargetStreamer().emitDirectiveSetReorder();
6447 Parser.Lex(); // Consume the EndOfStatement.
6451 bool MipsAsmParser::parseSetNoReorderDirective() {
6452 MCAsmParser &Parser = getParser();
6454 // If this is not the end of the statement, report an error.
6455 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6456 reportParseError("unexpected token, expected end of statement");
6459 AssemblerOptions.back()->setNoReorder();
6460 getTargetStreamer().emitDirectiveSetNoReorder();
6461 Parser.Lex(); // Consume the EndOfStatement.
6465 bool MipsAsmParser::parseSetMacroDirective() {
6466 MCAsmParser &Parser = getParser();
6468 // If this is not the end of the statement, report an error.
6469 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6470 reportParseError("unexpected token, expected end of statement");
6473 AssemblerOptions.back()->setMacro();
6474 getTargetStreamer().emitDirectiveSetMacro();
6475 Parser.Lex(); // Consume the EndOfStatement.
6479 bool MipsAsmParser::parseSetNoMacroDirective() {
6480 MCAsmParser &Parser = getParser();
6482 // If this is not the end of the statement, report an error.
6483 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6484 reportParseError("unexpected token, expected end of statement");
6487 if (AssemblerOptions.back()->isReorder()) {
6488 reportParseError("`noreorder' must be set before `nomacro'");
6491 AssemblerOptions.back()->setNoMacro();
6492 getTargetStreamer().emitDirectiveSetNoMacro();
6493 Parser.Lex(); // Consume the EndOfStatement.
6497 bool MipsAsmParser::parseSetMsaDirective() {
6498 MCAsmParser &Parser = getParser();
6501 // If this is not the end of the statement, report an error.
6502 if (getLexer().isNot(AsmToken::EndOfStatement))
6503 return reportParseError("unexpected token, expected end of statement");
6505 setFeatureBits(Mips::FeatureMSA, "msa");
6506 getTargetStreamer().emitDirectiveSetMsa();
6510 bool MipsAsmParser::parseSetNoMsaDirective() {
6511 MCAsmParser &Parser = getParser();
6514 // If this is not the end of the statement, report an error.
6515 if (getLexer().isNot(AsmToken::EndOfStatement))
6516 return reportParseError("unexpected token, expected end of statement");
6518 clearFeatureBits(Mips::FeatureMSA, "msa");
6519 getTargetStreamer().emitDirectiveSetNoMsa();
6523 bool MipsAsmParser::parseSetNoDspDirective() {
6524 MCAsmParser &Parser = getParser();
6525 Parser.Lex(); // Eat "nodsp".
6527 // If this is not the end of the statement, report an error.
6528 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6529 reportParseError("unexpected token, expected end of statement");
6533 clearFeatureBits(Mips::FeatureDSP, "dsp");
6534 getTargetStreamer().emitDirectiveSetNoDsp();
6538 bool MipsAsmParser::parseSetMips16Directive() {
6539 MCAsmParser &Parser = getParser();
6540 Parser.Lex(); // Eat "mips16".
6542 // If this is not the end of the statement, report an error.
6543 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6544 reportParseError("unexpected token, expected end of statement");
6548 setFeatureBits(Mips::FeatureMips16, "mips16");
6549 getTargetStreamer().emitDirectiveSetMips16();
6550 Parser.Lex(); // Consume the EndOfStatement.
6554 bool MipsAsmParser::parseSetNoMips16Directive() {
6555 MCAsmParser &Parser = getParser();
6556 Parser.Lex(); // Eat "nomips16".
6558 // If this is not the end of the statement, report an error.
6559 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6560 reportParseError("unexpected token, expected end of statement");
6564 clearFeatureBits(Mips::FeatureMips16, "mips16");
6565 getTargetStreamer().emitDirectiveSetNoMips16();
6566 Parser.Lex(); // Consume the EndOfStatement.
6570 bool MipsAsmParser::parseSetFpDirective() {
6571 MCAsmParser &Parser = getParser();
6572 MipsABIFlagsSection::FpABIKind FpAbiVal;
6573 // Line can be: .set fp=32
6576 Parser.Lex(); // Eat fp token
6577 AsmToken Tok = Parser.getTok();
6578 if (Tok.isNot(AsmToken::Equal)) {
6579 reportParseError("unexpected token, expected equals sign '='");
6582 Parser.Lex(); // Eat '=' token.
6583 Tok = Parser.getTok();
6585 if (!parseFpABIValue(FpAbiVal, ".set"))
6588 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6589 reportParseError("unexpected token, expected end of statement");
6592 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6593 Parser.Lex(); // Consume the EndOfStatement.
6597 bool MipsAsmParser::parseSetOddSPRegDirective() {
6598 MCAsmParser &Parser = getParser();
6600 Parser.Lex(); // Eat "oddspreg".
6601 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6602 reportParseError("unexpected token, expected end of statement");
6606 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6607 getTargetStreamer().emitDirectiveSetOddSPReg();
6611 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6612 MCAsmParser &Parser = getParser();
6614 Parser.Lex(); // Eat "nooddspreg".
6615 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6616 reportParseError("unexpected token, expected end of statement");
6620 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6621 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6625 bool MipsAsmParser::parseSetMtDirective() {
6626 MCAsmParser &Parser = getParser();
6627 Parser.Lex(); // Eat "mt".
6629 // If this is not the end of the statement, report an error.
6630 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6631 reportParseError("unexpected token, expected end of statement");
6635 setFeatureBits(Mips::FeatureMT, "mt");
6636 getTargetStreamer().emitDirectiveSetMt();
6637 Parser.Lex(); // Consume the EndOfStatement.
6641 bool MipsAsmParser::parseSetNoMtDirective() {
6642 MCAsmParser &Parser = getParser();
6643 Parser.Lex(); // Eat "nomt".
6645 // If this is not the end of the statement, report an error.
6646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6647 reportParseError("unexpected token, expected end of statement");
6651 clearFeatureBits(Mips::FeatureMT, "mt");
6653 getTargetStreamer().emitDirectiveSetNoMt();
6654 Parser.Lex(); // Consume the EndOfStatement.
6658 bool MipsAsmParser::parseSetPopDirective() {
6659 MCAsmParser &Parser = getParser();
6660 SMLoc Loc = getLexer().getLoc();
6663 if (getLexer().isNot(AsmToken::EndOfStatement))
6664 return reportParseError("unexpected token, expected end of statement");
6666 // Always keep an element on the options "stack" to prevent the user
6667 // from changing the initial options. This is how we remember them.
6668 if (AssemblerOptions.size() == 2)
6669 return reportParseError(Loc, ".set pop with no .set push");
6671 MCSubtargetInfo &STI = copySTI();
6672 AssemblerOptions.pop_back();
6673 setAvailableFeatures(
6674 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6675 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6677 getTargetStreamer().emitDirectiveSetPop();
6681 bool MipsAsmParser::parseSetPushDirective() {
6682 MCAsmParser &Parser = getParser();
6684 if (getLexer().isNot(AsmToken::EndOfStatement))
6685 return reportParseError("unexpected token, expected end of statement");
6687 // Create a copy of the current assembler options environment and push it.
6688 AssemblerOptions.push_back(
6689 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6691 getTargetStreamer().emitDirectiveSetPush();
6695 bool MipsAsmParser::parseSetSoftFloatDirective() {
6696 MCAsmParser &Parser = getParser();
6698 if (getLexer().isNot(AsmToken::EndOfStatement))
6699 return reportParseError("unexpected token, expected end of statement");
6701 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6702 getTargetStreamer().emitDirectiveSetSoftFloat();
6706 bool MipsAsmParser::parseSetHardFloatDirective() {
6707 MCAsmParser &Parser = getParser();
6709 if (getLexer().isNot(AsmToken::EndOfStatement))
6710 return reportParseError("unexpected token, expected end of statement");
6712 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6713 getTargetStreamer().emitDirectiveSetHardFloat();
6717 bool MipsAsmParser::parseSetAssignment() {
6719 const MCExpr *Value;
6720 MCAsmParser &Parser = getParser();
6722 if (Parser.parseIdentifier(Name))
6723 reportParseError("expected identifier after .set");
6725 if (getLexer().isNot(AsmToken::Comma))
6726 return reportParseError("unexpected token, expected comma");
6729 if (Parser.parseExpression(Value))
6730 return reportParseError("expected valid expression after comma");
6732 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6733 Sym->setVariableValue(Value);
6738 bool MipsAsmParser::parseSetMips0Directive() {
6739 MCAsmParser &Parser = getParser();
6741 if (getLexer().isNot(AsmToken::EndOfStatement))
6742 return reportParseError("unexpected token, expected end of statement");
6744 // Reset assembler options to their initial values.
6745 MCSubtargetInfo &STI = copySTI();
6746 setAvailableFeatures(
6747 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6748 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6749 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6751 getTargetStreamer().emitDirectiveSetMips0();
6755 bool MipsAsmParser::parseSetArchDirective() {
6756 MCAsmParser &Parser = getParser();
6758 if (getLexer().isNot(AsmToken::Equal))
6759 return reportParseError("unexpected token, expected equals sign");
6763 if (Parser.parseIdentifier(Arch))
6764 return reportParseError("expected arch identifier");
6766 StringRef ArchFeatureName =
6767 StringSwitch<StringRef>(Arch)
6768 .Case("mips1", "mips1")
6769 .Case("mips2", "mips2")
6770 .Case("mips3", "mips3")
6771 .Case("mips4", "mips4")
6772 .Case("mips5", "mips5")
6773 .Case("mips32", "mips32")
6774 .Case("mips32r2", "mips32r2")
6775 .Case("mips32r3", "mips32r3")
6776 .Case("mips32r5", "mips32r5")
6777 .Case("mips32r6", "mips32r6")
6778 .Case("mips64", "mips64")
6779 .Case("mips64r2", "mips64r2")
6780 .Case("mips64r3", "mips64r3")
6781 .Case("mips64r5", "mips64r5")
6782 .Case("mips64r6", "mips64r6")
6783 .Case("octeon", "cnmips")
6784 .Case("r4000", "mips3") // This is an implementation of Mips3.
6787 if (ArchFeatureName.empty())
6788 return reportParseError("unsupported architecture");
6790 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
6791 return reportParseError("mips64r6 does not support microMIPS");
6793 selectArch(ArchFeatureName);
6794 getTargetStreamer().emitDirectiveSetArch(Arch);
6798 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6799 MCAsmParser &Parser = getParser();
6801 if (getLexer().isNot(AsmToken::EndOfStatement))
6802 return reportParseError("unexpected token, expected end of statement");
6806 llvm_unreachable("Unimplemented feature");
6807 case Mips::FeatureDSP:
6808 setFeatureBits(Mips::FeatureDSP, "dsp");
6809 getTargetStreamer().emitDirectiveSetDsp();
6811 case Mips::FeatureDSPR2:
6812 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
6813 getTargetStreamer().emitDirectiveSetDspr2();
6815 case Mips::FeatureMicroMips:
6816 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6817 getTargetStreamer().emitDirectiveSetMicroMips();
6819 case Mips::FeatureMips1:
6820 selectArch("mips1");
6821 getTargetStreamer().emitDirectiveSetMips1();
6823 case Mips::FeatureMips2:
6824 selectArch("mips2");
6825 getTargetStreamer().emitDirectiveSetMips2();
6827 case Mips::FeatureMips3:
6828 selectArch("mips3");
6829 getTargetStreamer().emitDirectiveSetMips3();
6831 case Mips::FeatureMips4:
6832 selectArch("mips4");
6833 getTargetStreamer().emitDirectiveSetMips4();
6835 case Mips::FeatureMips5:
6836 selectArch("mips5");
6837 getTargetStreamer().emitDirectiveSetMips5();
6839 case Mips::FeatureMips32:
6840 selectArch("mips32");
6841 getTargetStreamer().emitDirectiveSetMips32();
6843 case Mips::FeatureMips32r2:
6844 selectArch("mips32r2");
6845 getTargetStreamer().emitDirectiveSetMips32R2();
6847 case Mips::FeatureMips32r3:
6848 selectArch("mips32r3");
6849 getTargetStreamer().emitDirectiveSetMips32R3();
6851 case Mips::FeatureMips32r5:
6852 selectArch("mips32r5");
6853 getTargetStreamer().emitDirectiveSetMips32R5();
6855 case Mips::FeatureMips32r6:
6856 selectArch("mips32r6");
6857 getTargetStreamer().emitDirectiveSetMips32R6();
6859 case Mips::FeatureMips64:
6860 selectArch("mips64");
6861 getTargetStreamer().emitDirectiveSetMips64();
6863 case Mips::FeatureMips64r2:
6864 selectArch("mips64r2");
6865 getTargetStreamer().emitDirectiveSetMips64R2();
6867 case Mips::FeatureMips64r3:
6868 selectArch("mips64r3");
6869 getTargetStreamer().emitDirectiveSetMips64R3();
6871 case Mips::FeatureMips64r5:
6872 selectArch("mips64r5");
6873 getTargetStreamer().emitDirectiveSetMips64R5();
6875 case Mips::FeatureMips64r6:
6876 selectArch("mips64r6");
6877 getTargetStreamer().emitDirectiveSetMips64R6();
6883 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6884 MCAsmParser &Parser = getParser();
6885 if (getLexer().isNot(AsmToken::Comma)) {
6886 SMLoc Loc = getLexer().getLoc();
6887 return Error(Loc, ErrorStr);
6890 Parser.Lex(); // Eat the comma.
6894 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
6895 // In this class, it is only used for .cprestore.
6896 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
6897 // MipsTargetELFStreamer and MipsAsmParser.
6898 bool MipsAsmParser::isPicAndNotNxxAbi() {
6899 return inPicMode() && !(isABI_N32() || isABI_N64());
6902 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
6903 if (AssemblerOptions.back()->isReorder())
6904 Warning(Loc, ".cpload should be inside a noreorder section");
6906 if (inMips16Mode()) {
6907 reportParseError(".cpload is not supported in Mips16 mode");
6911 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
6912 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
6913 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6914 reportParseError("expected register containing function address");
6918 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
6919 if (!RegOpnd.isGPRAsmReg()) {
6920 reportParseError(RegOpnd.getStartLoc(), "invalid register");
6924 // If this is not the end of the statement, report an error.
6925 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6926 reportParseError("unexpected token, expected end of statement");
6930 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
6934 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
6935 MCAsmParser &Parser = getParser();
6937 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
6938 // is used in non-PIC mode.
6940 if (inMips16Mode()) {
6941 reportParseError(".cprestore is not supported in Mips16 mode");
6945 // Get the stack offset value.
6946 const MCExpr *StackOffset;
6947 int64_t StackOffsetVal;
6948 if (Parser.parseExpression(StackOffset)) {
6949 reportParseError("expected stack offset value");
6953 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
6954 reportParseError("stack offset is not an absolute expression");
6958 if (StackOffsetVal < 0) {
6959 Warning(Loc, ".cprestore with negative stack offset has no effect");
6960 IsCpRestoreSet = false;
6962 IsCpRestoreSet = true;
6963 CpRestoreOffset = StackOffsetVal;
6966 // If this is not the end of the statement, report an error.
6967 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6968 reportParseError("unexpected token, expected end of statement");
6972 if (!getTargetStreamer().emitDirectiveCpRestore(
6973 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
6975 Parser.Lex(); // Consume the EndOfStatement.
6979 bool MipsAsmParser::parseDirectiveCPSetup() {
6980 MCAsmParser &Parser = getParser();
6983 bool SaveIsReg = true;
6985 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6986 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6987 if (ResTy == MatchOperand_NoMatch) {
6988 reportParseError("expected register containing function address");
6992 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6993 if (!FuncRegOpnd.isGPRAsmReg()) {
6994 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
6998 FuncReg = FuncRegOpnd.getGPR32Reg();
7001 if (!eatComma("unexpected token, expected comma"))
7004 ResTy = parseAnyRegister(TmpReg);
7005 if (ResTy == MatchOperand_NoMatch) {
7006 const MCExpr *OffsetExpr;
7008 SMLoc ExprLoc = getLexer().getLoc();
7010 if (Parser.parseExpression(OffsetExpr) ||
7011 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7012 reportParseError(ExprLoc, "expected save register or stack offset");
7019 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7020 if (!SaveOpnd.isGPRAsmReg()) {
7021 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7024 Save = SaveOpnd.getGPR32Reg();
7027 if (!eatComma("unexpected token, expected comma"))
7031 if (Parser.parseExpression(Expr)) {
7032 reportParseError("expected expression");
7036 if (Expr->getKind() != MCExpr::SymbolRef) {
7037 reportParseError("expected symbol");
7040 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7042 CpSaveLocation = Save;
7043 CpSaveLocationIsRegister = SaveIsReg;
7045 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7050 bool MipsAsmParser::parseDirectiveCPReturn() {
7051 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7052 CpSaveLocationIsRegister);
7056 bool MipsAsmParser::parseDirectiveNaN() {
7057 MCAsmParser &Parser = getParser();
7058 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7059 const AsmToken &Tok = Parser.getTok();
7061 if (Tok.getString() == "2008") {
7063 getTargetStreamer().emitDirectiveNaN2008();
7065 } else if (Tok.getString() == "legacy") {
7067 getTargetStreamer().emitDirectiveNaNLegacy();
7071 // If we don't recognize the option passed to the .nan
7072 // directive (e.g. no option or unknown option), emit an error.
7073 reportParseError("invalid option in .nan directive");
7077 bool MipsAsmParser::parseDirectiveSet() {
7078 MCAsmParser &Parser = getParser();
7079 // Get the next token.
7080 const AsmToken &Tok = Parser.getTok();
7082 if (Tok.getString() == "noat") {
7083 return parseSetNoAtDirective();
7084 } else if (Tok.getString() == "at") {
7085 return parseSetAtDirective();
7086 } else if (Tok.getString() == "arch") {
7087 return parseSetArchDirective();
7088 } else if (Tok.getString() == "bopt") {
7089 Warning(Tok.getLoc(), "'bopt' feature is unsupported");
7092 } else if (Tok.getString() == "nobopt") {
7093 // We're already running in nobopt mode, so nothing to do.
7096 } else if (Tok.getString() == "fp") {
7097 return parseSetFpDirective();
7098 } else if (Tok.getString() == "oddspreg") {
7099 return parseSetOddSPRegDirective();
7100 } else if (Tok.getString() == "nooddspreg") {
7101 return parseSetNoOddSPRegDirective();
7102 } else if (Tok.getString() == "pop") {
7103 return parseSetPopDirective();
7104 } else if (Tok.getString() == "push") {
7105 return parseSetPushDirective();
7106 } else if (Tok.getString() == "reorder") {
7107 return parseSetReorderDirective();
7108 } else if (Tok.getString() == "noreorder") {
7109 return parseSetNoReorderDirective();
7110 } else if (Tok.getString() == "macro") {
7111 return parseSetMacroDirective();
7112 } else if (Tok.getString() == "nomacro") {
7113 return parseSetNoMacroDirective();
7114 } else if (Tok.getString() == "mips16") {
7115 return parseSetMips16Directive();
7116 } else if (Tok.getString() == "nomips16") {
7117 return parseSetNoMips16Directive();
7118 } else if (Tok.getString() == "nomicromips") {
7119 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7120 getTargetStreamer().emitDirectiveSetNoMicroMips();
7121 Parser.eatToEndOfStatement();
7123 } else if (Tok.getString() == "micromips") {
7124 if (hasMips64r6()) {
7125 Error(Tok.getLoc(), ".set micromips directive is not supported with MIPS64R6");
7128 return parseSetFeature(Mips::FeatureMicroMips);
7129 } else if (Tok.getString() == "mips0") {
7130 return parseSetMips0Directive();
7131 } else if (Tok.getString() == "mips1") {
7132 return parseSetFeature(Mips::FeatureMips1);
7133 } else if (Tok.getString() == "mips2") {
7134 return parseSetFeature(Mips::FeatureMips2);
7135 } else if (Tok.getString() == "mips3") {
7136 return parseSetFeature(Mips::FeatureMips3);
7137 } else if (Tok.getString() == "mips4") {
7138 return parseSetFeature(Mips::FeatureMips4);
7139 } else if (Tok.getString() == "mips5") {
7140 return parseSetFeature(Mips::FeatureMips5);
7141 } else if (Tok.getString() == "mips32") {
7142 return parseSetFeature(Mips::FeatureMips32);
7143 } else if (Tok.getString() == "mips32r2") {
7144 return parseSetFeature(Mips::FeatureMips32r2);
7145 } else if (Tok.getString() == "mips32r3") {
7146 return parseSetFeature(Mips::FeatureMips32r3);
7147 } else if (Tok.getString() == "mips32r5") {
7148 return parseSetFeature(Mips::FeatureMips32r5);
7149 } else if (Tok.getString() == "mips32r6") {
7150 return parseSetFeature(Mips::FeatureMips32r6);
7151 } else if (Tok.getString() == "mips64") {
7152 return parseSetFeature(Mips::FeatureMips64);
7153 } else if (Tok.getString() == "mips64r2") {
7154 return parseSetFeature(Mips::FeatureMips64r2);
7155 } else if (Tok.getString() == "mips64r3") {
7156 return parseSetFeature(Mips::FeatureMips64r3);
7157 } else if (Tok.getString() == "mips64r5") {
7158 return parseSetFeature(Mips::FeatureMips64r5);
7159 } else if (Tok.getString() == "mips64r6") {
7160 if (inMicroMipsMode()) {
7161 Error(Tok.getLoc(), "MIPS64R6 is not supported with microMIPS");
7164 return parseSetFeature(Mips::FeatureMips64r6);
7165 } else if (Tok.getString() == "dsp") {
7166 return parseSetFeature(Mips::FeatureDSP);
7167 } else if (Tok.getString() == "dspr2") {
7168 return parseSetFeature(Mips::FeatureDSPR2);
7169 } else if (Tok.getString() == "nodsp") {
7170 return parseSetNoDspDirective();
7171 } else if (Tok.getString() == "msa") {
7172 return parseSetMsaDirective();
7173 } else if (Tok.getString() == "nomsa") {
7174 return parseSetNoMsaDirective();
7175 } else if (Tok.getString() == "mt") {
7176 return parseSetMtDirective();
7177 } else if (Tok.getString() == "nomt") {
7178 return parseSetNoMtDirective();
7179 } else if (Tok.getString() == "softfloat") {
7180 return parseSetSoftFloatDirective();
7181 } else if (Tok.getString() == "hardfloat") {
7182 return parseSetHardFloatDirective();
7184 // It is just an identifier, look for an assignment.
7185 parseSetAssignment();
7192 /// parseDataDirective
7193 /// ::= .word [ expression (, expression)* ]
7194 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
7195 MCAsmParser &Parser = getParser();
7196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7198 const MCExpr *Value;
7199 if (getParser().parseExpression(Value))
7202 getParser().getStreamer().EmitValue(Value, Size);
7204 if (getLexer().is(AsmToken::EndOfStatement))
7207 if (getLexer().isNot(AsmToken::Comma))
7208 return Error(L, "unexpected token, expected comma");
7217 /// parseDirectiveGpWord
7218 /// ::= .gpword local_sym
7219 bool MipsAsmParser::parseDirectiveGpWord() {
7220 MCAsmParser &Parser = getParser();
7221 const MCExpr *Value;
7222 // EmitGPRel32Value requires an expression, so we are using base class
7223 // method to evaluate the expression.
7224 if (getParser().parseExpression(Value))
7226 getParser().getStreamer().EmitGPRel32Value(Value);
7228 if (getLexer().isNot(AsmToken::EndOfStatement))
7229 return Error(getLexer().getLoc(),
7230 "unexpected token, expected end of statement");
7231 Parser.Lex(); // Eat EndOfStatement token.
7235 /// parseDirectiveGpDWord
7236 /// ::= .gpdword local_sym
7237 bool MipsAsmParser::parseDirectiveGpDWord() {
7238 MCAsmParser &Parser = getParser();
7239 const MCExpr *Value;
7240 // EmitGPRel64Value requires an expression, so we are using base class
7241 // method to evaluate the expression.
7242 if (getParser().parseExpression(Value))
7244 getParser().getStreamer().EmitGPRel64Value(Value);
7246 if (getLexer().isNot(AsmToken::EndOfStatement))
7247 return Error(getLexer().getLoc(),
7248 "unexpected token, expected end of statement");
7249 Parser.Lex(); // Eat EndOfStatement token.
7253 /// parseDirectiveDtpRelWord
7254 /// ::= .dtprelword tls_sym
7255 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7256 MCAsmParser &Parser = getParser();
7257 const MCExpr *Value;
7258 // EmitDTPRel32Value requires an expression, so we are using base class
7259 // method to evaluate the expression.
7260 if (getParser().parseExpression(Value))
7262 getParser().getStreamer().EmitDTPRel32Value(Value);
7264 if (getLexer().isNot(AsmToken::EndOfStatement))
7265 return Error(getLexer().getLoc(),
7266 "unexpected token, expected end of statement");
7267 Parser.Lex(); // Eat EndOfStatement token.
7271 /// parseDirectiveDtpRelDWord
7272 /// ::= .dtpreldword tls_sym
7273 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7274 MCAsmParser &Parser = getParser();
7275 const MCExpr *Value;
7276 // EmitDTPRel64Value requires an expression, so we are using base class
7277 // method to evaluate the expression.
7278 if (getParser().parseExpression(Value))
7280 getParser().getStreamer().EmitDTPRel64Value(Value);
7282 if (getLexer().isNot(AsmToken::EndOfStatement))
7283 return Error(getLexer().getLoc(),
7284 "unexpected token, expected end of statement");
7285 Parser.Lex(); // Eat EndOfStatement token.
7289 /// parseDirectiveTpRelWord
7290 /// ::= .tprelword tls_sym
7291 bool MipsAsmParser::parseDirectiveTpRelWord() {
7292 MCAsmParser &Parser = getParser();
7293 const MCExpr *Value;
7294 // EmitTPRel32Value requires an expression, so we are using base class
7295 // method to evaluate the expression.
7296 if (getParser().parseExpression(Value))
7298 getParser().getStreamer().EmitTPRel32Value(Value);
7300 if (getLexer().isNot(AsmToken::EndOfStatement))
7301 return Error(getLexer().getLoc(),
7302 "unexpected token, expected end of statement");
7303 Parser.Lex(); // Eat EndOfStatement token.
7307 /// parseDirectiveTpRelDWord
7308 /// ::= .tpreldword tls_sym
7309 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7310 MCAsmParser &Parser = getParser();
7311 const MCExpr *Value;
7312 // EmitTPRel64Value requires an expression, so we are using base class
7313 // method to evaluate the expression.
7314 if (getParser().parseExpression(Value))
7316 getParser().getStreamer().EmitTPRel64Value(Value);
7318 if (getLexer().isNot(AsmToken::EndOfStatement))
7319 return Error(getLexer().getLoc(),
7320 "unexpected token, expected end of statement");
7321 Parser.Lex(); // Eat EndOfStatement token.
7325 bool MipsAsmParser::parseDirectiveOption() {
7326 MCAsmParser &Parser = getParser();
7327 // Get the option token.
7328 AsmToken Tok = Parser.getTok();
7329 // At the moment only identifiers are supported.
7330 if (Tok.isNot(AsmToken::Identifier)) {
7331 return Error(Parser.getTok().getLoc(),
7332 "unexpected token, expected identifier");
7335 StringRef Option = Tok.getIdentifier();
7337 if (Option == "pic0") {
7338 // MipsAsmParser needs to know if the current PIC mode changes.
7339 IsPicEnabled = false;
7341 getTargetStreamer().emitDirectiveOptionPic0();
7343 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7344 return Error(Parser.getTok().getLoc(),
7345 "unexpected token, expected end of statement");
7350 if (Option == "pic2") {
7351 // MipsAsmParser needs to know if the current PIC mode changes.
7352 IsPicEnabled = true;
7354 getTargetStreamer().emitDirectiveOptionPic2();
7356 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7357 return Error(Parser.getTok().getLoc(),
7358 "unexpected token, expected end of statement");
7364 Warning(Parser.getTok().getLoc(),
7365 "unknown option, expected 'pic0' or 'pic2'");
7366 Parser.eatToEndOfStatement();
7370 /// parseInsnDirective
7372 bool MipsAsmParser::parseInsnDirective() {
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 // The actual label marking happens in
7380 // MipsELFStreamer::createPendingLabelRelocs().
7381 getTargetStreamer().emitDirectiveInsn();
7383 getParser().Lex(); // Eat EndOfStatement token.
7387 /// parseRSectionDirective
7389 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7390 // If this is not the end of the statement, report an error.
7391 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7392 reportParseError("unexpected token, expected end of statement");
7396 MCSection *ELFSection = getContext().getELFSection(
7397 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7398 getParser().getStreamer().SwitchSection(ELFSection);
7400 getParser().Lex(); // Eat EndOfStatement token.
7404 /// parseSSectionDirective
7407 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7408 // If this is not the end of the statement, report an error.
7409 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7410 reportParseError("unexpected token, expected end of statement");
7414 MCSection *ELFSection = getContext().getELFSection(
7415 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7416 getParser().getStreamer().SwitchSection(ELFSection);
7418 getParser().Lex(); // Eat EndOfStatement token.
7422 /// parseDirectiveModule
7423 /// ::= .module oddspreg
7424 /// ::= .module nooddspreg
7425 /// ::= .module fp=value
7426 /// ::= .module softfloat
7427 /// ::= .module hardfloat
7429 bool MipsAsmParser::parseDirectiveModule() {
7430 MCAsmParser &Parser = getParser();
7431 MCAsmLexer &Lexer = getLexer();
7432 SMLoc L = Lexer.getLoc();
7434 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7435 // TODO : get a better message.
7436 reportParseError(".module directive must appear before any code");
7441 if (Parser.parseIdentifier(Option)) {
7442 reportParseError("expected .module option identifier");
7446 if (Option == "oddspreg") {
7447 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7449 // Synchronize the abiflags information with the FeatureBits information we
7451 getTargetStreamer().updateABIInfo(*this);
7453 // If printing assembly, use the recently updated abiflags information.
7454 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7455 // emitted at the end).
7456 getTargetStreamer().emitDirectiveModuleOddSPReg();
7458 // If this is not the end of the statement, report an error.
7459 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7460 reportParseError("unexpected token, expected end of statement");
7464 return false; // parseDirectiveModule has finished successfully.
7465 } else if (Option == "nooddspreg") {
7467 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7470 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7472 // Synchronize the abiflags information with the FeatureBits information we
7474 getTargetStreamer().updateABIInfo(*this);
7476 // If printing assembly, use the recently updated abiflags information.
7477 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7478 // emitted at the end).
7479 getTargetStreamer().emitDirectiveModuleOddSPReg();
7481 // If this is not the end of the statement, report an error.
7482 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7483 reportParseError("unexpected token, expected end of statement");
7487 return false; // parseDirectiveModule has finished successfully.
7488 } else if (Option == "fp") {
7489 return parseDirectiveModuleFP();
7490 } else if (Option == "softfloat") {
7491 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7493 // Synchronize the ABI Flags information with the FeatureBits information we
7495 getTargetStreamer().updateABIInfo(*this);
7497 // If printing assembly, use the recently updated ABI Flags information.
7498 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7500 getTargetStreamer().emitDirectiveModuleSoftFloat();
7502 // If this is not the end of the statement, report an error.
7503 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7504 reportParseError("unexpected token, expected end of statement");
7508 return false; // parseDirectiveModule has finished successfully.
7509 } else if (Option == "hardfloat") {
7510 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7512 // Synchronize the ABI Flags information with the FeatureBits information we
7514 getTargetStreamer().updateABIInfo(*this);
7516 // If printing assembly, use the recently updated ABI Flags information.
7517 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7519 getTargetStreamer().emitDirectiveModuleHardFloat();
7521 // If this is not the end of the statement, report an error.
7522 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7523 reportParseError("unexpected token, expected end of statement");
7527 return false; // parseDirectiveModule has finished successfully.
7528 } else if (Option == "mt") {
7529 setModuleFeatureBits(Mips::FeatureMT, "mt");
7531 // Synchronize the ABI Flags information with the FeatureBits information we
7533 getTargetStreamer().updateABIInfo(*this);
7535 // If printing assembly, use the recently updated ABI Flags information.
7536 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7538 getTargetStreamer().emitDirectiveModuleMT();
7540 // If this is not the end of the statement, report an error.
7541 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7542 reportParseError("unexpected token, expected end of statement");
7546 return false; // parseDirectiveModule has finished successfully.
7548 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7552 /// parseDirectiveModuleFP
7556 bool MipsAsmParser::parseDirectiveModuleFP() {
7557 MCAsmParser &Parser = getParser();
7558 MCAsmLexer &Lexer = getLexer();
7560 if (Lexer.isNot(AsmToken::Equal)) {
7561 reportParseError("unexpected token, expected equals sign '='");
7564 Parser.Lex(); // Eat '=' token.
7566 MipsABIFlagsSection::FpABIKind FpABI;
7567 if (!parseFpABIValue(FpABI, ".module"))
7570 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7571 reportParseError("unexpected token, expected end of statement");
7575 // Synchronize the abiflags information with the FeatureBits information we
7577 getTargetStreamer().updateABIInfo(*this);
7579 // If printing assembly, use the recently updated abiflags information.
7580 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7581 // emitted at the end).
7582 getTargetStreamer().emitDirectiveModuleFP();
7584 Parser.Lex(); // Consume the EndOfStatement.
7588 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7589 StringRef Directive) {
7590 MCAsmParser &Parser = getParser();
7591 MCAsmLexer &Lexer = getLexer();
7592 bool ModuleLevelOptions = Directive == ".module";
7594 if (Lexer.is(AsmToken::Identifier)) {
7595 StringRef Value = Parser.getTok().getString();
7598 if (Value != "xx") {
7599 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7604 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7608 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7609 if (ModuleLevelOptions) {
7610 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7611 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7613 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7614 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7619 if (Lexer.is(AsmToken::Integer)) {
7620 unsigned Value = Parser.getTok().getIntVal();
7623 if (Value != 32 && Value != 64) {
7624 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7630 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7634 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7635 if (ModuleLevelOptions) {
7636 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7637 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7639 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7640 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7643 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7644 if (ModuleLevelOptions) {
7645 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7646 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7648 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7649 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7659 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7660 // This returns false if this function recognizes the directive
7661 // regardless of whether it is successfully handles or reports an
7662 // error. Otherwise it returns true to give the generic parser a
7663 // chance at recognizing it.
7665 MCAsmParser &Parser = getParser();
7666 StringRef IDVal = DirectiveID.getString();
7668 if (IDVal == ".cpload") {
7669 parseDirectiveCpLoad(DirectiveID.getLoc());
7672 if (IDVal == ".cprestore") {
7673 parseDirectiveCpRestore(DirectiveID.getLoc());
7676 if (IDVal == ".dword") {
7677 parseDataDirective(8, DirectiveID.getLoc());
7680 if (IDVal == ".ent") {
7681 StringRef SymbolName;
7683 if (Parser.parseIdentifier(SymbolName)) {
7684 reportParseError("expected identifier after .ent");
7688 // There's an undocumented extension that allows an integer to
7689 // follow the name of the procedure which AFAICS is ignored by GAS.
7690 // Example: .ent foo,2
7691 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7692 if (getLexer().isNot(AsmToken::Comma)) {
7693 // Even though we accept this undocumented extension for compatibility
7694 // reasons, the additional integer argument does not actually change
7695 // the behaviour of the '.ent' directive, so we would like to discourage
7696 // its use. We do this by not referring to the extended version in
7697 // error messages which are not directly related to its use.
7698 reportParseError("unexpected token, expected end of statement");
7701 Parser.Lex(); // Eat the comma.
7702 const MCExpr *DummyNumber;
7703 int64_t DummyNumberVal;
7704 // If the user was explicitly trying to use the extended version,
7705 // we still give helpful extension-related error messages.
7706 if (Parser.parseExpression(DummyNumber)) {
7707 reportParseError("expected number after comma");
7710 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7711 reportParseError("expected an absolute expression after comma");
7716 // If this is not the end of the statement, report an error.
7717 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7718 reportParseError("unexpected token, expected end of statement");
7722 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7724 getTargetStreamer().emitDirectiveEnt(*Sym);
7726 IsCpRestoreSet = false;
7730 if (IDVal == ".end") {
7731 StringRef SymbolName;
7733 if (Parser.parseIdentifier(SymbolName)) {
7734 reportParseError("expected identifier after .end");
7738 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7739 reportParseError("unexpected token, expected end of statement");
7743 if (CurrentFn == nullptr) {
7744 reportParseError(".end used without .ent");
7748 if ((SymbolName != CurrentFn->getName())) {
7749 reportParseError(".end symbol does not match .ent symbol");
7753 getTargetStreamer().emitDirectiveEnd(SymbolName);
7754 CurrentFn = nullptr;
7755 IsCpRestoreSet = false;
7759 if (IDVal == ".frame") {
7760 // .frame $stack_reg, frame_size_in_bytes, $return_reg
7761 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7762 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7763 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7764 reportParseError("expected stack register");
7768 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7769 if (!StackRegOpnd.isGPRAsmReg()) {
7770 reportParseError(StackRegOpnd.getStartLoc(),
7771 "expected general purpose register");
7774 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7776 if (Parser.getTok().is(AsmToken::Comma))
7779 reportParseError("unexpected token, expected comma");
7783 // Parse the frame size.
7784 const MCExpr *FrameSize;
7785 int64_t FrameSizeVal;
7787 if (Parser.parseExpression(FrameSize)) {
7788 reportParseError("expected frame size value");
7792 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
7793 reportParseError("frame size not an absolute expression");
7797 if (Parser.getTok().is(AsmToken::Comma))
7800 reportParseError("unexpected token, expected comma");
7804 // Parse the return register.
7806 ResTy = parseAnyRegister(TmpReg);
7807 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7808 reportParseError("expected return register");
7812 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7813 if (!ReturnRegOpnd.isGPRAsmReg()) {
7814 reportParseError(ReturnRegOpnd.getStartLoc(),
7815 "expected general purpose register");
7819 // If this is not the end of the statement, report an error.
7820 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7821 reportParseError("unexpected token, expected end of statement");
7825 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
7826 ReturnRegOpnd.getGPR32Reg());
7827 IsCpRestoreSet = false;
7831 if (IDVal == ".set") {
7832 parseDirectiveSet();
7836 if (IDVal == ".mask" || IDVal == ".fmask") {
7837 // .mask bitmask, frame_offset
7838 // bitmask: One bit for each register used.
7839 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
7840 // first register is expected to be saved.
7842 // .mask 0x80000000, -4
7843 // .fmask 0x80000000, -4
7846 // Parse the bitmask
7847 const MCExpr *BitMask;
7850 if (Parser.parseExpression(BitMask)) {
7851 reportParseError("expected bitmask value");
7855 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
7856 reportParseError("bitmask not an absolute expression");
7860 if (Parser.getTok().is(AsmToken::Comma))
7863 reportParseError("unexpected token, expected comma");
7867 // Parse the frame_offset
7868 const MCExpr *FrameOffset;
7869 int64_t FrameOffsetVal;
7871 if (Parser.parseExpression(FrameOffset)) {
7872 reportParseError("expected frame offset value");
7876 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
7877 reportParseError("frame offset not an absolute expression");
7881 // If this is not the end of the statement, report an error.
7882 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7883 reportParseError("unexpected token, expected end of statement");
7887 if (IDVal == ".mask")
7888 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
7890 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
7894 if (IDVal == ".nan")
7895 return parseDirectiveNaN();
7897 if (IDVal == ".gpword") {
7898 parseDirectiveGpWord();
7902 if (IDVal == ".gpdword") {
7903 parseDirectiveGpDWord();
7907 if (IDVal == ".dtprelword") {
7908 parseDirectiveDtpRelWord();
7912 if (IDVal == ".dtpreldword") {
7913 parseDirectiveDtpRelDWord();
7917 if (IDVal == ".tprelword") {
7918 parseDirectiveTpRelWord();
7922 if (IDVal == ".tpreldword") {
7923 parseDirectiveTpRelDWord();
7927 if (IDVal == ".word") {
7928 parseDataDirective(4, DirectiveID.getLoc());
7932 if (IDVal == ".hword") {
7933 parseDataDirective(2, DirectiveID.getLoc());
7937 if (IDVal == ".option") {
7938 parseDirectiveOption();
7942 if (IDVal == ".abicalls") {
7943 getTargetStreamer().emitDirectiveAbiCalls();
7944 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7945 Error(Parser.getTok().getLoc(),
7946 "unexpected token, expected end of statement");
7951 if (IDVal == ".cpsetup") {
7952 parseDirectiveCPSetup();
7955 if (IDVal == ".cpreturn") {
7956 parseDirectiveCPReturn();
7959 if (IDVal == ".module") {
7960 parseDirectiveModule();
7963 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
7964 parseInternalDirectiveReallowModule();
7967 if (IDVal == ".insn") {
7968 parseInsnDirective();
7971 if (IDVal == ".rdata") {
7972 parseRSectionDirective(".rodata");
7975 if (IDVal == ".sbss") {
7976 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
7979 if (IDVal == ".sdata") {
7980 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
7987 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
7988 // If this is not the end of the statement, report an error.
7989 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7990 reportParseError("unexpected token, expected end of statement");
7994 getTargetStreamer().reallowModuleDirective();
7996 getParser().Lex(); // Eat EndOfStatement token.
8000 extern "C" void LLVMInitializeMipsAsmParser() {
8001 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8002 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8003 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8004 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8007 #define GET_REGISTER_MATCHER
8008 #define GET_MATCHER_IMPLEMENTATION
8009 #include "MipsGenAsmMatcher.inc"
8011 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8012 // Find the appropriate table for this asm variant.
8013 const MatchEntry *Start, *End;
8014 switch (VariantID) {
8015 default: llvm_unreachable("invalid variant!");
8016 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8018 // Search the table.
8019 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8020 return MnemonicRange.first != MnemonicRange.second;