1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIFlagsSection.h"
11 #include "MCTargetDesc/MipsABIInfo.h"
12 #include "MCTargetDesc/MipsMCExpr.h"
13 #include "MCTargetDesc/MipsMCTargetDesc.h"
14 #include "MipsTargetStreamer.h"
15 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrDesc.h"
26 #include "llvm/MC/MCObjectFileInfo.h"
27 #include "llvm/MC/MCParser/MCAsmLexer.h"
28 #include "llvm/MC/MCParser/MCAsmParser.h"
29 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
30 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
31 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
32 #include "llvm/MC/MCSectionELF.h"
33 #include "llvm/MC/MCStreamer.h"
34 #include "llvm/MC/MCSubtargetInfo.h"
35 #include "llvm/MC/MCSymbol.h"
36 #include "llvm/MC/MCSymbolELF.h"
37 #include "llvm/MC/MCValue.h"
38 #include "llvm/MC/SubtargetFeature.h"
39 #include "llvm/Support/Casting.h"
40 #include "llvm/Support/Compiler.h"
41 #include "llvm/Support/Debug.h"
42 #include "llvm/Support/ELF.h"
43 #include "llvm/Support/ErrorHandling.h"
44 #include "llvm/Support/MathExtras.h"
45 #include "llvm/Support/raw_ostream.h"
46 #include "llvm/Support/SMLoc.h"
47 #include "llvm/Support/SourceMgr.h"
48 #include "llvm/Support/TargetRegistry.h"
58 #define DEBUG_TYPE "mips-asm-parser"
64 } // end namespace llvm
68 class MipsAssemblerOptions {
70 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
72 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
73 ATReg = Opts->getATRegIndex();
74 Reorder = Opts->isReorder();
75 Macro = Opts->isMacro();
76 Features = Opts->getFeatures();
79 unsigned getATRegIndex() const { return ATReg; }
80 bool setATRegIndex(unsigned Reg) {
88 bool isReorder() const { return Reorder; }
89 void setReorder() { Reorder = true; }
90 void setNoReorder() { Reorder = false; }
92 bool isMacro() const { return Macro; }
93 void setMacro() { Macro = true; }
94 void setNoMacro() { Macro = false; }
96 const FeatureBitset &getFeatures() const { return Features; }
97 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
99 // Set of features that are either architecture features or referenced
100 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
101 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
102 // The reason we need this mask is explained in the selectArch function.
103 // FIXME: Ideally we would like TableGen to generate this information.
104 static const FeatureBitset AllArchRelatedMask;
110 FeatureBitset Features;
113 } // end anonymous namespace
115 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
116 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
117 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
118 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
119 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
120 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
121 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
122 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
123 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
128 class MipsAsmParser : public MCTargetAsmParser {
129 MipsTargetStreamer &getTargetStreamer() {
130 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
131 return static_cast<MipsTargetStreamer &>(TS);
135 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
136 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
137 // nullptr, which indicates that no function is currently
138 // selected. This usually happens after an '.end func'
144 unsigned CpSaveLocation;
145 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
146 bool CpSaveLocationIsRegister;
148 // Print a warning along with its fix-it message at the given range.
149 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
150 SMRange Range, bool ShowColors = true);
152 #define GET_ASSEMBLER_HEADER
153 #include "MipsGenAsmMatcher.inc"
156 checkEarlyTargetMatchPredicate(MCInst &Inst,
157 const OperandVector &Operands) override;
158 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
160 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
161 OperandVector &Operands, MCStreamer &Out,
163 bool MatchingInlineAsm) override;
165 /// Parse a register as used in CFI directives
166 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
168 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
170 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
172 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
174 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
175 SMLoc NameLoc, OperandVector &Operands) override;
177 bool ParseDirective(AsmToken DirectiveID) override;
179 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
181 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
182 StringRef Identifier, SMLoc S);
183 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
185 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
186 OperandMatchResultTy parseImm(OperandVector &Operands);
187 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
188 OperandMatchResultTy parseInvNum(OperandVector &Operands);
189 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
190 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
191 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
193 bool searchSymbolAlias(OperandVector &Operands);
195 bool parseOperand(OperandVector &, StringRef Mnemonic);
197 enum MacroExpanderResultTy {
203 // Expands assembly pseudo instructions.
204 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
206 const MCSubtargetInfo *STI);
208 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
209 const MCSubtargetInfo *STI);
211 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
212 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
213 MCStreamer &Out, const MCSubtargetInfo *STI);
215 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
216 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
217 MCStreamer &Out, const MCSubtargetInfo *STI);
219 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
220 MCStreamer &Out, const MCSubtargetInfo *STI);
222 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
223 const MCOperand &Offset, bool Is32BitAddress,
224 SMLoc IDLoc, MCStreamer &Out,
225 const MCSubtargetInfo *STI);
227 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
228 const MCSubtargetInfo *STI);
230 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
231 const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
233 void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
234 const MCSubtargetInfo *STI, bool IsImmOpnd);
236 void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
237 const MCSubtargetInfo *STI, bool IsImmOpnd);
239 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
240 const MCSubtargetInfo *STI);
242 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
243 const MCSubtargetInfo *STI);
245 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
248 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
249 const MCSubtargetInfo *STI);
251 bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
252 const MCSubtargetInfo *STI, const bool IsMips64,
255 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
256 MCStreamer &Out, const MCSubtargetInfo *STI);
258 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI);
261 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI);
264 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
265 const MCSubtargetInfo *STI);
267 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
268 MCStreamer &Out, const MCSubtargetInfo *STI);
269 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270 const MCSubtargetInfo *STI);
271 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
273 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
274 const MCSubtargetInfo *STI);
276 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI);
279 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
282 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
285 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
288 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289 const MCSubtargetInfo *STI);
291 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292 const MCSubtargetInfo *STI, bool IsLoad);
294 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295 const MCSubtargetInfo *STI);
297 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298 const MCSubtargetInfo *STI);
300 bool reportParseError(Twine ErrorMsg);
301 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
303 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
305 bool isEvaluated(const MCExpr *Expr);
306 bool parseSetMips0Directive();
307 bool parseSetArchDirective();
308 bool parseSetFeature(uint64_t Feature);
309 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
310 bool parseDirectiveCpLoad(SMLoc Loc);
311 bool parseDirectiveCpRestore(SMLoc Loc);
312 bool parseDirectiveCPSetup();
313 bool parseDirectiveCPReturn();
314 bool parseDirectiveNaN();
315 bool parseDirectiveSet();
316 bool parseDirectiveOption();
317 bool parseInsnDirective();
318 bool parseSSectionDirective(StringRef Section, unsigned Type);
320 bool parseSetAtDirective();
321 bool parseSetNoAtDirective();
322 bool parseSetMacroDirective();
323 bool parseSetNoMacroDirective();
324 bool parseSetMsaDirective();
325 bool parseSetNoMsaDirective();
326 bool parseSetNoDspDirective();
327 bool parseSetReorderDirective();
328 bool parseSetNoReorderDirective();
329 bool parseSetMips16Directive();
330 bool parseSetNoMips16Directive();
331 bool parseSetFpDirective();
332 bool parseSetOddSPRegDirective();
333 bool parseSetNoOddSPRegDirective();
334 bool parseSetPopDirective();
335 bool parseSetPushDirective();
336 bool parseSetSoftFloatDirective();
337 bool parseSetHardFloatDirective();
339 bool parseSetAssignment();
341 bool parseDataDirective(unsigned Size, SMLoc L);
342 bool parseDirectiveGpWord();
343 bool parseDirectiveGpDWord();
344 bool parseDirectiveDtpRelWord();
345 bool parseDirectiveDtpRelDWord();
346 bool parseDirectiveTpRelWord();
347 bool parseDirectiveTpRelDWord();
348 bool parseDirectiveModule();
349 bool parseDirectiveModuleFP();
350 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
351 StringRef Directive);
353 bool parseInternalDirectiveReallowModule();
355 bool eatComma(StringRef ErrorStr);
357 int matchCPURegisterName(StringRef Symbol);
359 int matchHWRegsRegisterName(StringRef Symbol);
361 int matchFPURegisterName(StringRef Name);
363 int matchFCCRegisterName(StringRef Name);
365 int matchACRegisterName(StringRef Name);
367 int matchMSA128RegisterName(StringRef Name);
369 int matchMSA128CtrlRegisterName(StringRef Name);
371 unsigned getReg(int RC, int RegNo);
373 /// Returns the internal register number for the current AT. Also checks if
374 /// the current AT is unavailable (set to $0) and gives an error if it is.
375 /// This should be used in pseudo-instruction expansions which need AT.
376 unsigned getATReg(SMLoc Loc);
380 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
381 const MCSubtargetInfo *STI);
383 // Helper function that checks if the value of a vector index is within the
384 // boundaries of accepted values for each RegisterKind
385 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
386 bool validateMSAIndex(int Val, int RegKind);
388 // Selects a new architecture by updating the FeatureBits with the necessary
389 // info including implied dependencies.
390 // Internally, it clears all the feature bits related to *any* architecture
391 // and selects the new one using the ToggleFeature functionality of the
392 // MCSubtargetInfo object that handles implied dependencies. The reason we
393 // clear all the arch related bits manually is because ToggleFeature only
394 // clears the features that imply the feature being cleared and not the
395 // features implied by the feature being cleared. This is easier to see
397 // --------------------------------------------------
398 // | Feature | Implies |
399 // | -------------------------------------------------|
400 // | FeatureMips1 | None |
401 // | FeatureMips2 | FeatureMips1 |
402 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
403 // | FeatureMips4 | FeatureMips3 |
405 // --------------------------------------------------
407 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
408 // FeatureMipsGP64 | FeatureMips1)
409 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
410 void selectArch(StringRef ArchFeature) {
411 MCSubtargetInfo &STI = copySTI();
412 FeatureBitset FeatureBits = STI.getFeatureBits();
413 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
414 STI.setFeatureBits(FeatureBits);
415 setAvailableFeatures(
416 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
417 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
420 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
421 if (!(getSTI().getFeatureBits()[Feature])) {
422 MCSubtargetInfo &STI = copySTI();
423 setAvailableFeatures(
424 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
425 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
429 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
430 if (getSTI().getFeatureBits()[Feature]) {
431 MCSubtargetInfo &STI = copySTI();
432 setAvailableFeatures(
433 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
434 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
438 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
439 setFeatureBits(Feature, FeatureString);
440 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
443 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
444 clearFeatureBits(Feature, FeatureString);
445 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
449 enum MipsMatchResultTy {
450 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
451 Match_RequiresDifferentOperands,
452 Match_RequiresNoZeroRegister,
453 Match_RequiresSameSrcAndDst,
454 Match_NoFCCRegisterForCurrentISA,
455 Match_NonZeroOperandForSync,
456 #define GET_OPERAND_DIAGNOSTIC_TYPES
457 #include "MipsGenAsmMatcher.inc"
458 #undef GET_OPERAND_DIAGNOSTIC_TYPES
461 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
462 const MCInstrInfo &MII, const MCTargetOptions &Options)
463 : MCTargetAsmParser(Options, sti),
464 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
465 sti.getCPU(), Options)) {
466 MCAsmParserExtension::Initialize(parser);
468 parser.addAliasForDirective(".asciiz", ".asciz");
470 // Initialize the set of available features.
471 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
473 // Remember the initial assembler options. The user can not modify these.
474 AssemblerOptions.push_back(
475 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
477 // Create an assembler options environment for the user to modify.
478 AssemblerOptions.push_back(
479 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
481 getTargetStreamer().updateABIInfo(*this);
483 if (!isABI_O32() && !useOddSPReg() != 0)
484 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
488 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
490 IsCpRestoreSet = false;
491 CpRestoreOffset = -1;
493 const Triple &TheTriple = sti.getTargetTriple();
494 if ((TheTriple.getArch() == Triple::mips) ||
495 (TheTriple.getArch() == Triple::mips64))
496 IsLittleEndian = false;
498 IsLittleEndian = true;
501 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
502 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
504 bool isGP64bit() const {
505 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
508 bool isFP64bit() const {
509 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
512 const MipsABIInfo &getABI() const { return ABI; }
513 bool isABI_N32() const { return ABI.IsN32(); }
514 bool isABI_N64() const { return ABI.IsN64(); }
515 bool isABI_O32() const { return ABI.IsO32(); }
516 bool isABI_FPXX() const {
517 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
520 bool useOddSPReg() const {
521 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
524 bool inMicroMipsMode() const {
525 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
528 bool hasMips1() const {
529 return getSTI().getFeatureBits()[Mips::FeatureMips1];
532 bool hasMips2() const {
533 return getSTI().getFeatureBits()[Mips::FeatureMips2];
536 bool hasMips3() const {
537 return getSTI().getFeatureBits()[Mips::FeatureMips3];
540 bool hasMips4() const {
541 return getSTI().getFeatureBits()[Mips::FeatureMips4];
544 bool hasMips5() const {
545 return getSTI().getFeatureBits()[Mips::FeatureMips5];
548 bool hasMips32() const {
549 return getSTI().getFeatureBits()[Mips::FeatureMips32];
552 bool hasMips64() const {
553 return getSTI().getFeatureBits()[Mips::FeatureMips64];
556 bool hasMips32r2() const {
557 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
560 bool hasMips64r2() const {
561 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
564 bool hasMips32r3() const {
565 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
568 bool hasMips64r3() const {
569 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
572 bool hasMips32r5() const {
573 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
576 bool hasMips64r5() const {
577 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
580 bool hasMips32r6() const {
581 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
584 bool hasMips64r6() const {
585 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
588 bool hasDSP() const {
589 return getSTI().getFeatureBits()[Mips::FeatureDSP];
592 bool hasDSPR2() const {
593 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
596 bool hasDSPR3() const {
597 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
600 bool hasMSA() const {
601 return getSTI().getFeatureBits()[Mips::FeatureMSA];
604 bool hasCnMips() const {
605 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
612 bool inMips16Mode() const {
613 return getSTI().getFeatureBits()[Mips::FeatureMips16];
616 bool useTraps() const {
617 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
620 bool useSoftFloat() const {
621 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
624 /// Warn if RegIndex is the same as the current AT.
625 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
627 void warnIfNoMacro(SMLoc Loc);
629 bool isLittle() const { return IsLittleEndian; }
631 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
632 AsmToken::TokenKind OperatorToken,
633 MCContext &Ctx) override {
634 switch(OperatorToken) {
636 llvm_unreachable("Unknown token");
638 case AsmToken::PercentCall16:
639 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
640 case AsmToken::PercentCall_Hi:
641 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
642 case AsmToken::PercentCall_Lo:
643 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
644 case AsmToken::PercentDtprel_Hi:
645 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
646 case AsmToken::PercentDtprel_Lo:
647 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
648 case AsmToken::PercentGot:
649 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
650 case AsmToken::PercentGot_Disp:
651 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
652 case AsmToken::PercentGot_Hi:
653 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
654 case AsmToken::PercentGot_Lo:
655 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
656 case AsmToken::PercentGot_Ofst:
657 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
658 case AsmToken::PercentGot_Page:
659 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
660 case AsmToken::PercentGottprel:
661 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
662 case AsmToken::PercentGp_Rel:
663 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
664 case AsmToken::PercentHi:
665 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
666 case AsmToken::PercentHigher:
667 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
668 case AsmToken::PercentHighest:
669 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
670 case AsmToken::PercentLo:
671 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
672 case AsmToken::PercentNeg:
673 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
674 case AsmToken::PercentPcrel_Hi:
675 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
676 case AsmToken::PercentPcrel_Lo:
677 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
678 case AsmToken::PercentTlsgd:
679 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
680 case AsmToken::PercentTlsldm:
681 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
682 case AsmToken::PercentTprel_Hi:
683 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
684 case AsmToken::PercentTprel_Lo:
685 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
690 /// MipsOperand - Instances of this class represent a parsed Mips machine
692 class MipsOperand : public MCParsedAsmOperand {
694 /// Broad categories of register classes
695 /// The exact class is finalized by the render method.
697 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
698 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
700 RegKind_FCC = 4, /// FCC
701 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
702 RegKind_MSACtrl = 16, /// MSA control registers
703 RegKind_COP2 = 32, /// COP2
704 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
706 RegKind_CCR = 128, /// CCR
707 RegKind_HWRegs = 256, /// HWRegs
708 RegKind_COP3 = 512, /// COP3
709 RegKind_COP0 = 1024, /// COP0
710 /// Potentially any (e.g. $1)
711 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
712 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
713 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
718 k_Immediate, /// An immediate (possibly involving symbol references)
719 k_Memory, /// Base + Offset Memory Address
720 k_RegisterIndex, /// A register index in one or more RegKind.
721 k_Token, /// A simple token
722 k_RegList, /// A physical register list
723 k_RegPair /// A pair of physical register
727 MipsOperand(KindTy K, MipsAsmParser &Parser)
728 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
730 ~MipsOperand() override {
739 case k_RegisterIndex:
747 /// For diagnostics, and checking the assembler temporary
748 MipsAsmParser &AsmParser;
756 unsigned Index; /// Index into the register class
757 RegKind Kind; /// Bitfield of the kinds it could possibly be
758 struct Token Tok; /// The input token this operand originated from.
759 const MCRegisterInfo *RegInfo;
772 SmallVector<unsigned, 10> *List;
777 struct RegIdxOp RegIdx;
780 struct RegListOp RegList;
783 SMLoc StartLoc, EndLoc;
785 /// Internal constructor for register kinds
786 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
788 const MCRegisterInfo *RegInfo,
790 MipsAsmParser &Parser) {
791 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
792 Op->RegIdx.Index = Index;
793 Op->RegIdx.RegInfo = RegInfo;
794 Op->RegIdx.Kind = RegKind;
795 Op->RegIdx.Tok.Data = Str.data();
796 Op->RegIdx.Tok.Length = Str.size();
803 /// Coerce the register to GPR32 and return the real register for the current
805 unsigned getGPR32Reg() const {
806 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
807 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
808 unsigned ClassID = Mips::GPR32RegClassID;
809 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
812 /// Coerce the register to GPR32 and return the real register for the current
814 unsigned getGPRMM16Reg() const {
815 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
816 unsigned ClassID = Mips::GPR32RegClassID;
817 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
820 /// Coerce the register to GPR64 and return the real register for the current
822 unsigned getGPR64Reg() const {
823 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
824 unsigned ClassID = Mips::GPR64RegClassID;
825 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
829 /// Coerce the register to AFGR64 and return the real register for the current
831 unsigned getAFGR64Reg() const {
832 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
833 if (RegIdx.Index % 2 != 0)
834 AsmParser.Warning(StartLoc, "Float register should be even.");
835 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
836 .getRegister(RegIdx.Index / 2);
839 /// Coerce the register to FGR64 and return the real register for the current
841 unsigned getFGR64Reg() const {
842 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
843 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
844 .getRegister(RegIdx.Index);
847 /// Coerce the register to FGR32 and return the real register for the current
849 unsigned getFGR32Reg() const {
850 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
851 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
852 .getRegister(RegIdx.Index);
855 /// Coerce the register to FGRH32 and return the real register for the current
857 unsigned getFGRH32Reg() const {
858 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
859 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
860 .getRegister(RegIdx.Index);
863 /// Coerce the register to FCC and return the real register for the current
865 unsigned getFCCReg() const {
866 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
867 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
868 .getRegister(RegIdx.Index);
871 /// Coerce the register to MSA128 and return the real register for the current
873 unsigned getMSA128Reg() const {
874 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
875 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
877 unsigned ClassID = Mips::MSA128BRegClassID;
878 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
881 /// Coerce the register to MSACtrl and return the real register for the
883 unsigned getMSACtrlReg() const {
884 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
885 unsigned ClassID = Mips::MSACtrlRegClassID;
886 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
889 /// Coerce the register to COP0 and return the real register for the
891 unsigned getCOP0Reg() const {
892 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
893 unsigned ClassID = Mips::COP0RegClassID;
894 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
897 /// Coerce the register to COP2 and return the real register for the
899 unsigned getCOP2Reg() const {
900 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
901 unsigned ClassID = Mips::COP2RegClassID;
902 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
905 /// Coerce the register to COP3 and return the real register for the
907 unsigned getCOP3Reg() const {
908 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
909 unsigned ClassID = Mips::COP3RegClassID;
910 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
913 /// Coerce the register to ACC64DSP and return the real register for the
915 unsigned getACC64DSPReg() const {
916 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
917 unsigned ClassID = Mips::ACC64DSPRegClassID;
918 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
921 /// Coerce the register to HI32DSP and return the real register for the
923 unsigned getHI32DSPReg() const {
924 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
925 unsigned ClassID = Mips::HI32DSPRegClassID;
926 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
929 /// Coerce the register to LO32DSP and return the real register for the
931 unsigned getLO32DSPReg() const {
932 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
933 unsigned ClassID = Mips::LO32DSPRegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 /// Coerce the register to CCR and return the real register for the
939 unsigned getCCRReg() const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
941 unsigned ClassID = Mips::CCRRegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 /// Coerce the register to HWRegs and return the real register for the
947 unsigned getHWRegsReg() const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
949 unsigned ClassID = Mips::HWRegsRegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
954 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
955 // Add as immediate when possible. Null MCExpr = 0.
957 Inst.addOperand(MCOperand::createImm(0));
958 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
959 Inst.addOperand(MCOperand::createImm(CE->getValue()));
961 Inst.addOperand(MCOperand::createExpr(Expr));
964 void addRegOperands(MCInst &Inst, unsigned N) const {
965 llvm_unreachable("Use a custom parser instead");
968 /// Render the operand to an MCInst as a GPR32
969 /// Asserts if the wrong number of operands are requested, or the operand
970 /// is not a k_RegisterIndex compatible with RegKind_GPR
971 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
972 assert(N == 1 && "Invalid number of operands!");
973 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
976 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
977 assert(N == 1 && "Invalid number of operands!");
978 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
981 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
982 assert(N == 1 && "Invalid number of operands!");
983 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
986 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
987 assert(N == 1 && "Invalid number of operands!");
988 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
991 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
992 assert(N == 1 && "Invalid number of operands!");
993 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
996 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
997 assert(N == 1 && "Invalid number of operands!");
998 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1001 /// Render the operand to an MCInst as a GPR64
1002 /// Asserts if the wrong number of operands are requested, or the operand
1003 /// is not a k_RegisterIndex compatible with RegKind_GPR
1004 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1005 assert(N == 1 && "Invalid number of operands!");
1006 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1009 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1010 assert(N == 1 && "Invalid number of operands!");
1011 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1014 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1015 assert(N == 1 && "Invalid number of operands!");
1016 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1019 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1020 assert(N == 1 && "Invalid number of operands!");
1021 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1022 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1023 // FIXME: This should propagate failure up to parseStatement.
1024 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1025 AsmParser.getParser().printError(
1026 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1030 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1031 assert(N == 1 && "Invalid number of operands!");
1032 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1035 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1036 assert(N == 1 && "Invalid number of operands!");
1037 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1040 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1041 assert(N == 1 && "Invalid number of operands!");
1042 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1045 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1046 assert(N == 1 && "Invalid number of operands!");
1047 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1050 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1051 assert(N == 1 && "Invalid number of operands!");
1052 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1055 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1056 assert(N == 1 && "Invalid number of operands!");
1057 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1060 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1061 assert(N == 1 && "Invalid number of operands!");
1062 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1065 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1066 assert(N == 1 && "Invalid number of operands!");
1067 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1070 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1071 assert(N == 1 && "Invalid number of operands!");
1072 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1075 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1076 assert(N == 1 && "Invalid number of operands!");
1077 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1080 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1081 assert(N == 1 && "Invalid number of operands!");
1082 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1085 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1086 assert(N == 1 && "Invalid number of operands!");
1087 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1090 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1091 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 uint64_t Imm = getConstantImm() - Offset;
1094 Imm &= (1ULL << Bits) - 1;
1096 Imm += AdjustOffset;
1097 Inst.addOperand(MCOperand::createImm(Imm));
1100 template <unsigned Bits>
1101 void addSImmOperands(MCInst &Inst, unsigned N) const {
1102 if (isImm() && !isConstantImm()) {
1103 addExpr(Inst, getImm());
1106 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1109 template <unsigned Bits>
1110 void addUImmOperands(MCInst &Inst, unsigned N) const {
1111 if (isImm() && !isConstantImm()) {
1112 addExpr(Inst, getImm());
1115 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1118 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1119 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1120 assert(N == 1 && "Invalid number of operands!");
1121 int64_t Imm = getConstantImm() - Offset;
1122 Imm = SignExtend64<Bits>(Imm);
1124 Imm += AdjustOffset;
1125 Inst.addOperand(MCOperand::createImm(Imm));
1128 void addImmOperands(MCInst &Inst, unsigned N) const {
1129 assert(N == 1 && "Invalid number of operands!");
1130 const MCExpr *Expr = getImm();
1131 addExpr(Inst, Expr);
1134 void addMemOperands(MCInst &Inst, unsigned N) const {
1135 assert(N == 2 && "Invalid number of operands!");
1137 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1138 ? getMemBase()->getGPR64Reg()
1139 : getMemBase()->getGPR32Reg()));
1141 const MCExpr *Expr = getMemOff();
1142 addExpr(Inst, Expr);
1145 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1146 assert(N == 2 && "Invalid number of operands!");
1148 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1150 const MCExpr *Expr = getMemOff();
1151 addExpr(Inst, Expr);
1154 void addRegListOperands(MCInst &Inst, unsigned N) const {
1155 assert(N == 1 && "Invalid number of operands!");
1157 for (auto RegNo : getRegList())
1158 Inst.addOperand(MCOperand::createReg(RegNo));
1161 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1162 assert(N == 2 && "Invalid number of operands!");
1163 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1164 unsigned RegNo = getRegPair();
1165 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1166 Inst.addOperand(MCOperand::createReg(
1167 RegIdx.RegInfo->getRegClass(
1168 AsmParser.getABI().AreGprs64bit()
1169 ? Mips::GPR64RegClassID
1170 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1171 Inst.addOperand(MCOperand::createReg(
1172 RegIdx.RegInfo->getRegClass(
1173 AsmParser.getABI().AreGprs64bit()
1174 ? Mips::GPR64RegClassID
1175 : Mips::GPR32RegClassID).getRegister(RegNo)));
1178 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1179 assert(N == 2 && "Invalid number of operands!");
1180 for (auto RegNo : getRegList())
1181 Inst.addOperand(MCOperand::createReg(RegNo));
1184 bool isReg() const override {
1185 // As a special case until we sort out the definition of div/divu, accept
1186 // $0/$zero here so that MCK_ZERO works correctly.
1187 return isGPRAsmReg() && RegIdx.Index == 0;
1190 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1191 bool isImm() const override { return Kind == k_Immediate; }
1193 bool isConstantImm() const {
1195 return isImm() && getImm()->evaluateAsAbsolute(Res);
1198 bool isConstantImmz() const {
1199 return isConstantImm() && getConstantImm() == 0;
1202 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1203 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1206 template <unsigned Bits> bool isSImm() const {
1207 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1210 template <unsigned Bits> bool isUImm() const {
1211 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1214 template <unsigned Bits> bool isAnyImm() const {
1215 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1216 isUInt<Bits>(getConstantImm()))
1220 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1221 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1224 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1225 return isConstantImm() && getConstantImm() >= Bottom &&
1226 getConstantImm() <= Top;
1229 bool isToken() const override {
1230 // Note: It's not possible to pretend that other operand kinds are tokens.
1231 // The matcher emitter checks tokens first.
1232 return Kind == k_Token;
1235 bool isMem() const override { return Kind == k_Memory; }
1237 bool isConstantMemOff() const {
1238 return isMem() && isa<MCConstantExpr>(getMemOff());
1241 // Allow relocation operators.
1242 // FIXME: This predicate and others need to look through binary expressions
1243 // and determine whether a Value is a constant or not.
1244 template <unsigned Bits, unsigned ShiftAmount = 0>
1245 bool isMemWithSimmOffset() const {
1248 if (!getMemBase()->isGPRAsmReg())
1250 if (isa<MCTargetExpr>(getMemOff()) ||
1251 (isConstantMemOff() &&
1252 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1255 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1256 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1259 bool isMemWithGRPMM16Base() const {
1260 return isMem() && getMemBase()->isMM16AsmReg();
1263 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1264 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1265 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1268 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1269 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1270 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1271 && (getMemBase()->getGPR32Reg() == Mips::SP);
1274 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1275 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1276 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1277 && (getMemBase()->getGPR32Reg() == Mips::GP);
1280 template <unsigned Bits, unsigned ShiftLeftAmount>
1281 bool isScaledUImm() const {
1282 return isConstantImm() &&
1283 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1286 template <unsigned Bits, unsigned ShiftLeftAmount>
1287 bool isScaledSImm() const {
1288 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1290 // Operand can also be a symbol or symbol plus offset in case of relocations.
1291 if (Kind != k_Immediate)
1294 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1295 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1298 bool isRegList16() const {
1302 int Size = RegList.List->size();
1303 if (Size < 2 || Size > 5)
1306 unsigned R0 = RegList.List->front();
1307 unsigned R1 = RegList.List->back();
1308 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1309 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1312 int PrevReg = *RegList.List->begin();
1313 for (int i = 1; i < Size - 1; i++) {
1314 int Reg = (*(RegList.List))[i];
1315 if ( Reg != PrevReg + 1)
1323 bool isInvNum() const { return Kind == k_Immediate; }
1325 bool isLSAImm() const {
1326 if (!isConstantImm())
1328 int64_t Val = getConstantImm();
1329 return 1 <= Val && Val <= 4;
1332 bool isRegList() const { return Kind == k_RegList; }
1334 bool isMovePRegPair() const {
1335 if (Kind != k_RegList || RegList.List->size() != 2)
1338 unsigned R0 = RegList.List->front();
1339 unsigned R1 = RegList.List->back();
1341 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1342 (R0 == Mips::A1 && R1 == Mips::A3) ||
1343 (R0 == Mips::A2 && R1 == Mips::A3) ||
1344 (R0 == Mips::A0 && R1 == Mips::S5) ||
1345 (R0 == Mips::A0 && R1 == Mips::S6) ||
1346 (R0 == Mips::A0 && R1 == Mips::A1) ||
1347 (R0 == Mips::A0 && R1 == Mips::A2) ||
1348 (R0 == Mips::A0 && R1 == Mips::A3) ||
1349 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1350 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1351 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1352 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1353 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1354 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1355 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1356 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1362 StringRef getToken() const {
1363 assert(Kind == k_Token && "Invalid access!");
1364 return StringRef(Tok.Data, Tok.Length);
1367 bool isRegPair() const {
1368 return Kind == k_RegPair && RegIdx.Index <= 30;
1371 unsigned getReg() const override {
1372 // As a special case until we sort out the definition of div/divu, accept
1373 // $0/$zero here so that MCK_ZERO works correctly.
1374 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1375 RegIdx.Kind & RegKind_GPR)
1376 return getGPR32Reg(); // FIXME: GPR64 too
1378 llvm_unreachable("Invalid access!");
1382 const MCExpr *getImm() const {
1383 assert((Kind == k_Immediate) && "Invalid access!");
1387 int64_t getConstantImm() const {
1388 const MCExpr *Val = getImm();
1390 (void)Val->evaluateAsAbsolute(Value);
1394 MipsOperand *getMemBase() const {
1395 assert((Kind == k_Memory) && "Invalid access!");
1399 const MCExpr *getMemOff() const {
1400 assert((Kind == k_Memory) && "Invalid access!");
1404 int64_t getConstantMemOff() const {
1405 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1408 const SmallVectorImpl<unsigned> &getRegList() const {
1409 assert((Kind == k_RegList) && "Invalid access!");
1410 return *(RegList.List);
1413 unsigned getRegPair() const {
1414 assert((Kind == k_RegPair) && "Invalid access!");
1415 return RegIdx.Index;
1418 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1419 MipsAsmParser &Parser) {
1420 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1421 Op->Tok.Data = Str.data();
1422 Op->Tok.Length = Str.size();
1428 /// Create a numeric register (e.g. $1). The exact register remains
1429 /// unresolved until an instruction successfully matches
1430 static std::unique_ptr<MipsOperand>
1431 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1432 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1433 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1434 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1437 /// Create a register that is definitely a GPR.
1438 /// This is typically only used for named registers such as $gp.
1439 static std::unique_ptr<MipsOperand>
1440 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1441 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1442 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1445 /// Create a register that is definitely a FGR.
1446 /// This is typically only used for named registers such as $f0.
1447 static std::unique_ptr<MipsOperand>
1448 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1449 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1450 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1453 /// Create a register that is definitely a HWReg.
1454 /// This is typically only used for named registers such as $hwr_cpunum.
1455 static std::unique_ptr<MipsOperand>
1456 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1457 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1458 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1461 /// Create a register that is definitely an FCC.
1462 /// This is typically only used for named registers such as $fcc0.
1463 static std::unique_ptr<MipsOperand>
1464 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1465 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1466 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1469 /// Create a register that is definitely an ACC.
1470 /// This is typically only used for named registers such as $ac0.
1471 static std::unique_ptr<MipsOperand>
1472 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1473 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1474 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1477 /// Create a register that is definitely an MSA128.
1478 /// This is typically only used for named registers such as $w0.
1479 static std::unique_ptr<MipsOperand>
1480 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1481 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1482 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1485 /// Create a register that is definitely an MSACtrl.
1486 /// This is typically only used for named registers such as $msaaccess.
1487 static std::unique_ptr<MipsOperand>
1488 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1489 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1490 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1493 static std::unique_ptr<MipsOperand>
1494 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1495 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1502 static std::unique_ptr<MipsOperand>
1503 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1504 SMLoc E, MipsAsmParser &Parser) {
1505 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1506 Op->Mem.Base = Base.release();
1513 static std::unique_ptr<MipsOperand>
1514 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1515 MipsAsmParser &Parser) {
1516 assert(Regs.size() > 0 && "Empty list not allowed");
1518 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1519 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1520 Op->StartLoc = StartLoc;
1521 Op->EndLoc = EndLoc;
1525 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1527 MipsAsmParser &Parser) {
1528 auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
1529 Op->RegIdx.Index = MOP.RegIdx.Index;
1530 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1531 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1537 bool isGPRZeroAsmReg() const {
1538 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1541 bool isGPRNonZeroAsmReg() const {
1542 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1546 bool isGPRAsmReg() const {
1547 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1550 bool isMM16AsmReg() const {
1551 if (!(isRegIdx() && RegIdx.Kind))
1553 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1554 || RegIdx.Index == 16 || RegIdx.Index == 17);
1557 bool isMM16AsmRegZero() const {
1558 if (!(isRegIdx() && RegIdx.Kind))
1560 return (RegIdx.Index == 0 ||
1561 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1562 RegIdx.Index == 17);
1565 bool isMM16AsmRegMoveP() const {
1566 if (!(isRegIdx() && RegIdx.Kind))
1568 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1569 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1572 bool isFGRAsmReg() const {
1573 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1574 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1577 bool isHWRegsAsmReg() const {
1578 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1581 bool isCCRAsmReg() const {
1582 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1585 bool isFCCAsmReg() const {
1586 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1588 return RegIdx.Index <= 7;
1591 bool isACCAsmReg() const {
1592 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1595 bool isCOP0AsmReg() const {
1596 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1599 bool isCOP2AsmReg() const {
1600 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1603 bool isCOP3AsmReg() const {
1604 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1607 bool isMSA128AsmReg() const {
1608 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1611 bool isMSACtrlAsmReg() const {
1612 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1615 /// getStartLoc - Get the location of the first token of this operand.
1616 SMLoc getStartLoc() const override { return StartLoc; }
1617 /// getEndLoc - Get the location of the last token of this operand.
1618 SMLoc getEndLoc() const override { return EndLoc; }
1620 void print(raw_ostream &OS) const override {
1629 Mem.Base->print(OS);
1634 case k_RegisterIndex:
1635 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1636 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1643 for (auto Reg : (*RegList.List))
1648 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1653 bool isValidForTie(const MipsOperand &Other) const {
1654 if (Kind != Other.Kind)
1659 llvm_unreachable("Unexpected kind");
1661 case k_RegisterIndex: {
1662 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1663 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1664 return Token == OtherToken;
1668 }; // class MipsOperand
1670 } // end anonymous namespace
1674 extern const MCInstrDesc MipsInsts[];
1676 } // end namespace llvm
1678 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1679 return MipsInsts[Opcode];
1682 static bool hasShortDelaySlot(unsigned Opcode) {
1685 case Mips::JALRS_MM:
1686 case Mips::JALRS16_MM:
1687 case Mips::BGEZALS_MM:
1688 case Mips::BLTZALS_MM:
1695 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1696 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1697 return &SRExpr->getSymbol();
1700 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1701 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1702 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1713 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1714 return getSingleMCSymbol(UExpr->getSubExpr());
1719 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1720 if (isa<MCSymbolRefExpr>(Expr))
1723 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1724 return countMCSymbolRefExpr(BExpr->getLHS()) +
1725 countMCSymbolRefExpr(BExpr->getRHS());
1727 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1728 return countMCSymbolRefExpr(UExpr->getSubExpr());
1733 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1735 const MCSubtargetInfo *STI) {
1736 MipsTargetStreamer &TOut = getTargetStreamer();
1737 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1738 bool ExpandedJalSym = false;
1742 if (MCID.isBranch() || MCID.isCall()) {
1743 const unsigned Opcode = Inst.getOpcode();
1753 assert(hasCnMips() && "instruction only valid for octeon cpus");
1760 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1761 Offset = Inst.getOperand(2);
1762 if (!Offset.isImm())
1763 break; // We'll deal with this situation later on when applying fixups.
1764 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1765 return Error(IDLoc, "branch target out of range");
1766 if (OffsetToAlignment(Offset.getImm(),
1767 1LL << (inMicroMipsMode() ? 1 : 2)))
1768 return Error(IDLoc, "branch to misaligned address");
1782 case Mips::BGEZAL_MM:
1783 case Mips::BLTZAL_MM:
1786 case Mips::BC1EQZC_MMR6:
1787 case Mips::BC1NEZC_MMR6:
1788 case Mips::BC2EQZC_MMR6:
1789 case Mips::BC2NEZC_MMR6:
1790 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1791 Offset = Inst.getOperand(1);
1792 if (!Offset.isImm())
1793 break; // We'll deal with this situation later on when applying fixups.
1794 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1795 return Error(IDLoc, "branch target out of range");
1796 if (OffsetToAlignment(Offset.getImm(),
1797 1LL << (inMicroMipsMode() ? 1 : 2)))
1798 return Error(IDLoc, "branch to misaligned address");
1800 case Mips::BGEC: case Mips::BGEC_MMR6:
1801 case Mips::BLTC: case Mips::BLTC_MMR6:
1802 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1803 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1804 case Mips::BEQC: case Mips::BEQC_MMR6:
1805 case Mips::BNEC: case Mips::BNEC_MMR6:
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(18, Offset.getImm()))
1811 return Error(IDLoc, "branch target out of range");
1812 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1813 return Error(IDLoc, "branch to misaligned address");
1815 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1816 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1817 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1818 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1819 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1820 Offset = Inst.getOperand(1);
1821 if (!Offset.isImm())
1822 break; // We'll deal with this situation later on when applying fixups.
1823 if (!isIntN(18, Offset.getImm()))
1824 return Error(IDLoc, "branch target out of range");
1825 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1826 return Error(IDLoc, "branch to misaligned address");
1828 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1829 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1830 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1831 Offset = Inst.getOperand(1);
1832 if (!Offset.isImm())
1833 break; // We'll deal with this situation later on when applying fixups.
1834 if (!isIntN(23, Offset.getImm()))
1835 return Error(IDLoc, "branch target out of range");
1836 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1837 return Error(IDLoc, "branch to misaligned address");
1839 case Mips::BEQZ16_MM:
1840 case Mips::BEQZC16_MMR6:
1841 case Mips::BNEZ16_MM:
1842 case Mips::BNEZC16_MMR6:
1843 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1844 Offset = Inst.getOperand(1);
1845 if (!Offset.isImm())
1846 break; // We'll deal with this situation later on when applying fixups.
1847 if (!isInt<8>(Offset.getImm()))
1848 return Error(IDLoc, "branch target out of range");
1849 if (OffsetToAlignment(Offset.getImm(), 2LL))
1850 return Error(IDLoc, "branch to misaligned address");
1855 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1856 // We still accept it but it is a normal nop.
1857 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1858 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1859 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1864 const unsigned Opcode = Inst.getOpcode();
1876 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1877 // The offset is handled above
1878 Opnd = Inst.getOperand(1);
1880 return Error(IDLoc, "expected immediate operand kind");
1881 Imm = Opnd.getImm();
1882 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1883 Opcode == Mips::BBIT1 ? 63 : 31))
1884 return Error(IDLoc, "immediate operand value out of range");
1886 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1888 Inst.getOperand(1).setImm(Imm - 32);
1894 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1895 Opnd = Inst.getOperand(2);
1897 return Error(IDLoc, "expected immediate operand kind");
1898 Imm = Opnd.getImm();
1899 if (!isInt<10>(Imm))
1900 return Error(IDLoc, "immediate operand value out of range");
1905 // Warn on division by zero. We're checking here as all instructions get
1906 // processed here, not just the macros that need expansion.
1908 // The MIPS backend models most of the divison instructions and macros as
1909 // three operand instructions. The pre-R6 divide instructions however have
1910 // two operands and explicitly define HI/LO as part of the instruction,
1911 // not in the operands.
1912 unsigned FirstOp = 1;
1913 unsigned SecondOp = 2;
1914 switch (Inst.getOpcode()) {
1917 case Mips::SDivIMacro:
1918 case Mips::UDivIMacro:
1919 case Mips::DSDivIMacro:
1920 case Mips::DUDivIMacro:
1921 if (Inst.getOperand(2).getImm() == 0) {
1922 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1923 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1924 Warning(IDLoc, "dividing zero by zero");
1926 Warning(IDLoc, "division by zero");
1937 case Mips::SDivMacro:
1938 case Mips::DSDivMacro:
1939 case Mips::UDivMacro:
1940 case Mips::DUDivMacro:
1945 case Mips::DIVU_MMR6:
1946 case Mips::DDIVU_MM64R6:
1947 case Mips::DIV_MMR6:
1948 case Mips::DDIV_MM64R6:
1949 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1950 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1951 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1952 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1953 Warning(IDLoc, "dividing zero by zero");
1955 Warning(IDLoc, "division by zero");
1960 // For PIC code convert unconditional jump to unconditional branch.
1961 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1964 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1965 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1966 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1967 BInst.addOperand(Inst.getOperand(0));
1971 // This expansion is not in a function called by tryExpandInstruction()
1972 // because the pseudo-instruction doesn't have a distinct opcode.
1973 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1975 warnIfNoMacro(IDLoc);
1977 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1979 // We can do this expansion if there's only 1 symbol in the argument
1981 if (countMCSymbolRefExpr(JalExpr) > 1)
1982 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1984 // FIXME: This is checking the expression can be handled by the later stages
1985 // of the assembler. We ought to leave it to those later stages.
1986 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1988 // FIXME: Add support for label+offset operands (currently causes an error).
1989 // FIXME: Add support for forward-declared local symbols.
1990 // FIXME: Add expansion for when the LargeGOT option is enabled.
1991 if (JalSym->isInSection() || JalSym->isTemporary() ||
1992 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
1994 // If it's a local symbol and the O32 ABI is being used, we expand to:
1996 // R_(MICRO)MIPS_GOT16 label
1997 // addiu $25, $25, 0
1998 // R_(MICRO)MIPS_LO16 label
2000 const MCExpr *Got16RelocExpr =
2001 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2002 const MCExpr *Lo16RelocExpr =
2003 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2005 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2006 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2007 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2008 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2009 } else if (isABI_N32() || isABI_N64()) {
2010 // If it's a local symbol and the N32/N64 ABIs are being used,
2012 // lw/ld $25, 0($gp)
2013 // R_(MICRO)MIPS_GOT_DISP label
2015 const MCExpr *GotDispRelocExpr =
2016 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2018 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2019 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2023 // If it's an external/weak symbol, we expand to:
2024 // lw/ld $25, 0($gp)
2025 // R_(MICRO)MIPS_CALL16 label
2027 const MCExpr *Call16RelocExpr =
2028 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2030 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2031 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2035 if (IsCpRestoreSet && inMicroMipsMode())
2036 JalrInst.setOpcode(Mips::JALRS_MM);
2038 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2039 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2040 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2042 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
2043 // This relocation is supposed to be an optimization hint for the linker
2044 // and is not necessary for correctness.
2047 ExpandedJalSym = true;
2050 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2051 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2052 // Check the offset of memory operand, if it is a symbol
2053 // reference or immediate we may have to expand instructions.
2054 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2055 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2056 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2057 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2058 MCOperand &Op = Inst.getOperand(i);
2060 int MemOffset = Op.getImm();
2061 if (MemOffset < -32768 || MemOffset > 32767) {
2062 // Offset can't exceed 16bit value.
2063 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
2064 return getParser().hasPendingError();
2066 } else if (Op.isExpr()) {
2067 const MCExpr *Expr = Op.getExpr();
2068 if (Expr->getKind() == MCExpr::SymbolRef) {
2069 const MCSymbolRefExpr *SR =
2070 static_cast<const MCSymbolRefExpr *>(Expr);
2071 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2073 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2074 return getParser().hasPendingError();
2076 } else if (!isEvaluated(Expr)) {
2077 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
2078 return getParser().hasPendingError();
2085 if (inMicroMipsMode()) {
2086 if (MCID.mayLoad()) {
2087 // Try to create 16-bit GP relative load instruction.
2088 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2089 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2090 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2091 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2092 MCOperand &Op = Inst.getOperand(i);
2094 int MemOffset = Op.getImm();
2095 MCOperand &DstReg = Inst.getOperand(0);
2096 MCOperand &BaseReg = Inst.getOperand(1);
2097 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2098 getContext().getRegisterInfo()->getRegClass(
2099 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2100 (BaseReg.getReg() == Mips::GP ||
2101 BaseReg.getReg() == Mips::GP_64)) {
2103 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2112 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2117 switch (Inst.getOpcode()) {
2120 case Mips::ADDIUSP_MM:
2121 Opnd = Inst.getOperand(0);
2123 return Error(IDLoc, "expected immediate operand kind");
2124 Imm = Opnd.getImm();
2125 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2127 return Error(IDLoc, "immediate operand value out of range");
2129 case Mips::SLL16_MM:
2130 case Mips::SRL16_MM:
2131 Opnd = Inst.getOperand(2);
2133 return Error(IDLoc, "expected immediate operand kind");
2134 Imm = Opnd.getImm();
2135 if (Imm < 1 || Imm > 8)
2136 return Error(IDLoc, "immediate operand value out of range");
2139 Opnd = Inst.getOperand(1);
2141 return Error(IDLoc, "expected immediate operand kind");
2142 Imm = Opnd.getImm();
2143 if (Imm < -1 || Imm > 126)
2144 return Error(IDLoc, "immediate operand value out of range");
2146 case Mips::ADDIUR2_MM:
2147 Opnd = Inst.getOperand(2);
2149 return Error(IDLoc, "expected immediate operand kind");
2150 Imm = Opnd.getImm();
2151 if (!(Imm == 1 || Imm == -1 ||
2152 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2153 return Error(IDLoc, "immediate operand value out of range");
2155 case Mips::ANDI16_MM:
2156 Opnd = Inst.getOperand(2);
2158 return Error(IDLoc, "expected immediate operand kind");
2159 Imm = Opnd.getImm();
2160 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2161 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2162 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2163 return Error(IDLoc, "immediate operand value out of range");
2165 case Mips::LBU16_MM:
2166 Opnd = Inst.getOperand(2);
2168 return Error(IDLoc, "expected immediate operand kind");
2169 Imm = Opnd.getImm();
2170 if (Imm < -1 || Imm > 14)
2171 return Error(IDLoc, "immediate operand value out of range");
2174 case Mips::SB16_MMR6:
2175 Opnd = Inst.getOperand(2);
2177 return Error(IDLoc, "expected immediate operand kind");
2178 Imm = Opnd.getImm();
2179 if (Imm < 0 || Imm > 15)
2180 return Error(IDLoc, "immediate operand value out of range");
2182 case Mips::LHU16_MM:
2184 case Mips::SH16_MMR6:
2185 Opnd = Inst.getOperand(2);
2187 return Error(IDLoc, "expected immediate operand kind");
2188 Imm = Opnd.getImm();
2189 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2190 return Error(IDLoc, "immediate operand value out of range");
2194 case Mips::SW16_MMR6:
2195 Opnd = Inst.getOperand(2);
2197 return Error(IDLoc, "expected immediate operand kind");
2198 Imm = Opnd.getImm();
2199 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2200 return Error(IDLoc, "immediate operand value out of range");
2202 case Mips::ADDIUPC_MM:
2203 MCOperand Opnd = Inst.getOperand(1);
2205 return Error(IDLoc, "expected immediate operand kind");
2206 int Imm = Opnd.getImm();
2207 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2208 return Error(IDLoc, "immediate operand value out of range");
2213 bool FillDelaySlot =
2214 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2216 TOut.emitDirectiveSetNoReorder();
2218 MacroExpanderResultTy ExpandResult =
2219 tryExpandInstruction(Inst, IDLoc, Out, STI);
2220 switch (ExpandResult) {
2222 Out.EmitInstruction(Inst, *STI);
2230 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2231 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2232 if (inMicroMipsMode())
2233 TOut.setUsesMicroMips();
2235 // If this instruction has a delay slot and .set reorder is active,
2236 // emit a NOP after it.
2237 if (FillDelaySlot) {
2238 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2239 TOut.emitDirectiveSetReorder();
2242 if ((Inst.getOpcode() == Mips::JalOneReg ||
2243 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2244 isPicAndNotNxxAbi()) {
2245 if (IsCpRestoreSet) {
2246 // We need a NOP between the JALR and the LW:
2247 // If .set reorder has been used, we've already emitted a NOP.
2248 // If .set noreorder has been used, we need to emit a NOP at this point.
2249 if (!AssemblerOptions.back()->isReorder())
2250 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2253 // Load the $gp from the stack.
2254 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2256 Warning(IDLoc, "no .cprestore used in PIC mode");
2262 MipsAsmParser::MacroExpanderResultTy
2263 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2264 const MCSubtargetInfo *STI) {
2265 switch (Inst.getOpcode()) {
2267 return MER_NotAMacro;
2268 case Mips::LoadImm32:
2269 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2270 case Mips::LoadImm64:
2271 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2272 case Mips::LoadAddrImm32:
2273 case Mips::LoadAddrImm64:
2274 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2275 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2276 "expected immediate operand kind");
2278 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2280 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2284 case Mips::LoadAddrReg32:
2285 case Mips::LoadAddrReg64:
2286 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2287 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2288 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2289 "expected immediate operand kind");
2291 return expandLoadAddress(Inst.getOperand(0).getReg(),
2292 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2293 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2297 case Mips::B_MM_Pseudo:
2298 case Mips::B_MMR6_Pseudo:
2299 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2303 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2305 case Mips::JalOneReg:
2306 case Mips::JalTwoReg:
2307 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2310 case Mips::BEQLImmMacro:
2311 case Mips::BNELImmMacro:
2312 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2329 case Mips::BLTImmMacro:
2330 case Mips::BLEImmMacro:
2331 case Mips::BGEImmMacro:
2332 case Mips::BGTImmMacro:
2333 case Mips::BLTUImmMacro:
2334 case Mips::BLEUImmMacro:
2335 case Mips::BGEUImmMacro:
2336 case Mips::BGTUImmMacro:
2337 case Mips::BLTLImmMacro:
2338 case Mips::BLELImmMacro:
2339 case Mips::BGELImmMacro:
2340 case Mips::BGTLImmMacro:
2341 case Mips::BLTULImmMacro:
2342 case Mips::BLEULImmMacro:
2343 case Mips::BGEULImmMacro:
2344 case Mips::BGTULImmMacro:
2345 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2346 case Mips::SDivMacro:
2347 case Mips::SDivIMacro:
2348 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2350 case Mips::DSDivMacro:
2351 case Mips::DSDivIMacro:
2352 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2354 case Mips::UDivMacro:
2355 case Mips::UDivIMacro:
2356 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2358 case Mips::DUDivMacro:
2359 case Mips::DUDivIMacro:
2360 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2362 case Mips::PseudoTRUNC_W_S:
2363 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2365 case Mips::PseudoTRUNC_W_D32:
2366 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2368 case Mips::PseudoTRUNC_W_D:
2369 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2372 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2374 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2376 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2379 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2381 case Mips::NORImm64:
2382 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2383 case Mips::SLTImm64:
2384 if (isInt<16>(Inst.getOperand(2).getImm())) {
2385 Inst.setOpcode(Mips::SLTi64);
2386 return MER_NotAMacro;
2388 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2389 case Mips::SLTUImm64:
2390 if (isInt<16>(Inst.getOperand(2).getImm())) {
2391 Inst.setOpcode(Mips::SLTiu64);
2392 return MER_NotAMacro;
2394 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2395 case Mips::ADDi: case Mips::ADDi_MM:
2396 case Mips::ADDiu: case Mips::ADDiu_MM:
2397 case Mips::SLTi: case Mips::SLTi_MM:
2398 case Mips::SLTiu: case Mips::SLTiu_MM:
2399 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2400 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2401 int64_t ImmValue = Inst.getOperand(2).getImm();
2402 if (isInt<16>(ImmValue))
2403 return MER_NotAMacro;
2404 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2407 return MER_NotAMacro;
2408 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2409 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2410 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2411 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2412 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2413 int64_t ImmValue = Inst.getOperand(2).getImm();
2414 if (isUInt<16>(ImmValue))
2415 return MER_NotAMacro;
2416 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2419 return MER_NotAMacro;
2422 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2425 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2428 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2431 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2432 case Mips::ABSMacro:
2433 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2434 case Mips::MULImmMacro:
2435 case Mips::DMULImmMacro:
2436 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2437 case Mips::MULOMacro:
2438 case Mips::DMULOMacro:
2439 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2440 case Mips::MULOUMacro:
2441 case Mips::DMULOUMacro:
2442 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2443 case Mips::DMULMacro:
2444 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2447 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2448 Inst.getOpcode() == Mips::LDMacro)
2451 case Mips::SEQMacro:
2452 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2453 case Mips::SEQIMacro:
2454 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2458 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2460 const MCSubtargetInfo *STI) {
2461 MipsTargetStreamer &TOut = getTargetStreamer();
2463 // Create a JALR instruction which is going to replace the pseudo-JAL.
2465 JalrInst.setLoc(IDLoc);
2466 const MCOperand FirstRegOp = Inst.getOperand(0);
2467 const unsigned Opcode = Inst.getOpcode();
2469 if (Opcode == Mips::JalOneReg) {
2470 // jal $rs => jalr $rs
2471 if (IsCpRestoreSet && inMicroMipsMode()) {
2472 JalrInst.setOpcode(Mips::JALRS16_MM);
2473 JalrInst.addOperand(FirstRegOp);
2474 } else if (inMicroMipsMode()) {
2475 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2476 JalrInst.addOperand(FirstRegOp);
2478 JalrInst.setOpcode(Mips::JALR);
2479 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2480 JalrInst.addOperand(FirstRegOp);
2482 } else if (Opcode == Mips::JalTwoReg) {
2483 // jal $rd, $rs => jalr $rd, $rs
2484 if (IsCpRestoreSet && inMicroMipsMode())
2485 JalrInst.setOpcode(Mips::JALRS_MM);
2487 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2488 JalrInst.addOperand(FirstRegOp);
2489 const MCOperand SecondRegOp = Inst.getOperand(1);
2490 JalrInst.addOperand(SecondRegOp);
2492 Out.EmitInstruction(JalrInst, *STI);
2494 // If .set reorder is active and branch instruction has a delay slot,
2495 // emit a NOP after it.
2496 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2497 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2498 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2504 /// Can the value be represented by a unsigned N-bit value and a shift left?
2505 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2506 unsigned BitNum = findFirstSet(x);
2508 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2511 /// Load (or add) an immediate into a register.
2513 /// @param ImmValue The immediate to load.
2514 /// @param DstReg The register that will hold the immediate.
2515 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2516 /// for a simple initialization.
2517 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2518 /// @param IsAddress True if the immediate represents an address. False if it
2520 /// @param IDLoc Location of the immediate in the source file.
2521 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2522 unsigned SrcReg, bool Is32BitImm,
2523 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2524 const MCSubtargetInfo *STI) {
2525 MipsTargetStreamer &TOut = getTargetStreamer();
2527 if (!Is32BitImm && !isGP64bit()) {
2528 Error(IDLoc, "instruction requires a 64-bit architecture");
2533 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2534 // Sign extend up to 64-bit so that the predicates match the hardware
2535 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2537 ImmValue = SignExtend64<32>(ImmValue);
2539 Error(IDLoc, "instruction requires a 32-bit immediate");
2544 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2545 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2547 bool UseSrcReg = false;
2548 if (SrcReg != Mips::NoRegister)
2551 unsigned TmpReg = DstReg;
2553 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2554 // At this point we need AT to perform the expansions and we exit if it is
2556 unsigned ATReg = getATReg(IDLoc);
2562 if (isInt<16>(ImmValue)) {
2566 // This doesn't quite follow the usual ABI expectations for N32 but matches
2567 // traditional assembler behaviour. N32 would normally use addiu for both
2568 // integers and addresses.
2569 if (IsAddress && !Is32BitImm) {
2570 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2574 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2578 if (isUInt<16>(ImmValue)) {
2579 unsigned TmpReg = DstReg;
2580 if (SrcReg == DstReg) {
2581 TmpReg = getATReg(IDLoc);
2586 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2588 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2592 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2593 warnIfNoMacro(IDLoc);
2595 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2596 uint16_t Bits15To0 = ImmValue & 0xffff;
2597 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2598 // Traditional behaviour seems to special case this particular value. It's
2599 // not clear why other masks are handled differently.
2600 if (ImmValue == 0xffffffff) {
2601 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2602 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2604 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2608 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2610 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2611 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2613 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2615 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2619 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2621 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2623 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2627 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2629 Error(IDLoc, "instruction requires a 32-bit immediate");
2633 // Traditionally, these immediates are shifted as little as possible and as
2634 // such we align the most significant bit to bit 15 of our temporary.
2635 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2636 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2637 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2638 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2639 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2640 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2643 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2648 warnIfNoMacro(IDLoc);
2650 // The remaining case is packed with a sequence of dsll and ori with zeros
2651 // being omitted and any neighbouring dsll's being coalesced.
2652 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2654 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2655 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2659 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2660 // skip it and defer the shift to the next chunk.
2661 unsigned ShiftCarriedForwards = 16;
2662 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2663 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2665 if (ImmChunk != 0) {
2666 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2667 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2668 ShiftCarriedForwards = 0;
2671 ShiftCarriedForwards += 16;
2673 ShiftCarriedForwards -= 16;
2675 // Finish any remaining shifts left by trailing zeros.
2676 if (ShiftCarriedForwards)
2677 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2680 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2685 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2686 MCStreamer &Out, const MCSubtargetInfo *STI) {
2687 const MCOperand &ImmOp = Inst.getOperand(1);
2688 assert(ImmOp.isImm() && "expected immediate operand kind");
2689 const MCOperand &DstRegOp = Inst.getOperand(0);
2690 assert(DstRegOp.isReg() && "expected register operand kind");
2692 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2693 Is32BitImm, false, IDLoc, Out, STI))
2699 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2700 const MCOperand &Offset,
2701 bool Is32BitAddress, SMLoc IDLoc,
2703 const MCSubtargetInfo *STI) {
2704 // la can't produce a usable address when addresses are 64-bit.
2705 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2706 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2707 // We currently can't do this because we depend on the equality
2708 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2709 Error(IDLoc, "la used to load 64-bit address");
2710 // Continue as if we had 'dla' instead.
2711 Is32BitAddress = false;
2715 // dla requires 64-bit addresses.
2716 if (!Is32BitAddress && !hasMips3()) {
2717 Error(IDLoc, "instruction requires a 64-bit architecture");
2721 if (!Offset.isImm())
2722 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2723 Is32BitAddress, IDLoc, Out, STI);
2725 if (!ABI.ArePtrs64bit()) {
2726 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2727 Is32BitAddress = true;
2730 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2734 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2735 unsigned DstReg, unsigned SrcReg,
2736 bool Is32BitSym, SMLoc IDLoc,
2738 const MCSubtargetInfo *STI) {
2739 MipsTargetStreamer &TOut = getTargetStreamer();
2740 bool UseSrcReg = SrcReg != Mips::NoRegister;
2741 warnIfNoMacro(IDLoc);
2743 if (inPicMode() && ABI.IsO32()) {
2745 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2746 Error(IDLoc, "expected relocatable expression");
2749 if (Res.getSymB() != nullptr) {
2750 Error(IDLoc, "expected relocatable expression with only one symbol");
2754 // The case where the result register is $25 is somewhat special. If the
2755 // symbol in the final relocation is external and not modified with a
2756 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2757 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2758 Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
2759 !Res.getSymA()->getSymbol().isTemporary()) {
2760 const MCExpr *CallExpr =
2761 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2762 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2763 MCOperand::createExpr(CallExpr), IDLoc, STI);
2767 // The remaining cases are:
2768 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2769 // >addiu $tmp, $tmp, %lo(offset)
2770 // >addiu $rd, $tmp, $rs
2771 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2772 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2773 // >addiu $rd, $tmp, $rs
2774 // The addiu's marked with a '>' may be omitted if they are redundant. If
2775 // this happens then the last instruction must use $rd as the result
2777 const MipsMCExpr *GotExpr =
2778 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2779 const MCExpr *LoExpr = nullptr;
2780 if (Res.getSymA()->getSymbol().isInSection() ||
2781 Res.getSymA()->getSymbol().isTemporary())
2782 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2783 else if (Res.getConstant() != 0) {
2784 // External symbols fully resolve the symbol with just the %got(symbol)
2785 // but we must still account for any offset to the symbol for expressions
2787 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2790 unsigned TmpReg = DstReg;
2792 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2794 // If $rs is the same as $rd, we need to use AT.
2795 // If it is not available we exit.
2796 unsigned ATReg = getATReg(IDLoc);
2802 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2803 MCOperand::createExpr(GotExpr), IDLoc, STI);
2806 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2810 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2815 const MipsMCExpr *HiExpr =
2816 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2817 const MipsMCExpr *LoExpr =
2818 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2820 // This is the 64-bit symbol address expansion.
2821 if (ABI.ArePtrs64bit() && isGP64bit()) {
2822 // We need AT for the 64-bit expansion in the cases where the optional
2823 // source register is the destination register and for the superscalar
2826 // If it is not available we exit if the destination is the same as the
2829 const MipsMCExpr *HighestExpr =
2830 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2831 const MipsMCExpr *HigherExpr =
2832 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2835 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
2837 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
2838 unsigned ATReg = getATReg(IDLoc);
2840 // If $rs is the same as $rd:
2841 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2842 // daddiu $at, $at, %higher(sym)
2843 // dsll $at, $at, 16
2844 // daddiu $at, $at, %hi(sym)
2845 // dsll $at, $at, 16
2846 // daddiu $at, $at, %lo(sym)
2847 // daddu $rd, $at, $rd
2848 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2850 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2851 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2852 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2853 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2855 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2856 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2858 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2861 } else if (canUseATReg() && !RdRegIsRsReg) {
2862 unsigned ATReg = getATReg(IDLoc);
2864 // If the $rs is different from $rd or if $rs isn't specified and we
2865 // have $at available:
2866 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2867 // lui $at, %hi(sym)
2868 // daddiu $rd, $rd, %higher(sym)
2869 // daddiu $at, $at, %lo(sym)
2870 // dsll32 $rd, $rd, 0
2871 // daddu $rd, $rd, $at
2872 // (daddu $rd, $rd, $rs)
2874 // Which is preferred for superscalar issue.
2875 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2877 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2878 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2879 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2880 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2882 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2883 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2885 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2888 } else if (!canUseATReg() && !RdRegIsRsReg) {
2889 // Otherwise, synthesize the address in the destination register
2891 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2892 // daddiu $rd, $rd, %higher(sym)
2893 // dsll $rd, $rd, 16
2894 // daddiu $rd, $rd, %hi(sym)
2895 // dsll $rd, $rd, 16
2896 // daddiu $rd, $rd, %lo(sym)
2897 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2899 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2900 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2901 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
2902 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2903 MCOperand::createExpr(HiExpr), IDLoc, STI);
2904 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
2905 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2906 MCOperand::createExpr(LoExpr), IDLoc, STI);
2908 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2912 // We have a case where SrcReg == DstReg and we don't have $at
2913 // available. We can't expand this case, so error out appropriately.
2914 assert(SrcReg == DstReg && !canUseATReg() &&
2915 "Could have expanded dla but didn't?");
2916 reportParseError(IDLoc,
2917 "pseudo-instruction requires $at, which is not available");
2922 // And now, the 32-bit symbol address expansion:
2923 // If $rs is the same as $rd:
2924 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2925 // ori $at, $at, %lo(sym)
2926 // addu $rd, $at, $rd
2927 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2928 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2929 // ori $rd, $rd, %lo(sym)
2930 // (addu $rd, $rd, $rs)
2931 unsigned TmpReg = DstReg;
2933 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2934 // If $rs is the same as $rd, we need to use AT.
2935 // If it is not available we exit.
2936 unsigned ATReg = getATReg(IDLoc);
2942 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2943 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2947 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2950 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2955 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
2957 const MCSubtargetInfo *STI) {
2958 MipsTargetStreamer &TOut = getTargetStreamer();
2960 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2961 "unexpected number of operands");
2963 MCOperand Offset = Inst.getOperand(0);
2964 if (Offset.isExpr()) {
2966 Inst.setOpcode(Mips::BEQ_MM);
2967 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2968 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2969 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2971 assert(Offset.isImm() && "expected immediate operand kind");
2972 if (isInt<11>(Offset.getImm())) {
2973 // If offset fits into 11 bits then this instruction becomes microMIPS
2974 // 16-bit unconditional branch instruction.
2975 if (inMicroMipsMode())
2976 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2978 if (!isInt<17>(Offset.getImm()))
2979 return Error(IDLoc, "branch target out of range");
2980 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2981 return Error(IDLoc, "branch to misaligned address");
2983 Inst.setOpcode(Mips::BEQ_MM);
2984 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2985 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2986 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2989 Out.EmitInstruction(Inst, *STI);
2991 // If .set reorder is active and branch instruction has a delay slot,
2992 // emit a NOP after it.
2993 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2994 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2995 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3000 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3001 const MCSubtargetInfo *STI) {
3002 MipsTargetStreamer &TOut = getTargetStreamer();
3003 const MCOperand &DstRegOp = Inst.getOperand(0);
3004 assert(DstRegOp.isReg() && "expected register operand kind");
3006 const MCOperand &ImmOp = Inst.getOperand(1);
3007 assert(ImmOp.isImm() && "expected immediate operand kind");
3009 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3010 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3011 "expected immediate or expression operand");
3013 bool IsLikely = false;
3015 unsigned OpCode = 0;
3016 switch(Inst.getOpcode()) {
3023 case Mips::BEQLImmMacro:
3024 OpCode = Mips::BEQL;
3027 case Mips::BNELImmMacro:
3028 OpCode = Mips::BNEL;
3032 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3036 int64_t ImmValue = ImmOp.getImm();
3037 if (ImmValue == 0) {
3039 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3040 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3041 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3043 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3046 warnIfNoMacro(IDLoc);
3048 unsigned ATReg = getATReg(IDLoc);
3052 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3057 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3058 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3059 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3061 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3066 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3067 const MCSubtargetInfo *STI, bool IsLoad,
3070 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3073 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
3076 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3077 const MCSubtargetInfo *STI, bool IsImmOpnd) {
3078 MipsTargetStreamer &TOut = getTargetStreamer();
3080 unsigned DstReg = Inst.getOperand(0).getReg();
3081 unsigned BaseReg = Inst.getOperand(1).getReg();
3083 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3084 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3085 unsigned DstRegClassID =
3086 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3087 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3088 (DstRegClassID == Mips::GPR64RegClassID);
3091 // Try to use DstReg as the temporary.
3092 if (IsGPR && (BaseReg != DstReg)) {
3093 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3094 Inst.getOperand(2).getImm(), DstReg, IDLoc,
3099 // At this point we need AT to perform the expansions and we exit if it is
3101 unsigned ATReg = getATReg(IDLoc);
3105 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
3106 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
3110 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3111 MCOperand LoOperand = MCOperand::createExpr(
3112 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3113 MCOperand HiOperand = MCOperand::createExpr(
3114 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3116 // Try to use DstReg as the temporary.
3117 if (IsGPR && (BaseReg != DstReg)) {
3118 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3119 LoOperand, DstReg, IDLoc, STI);
3123 // At this point we need AT to perform the expansions and we exit if it is
3125 unsigned ATReg = getATReg(IDLoc);
3129 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3130 LoOperand, ATReg, IDLoc, STI);
3133 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3134 const MCSubtargetInfo *STI,
3136 MipsTargetStreamer &TOut = getTargetStreamer();
3138 unsigned SrcReg = Inst.getOperand(0).getReg();
3139 unsigned BaseReg = Inst.getOperand(1).getReg();
3142 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
3143 Inst.getOperand(2).getImm(),
3144 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
3148 unsigned ATReg = getATReg(IDLoc);
3152 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
3153 MCOperand LoOperand = MCOperand::createExpr(
3154 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3155 MCOperand HiOperand = MCOperand::createExpr(
3156 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3157 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
3158 LoOperand, ATReg, IDLoc, STI);
3161 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3163 const MCSubtargetInfo *STI) {
3164 unsigned OpNum = Inst.getNumOperands();
3165 unsigned Opcode = Inst.getOpcode();
3166 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3168 assert(Inst.getOperand(OpNum - 1).isImm() &&
3169 Inst.getOperand(OpNum - 2).isReg() &&
3170 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3172 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3173 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3174 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3175 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3176 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3177 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3178 // It can be implemented as SWM16 or LWM16 instruction.
3179 if (inMicroMipsMode() && hasMips32r6())
3180 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3182 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3185 Inst.setOpcode(NewOpcode);
3186 Out.EmitInstruction(Inst, *STI);
3190 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3192 const MCSubtargetInfo *STI) {
3193 MipsTargetStreamer &TOut = getTargetStreamer();
3194 bool EmittedNoMacroWarning = false;
3195 unsigned PseudoOpcode = Inst.getOpcode();
3196 unsigned SrcReg = Inst.getOperand(0).getReg();
3197 const MCOperand &TrgOp = Inst.getOperand(1);
3198 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3200 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3201 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3205 TrgReg = TrgOp.getReg();
3206 else if (TrgOp.isImm()) {
3207 warnIfNoMacro(IDLoc);
3208 EmittedNoMacroWarning = true;
3210 TrgReg = getATReg(IDLoc);
3214 switch(PseudoOpcode) {
3216 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3217 case Mips::BLTImmMacro:
3218 PseudoOpcode = Mips::BLT;
3220 case Mips::BLEImmMacro:
3221 PseudoOpcode = Mips::BLE;
3223 case Mips::BGEImmMacro:
3224 PseudoOpcode = Mips::BGE;
3226 case Mips::BGTImmMacro:
3227 PseudoOpcode = Mips::BGT;
3229 case Mips::BLTUImmMacro:
3230 PseudoOpcode = Mips::BLTU;
3232 case Mips::BLEUImmMacro:
3233 PseudoOpcode = Mips::BLEU;
3235 case Mips::BGEUImmMacro:
3236 PseudoOpcode = Mips::BGEU;
3238 case Mips::BGTUImmMacro:
3239 PseudoOpcode = Mips::BGTU;
3241 case Mips::BLTLImmMacro:
3242 PseudoOpcode = Mips::BLTL;
3244 case Mips::BLELImmMacro:
3245 PseudoOpcode = Mips::BLEL;
3247 case Mips::BGELImmMacro:
3248 PseudoOpcode = Mips::BGEL;
3250 case Mips::BGTLImmMacro:
3251 PseudoOpcode = Mips::BGTL;
3253 case Mips::BLTULImmMacro:
3254 PseudoOpcode = Mips::BLTUL;
3256 case Mips::BLEULImmMacro:
3257 PseudoOpcode = Mips::BLEUL;
3259 case Mips::BGEULImmMacro:
3260 PseudoOpcode = Mips::BGEUL;
3262 case Mips::BGTULImmMacro:
3263 PseudoOpcode = Mips::BGTUL;
3267 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3268 false, IDLoc, Out, STI))
3272 switch (PseudoOpcode) {
3277 AcceptsEquality = false;
3278 ReverseOrderSLT = false;
3279 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3280 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3281 ZeroSrcOpcode = Mips::BGTZ;
3282 ZeroTrgOpcode = Mips::BLTZ;
3288 AcceptsEquality = true;
3289 ReverseOrderSLT = true;
3290 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3291 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3292 ZeroSrcOpcode = Mips::BGEZ;
3293 ZeroTrgOpcode = Mips::BLEZ;
3299 AcceptsEquality = true;
3300 ReverseOrderSLT = false;
3301 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3302 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3303 ZeroSrcOpcode = Mips::BLEZ;
3304 ZeroTrgOpcode = Mips::BGEZ;
3310 AcceptsEquality = false;
3311 ReverseOrderSLT = true;
3312 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3313 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3314 ZeroSrcOpcode = Mips::BLTZ;
3315 ZeroTrgOpcode = Mips::BGTZ;
3318 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3321 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3322 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3323 if (IsSrcRegZero && IsTrgRegZero) {
3324 // FIXME: All of these Opcode-specific if's are needed for compatibility
3325 // with GAS' behaviour. However, they may not generate the most efficient
3326 // code in some circumstances.
3327 if (PseudoOpcode == Mips::BLT) {
3328 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3332 if (PseudoOpcode == Mips::BLE) {
3333 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3335 Warning(IDLoc, "branch is always taken");
3338 if (PseudoOpcode == Mips::BGE) {
3339 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3341 Warning(IDLoc, "branch is always taken");
3344 if (PseudoOpcode == Mips::BGT) {
3345 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3349 if (PseudoOpcode == Mips::BGTU) {
3350 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3351 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3354 if (AcceptsEquality) {
3355 // If both registers are $0 and the pseudo-branch accepts equality, it
3356 // will always be taken, so we emit an unconditional branch.
3357 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3358 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3359 Warning(IDLoc, "branch is always taken");
3362 // If both registers are $0 and the pseudo-branch does not accept
3363 // equality, it will never be taken, so we don't have to emit anything.
3366 if (IsSrcRegZero || IsTrgRegZero) {
3367 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3368 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3369 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3370 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3371 // the pseudo-branch will never be taken, so we don't emit anything.
3372 // This only applies to unsigned pseudo-branches.
3375 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3376 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3377 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3378 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3379 // the pseudo-branch will always be taken, so we emit an unconditional
3381 // This only applies to unsigned pseudo-branches.
3382 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3383 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3384 Warning(IDLoc, "branch is always taken");
3388 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3389 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3390 // the pseudo-branch will be taken only when the non-zero register is
3391 // different from 0, so we emit a BNEZ.
3393 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3394 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3395 // the pseudo-branch will be taken only when the non-zero register is
3396 // equal to 0, so we emit a BEQZ.
3398 // Because only BLEU and BGEU branch on equality, we can use the
3399 // AcceptsEquality variable to decide when to emit the BEQZ.
3400 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3401 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3402 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3405 // If we have a signed pseudo-branch and one of the registers is $0,
3406 // we can use an appropriate compare-to-zero branch. We select which one
3407 // to use in the switch statement above.
3408 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3409 IsSrcRegZero ? TrgReg : SrcReg,
3410 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3414 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3415 // expansions. If it is not available, we return.
3416 unsigned ATRegNum = getATReg(IDLoc);
3420 if (!EmittedNoMacroWarning)
3421 warnIfNoMacro(IDLoc);
3423 // SLT fits well with 2 of our 4 pseudo-branches:
3424 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3425 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3426 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3427 // This is accomplished by using a BNEZ with the result of the SLT.
3429 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3430 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3431 // Because only BGE and BLE branch on equality, we can use the
3432 // AcceptsEquality variable to decide when to emit the BEQZ.
3433 // Note that the order of the SLT arguments doesn't change between
3436 // The same applies to the unsigned variants, except that SLTu is used
3438 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3439 ReverseOrderSLT ? TrgReg : SrcReg,
3440 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3442 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3443 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3444 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3449 // Expand a integer division macro.
3451 // Notably we don't have to emit a warning when encountering $rt as the $zero
3452 // register, or 0 as an immediate. processInstruction() has already done that.
3454 // The destination register can only be $zero when expanding (S)DivIMacro or
3457 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3458 const MCSubtargetInfo *STI, const bool IsMips64,
3459 const bool Signed) {
3460 MipsTargetStreamer &TOut = getTargetStreamer();
3462 warnIfNoMacro(IDLoc);
3464 const MCOperand &RdRegOp = Inst.getOperand(0);
3465 assert(RdRegOp.isReg() && "expected register operand kind");
3466 unsigned RdReg = RdRegOp.getReg();
3468 const MCOperand &RsRegOp = Inst.getOperand(1);
3469 assert(RsRegOp.isReg() && "expected register operand kind");
3470 unsigned RsReg = RsRegOp.getReg();
3475 const MCOperand &RtOp = Inst.getOperand(2);
3476 assert((RtOp.isReg() || RtOp.isImm()) &&
3477 "expected register or immediate operand kind");
3479 RtReg = RtOp.getReg();
3481 ImmValue = RtOp.getImm();
3488 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3489 ZeroReg = Mips::ZERO_64;
3492 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3493 ZeroReg = Mips::ZERO;
3497 bool UseTraps = useTraps();
3500 unsigned ATReg = getATReg(IDLoc);
3504 if (ImmValue == 0) {
3506 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3508 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3512 if (ImmValue == 1) {
3513 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3515 } else if (Signed && ImmValue == -1) {
3516 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
3519 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
3520 false, Inst.getLoc(), Out, STI))
3522 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
3523 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3529 // If the macro expansion of (d)div(u) would always trap or break, insert
3530 // the trap/break and exit. This gives a different result to GAS. GAS has
3531 // an inconsistency/missed optimization in that not all cases are handled
3532 // equivalently. As the observed behaviour is the same, we're ok.
3533 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3535 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3538 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3542 // Temporary label for first branch traget
3543 MCContext &Context = TOut.getStreamer().getContext();
3548 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3550 // Branch to the li instruction.
3551 BrTarget = Context.createTempSymbol();
3552 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
3553 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
3556 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3559 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3563 TOut.getStreamer().EmitLabel(BrTarget);
3565 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3569 unsigned ATReg = getATReg(IDLoc);
3574 TOut.getStreamer().EmitLabel(BrTarget);
3576 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3578 // Temporary label for the second branch target.
3579 MCSymbol *BrTargetEnd = Context.createTempSymbol();
3580 MCOperand LabelOpEnd =
3581 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
3583 // Branch to the mflo instruction.
3584 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
3587 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3588 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3590 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3594 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3596 // Branch to the mflo instruction.
3597 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
3598 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3599 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3602 TOut.getStreamer().EmitLabel(BrTargetEnd);
3603 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3607 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3608 SMLoc IDLoc, MCStreamer &Out,
3609 const MCSubtargetInfo *STI) {
3610 MipsTargetStreamer &TOut = getTargetStreamer();
3612 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3613 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
3614 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
3616 unsigned FirstReg = Inst.getOperand(0).getReg();
3617 unsigned SecondReg = Inst.getOperand(1).getReg();
3618 unsigned ThirdReg = Inst.getOperand(2).getReg();
3620 if (hasMips1() && !hasMips2()) {
3621 unsigned ATReg = getATReg(IDLoc);
3624 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3625 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3626 TOut.emitNop(IDLoc, STI);
3627 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3628 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3629 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3630 TOut.emitNop(IDLoc, STI);
3631 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3633 FirstReg, SecondReg, IDLoc, STI);
3634 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3635 TOut.emitNop(IDLoc, STI);
3639 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3641 FirstReg, SecondReg, IDLoc, STI);
3646 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3647 MCStreamer &Out, const MCSubtargetInfo *STI) {
3648 if (hasMips32r6() || hasMips64r6()) {
3649 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3652 const MCOperand &DstRegOp = Inst.getOperand(0);
3653 assert(DstRegOp.isReg() && "expected register operand kind");
3654 const MCOperand &SrcRegOp = Inst.getOperand(1);
3655 assert(SrcRegOp.isReg() && "expected register operand kind");
3656 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3657 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3659 MipsTargetStreamer &TOut = getTargetStreamer();
3660 unsigned DstReg = DstRegOp.getReg();
3661 unsigned SrcReg = SrcRegOp.getReg();
3662 int64_t OffsetValue = OffsetImmOp.getImm();
3664 // NOTE: We always need AT for ULHU, as it is always used as the source
3665 // register for one of the LBu's.
3666 warnIfNoMacro(IDLoc);
3667 unsigned ATReg = getATReg(IDLoc);
3671 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3672 if (IsLargeOffset) {
3673 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3678 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
3679 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3681 std::swap(FirstOffset, SecondOffset);
3683 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
3684 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
3686 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
3687 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
3689 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3690 FirstOffset, IDLoc, STI);
3691 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
3692 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
3693 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3698 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3699 const MCSubtargetInfo *STI) {
3700 if (hasMips32r6() || hasMips64r6()) {
3701 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3704 const MCOperand &DstRegOp = Inst.getOperand(0);
3705 assert(DstRegOp.isReg() && "expected register operand kind");
3706 const MCOperand &SrcRegOp = Inst.getOperand(1);
3707 assert(SrcRegOp.isReg() && "expected register operand kind");
3708 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3709 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3711 MipsTargetStreamer &TOut = getTargetStreamer();
3712 unsigned DstReg = DstRegOp.getReg();
3713 unsigned SrcReg = SrcRegOp.getReg();
3714 int64_t OffsetValue = OffsetImmOp.getImm();
3716 warnIfNoMacro(IDLoc);
3717 unsigned ATReg = getATReg(IDLoc);
3721 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3722 if (IsLargeOffset) {
3723 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3728 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3729 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
3731 std::swap(FirstOffset, SecondOffset);
3733 if (IsLargeOffset) {
3734 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
3735 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
3736 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
3737 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
3738 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
3739 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3741 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
3742 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
3743 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
3749 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3750 const MCSubtargetInfo *STI) {
3751 if (hasMips32r6() || hasMips64r6()) {
3752 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3755 const MCOperand &DstRegOp = Inst.getOperand(0);
3756 assert(DstRegOp.isReg() && "expected register operand kind");
3757 const MCOperand &SrcRegOp = Inst.getOperand(1);
3758 assert(SrcRegOp.isReg() && "expected register operand kind");
3759 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3760 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3762 MipsTargetStreamer &TOut = getTargetStreamer();
3763 unsigned DstReg = DstRegOp.getReg();
3764 unsigned SrcReg = SrcRegOp.getReg();
3765 int64_t OffsetValue = OffsetImmOp.getImm();
3767 // Compute left/right load/store offsets.
3768 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
3769 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
3770 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
3772 std::swap(LxlOffset, LxrOffset);
3774 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
3775 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
3776 unsigned TmpReg = SrcReg;
3777 if (IsLargeOffset || DoMove) {
3778 warnIfNoMacro(IDLoc);
3779 TmpReg = getATReg(IDLoc);
3784 if (IsLargeOffset) {
3785 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
3791 std::swap(DstReg, TmpReg);
3793 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
3794 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
3795 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
3796 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
3799 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
3804 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3806 const MCSubtargetInfo *STI) {
3807 MipsTargetStreamer &TOut = getTargetStreamer();
3809 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3810 assert(Inst.getOperand(0).isReg() &&
3811 Inst.getOperand(1).isReg() &&
3812 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3814 unsigned ATReg = Mips::NoRegister;
3815 unsigned FinalDstReg = Mips::NoRegister;
3816 unsigned DstReg = Inst.getOperand(0).getReg();
3817 unsigned SrcReg = Inst.getOperand(1).getReg();
3818 int64_t ImmValue = Inst.getOperand(2).getImm();
3820 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
3822 unsigned FinalOpcode = Inst.getOpcode();
3824 if (DstReg == SrcReg) {
3825 ATReg = getATReg(Inst.getLoc());
3828 FinalDstReg = DstReg;
3832 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
3833 switch (FinalOpcode) {
3835 llvm_unreachable("unimplemented expansion");
3837 FinalOpcode = Mips::ADD;
3840 FinalOpcode = Mips::ADDu;
3843 FinalOpcode = Mips::AND;
3846 FinalOpcode = Mips::NOR;
3849 FinalOpcode = Mips::OR;
3852 FinalOpcode = Mips::SLT;
3855 FinalOpcode = Mips::SLTu;
3858 FinalOpcode = Mips::XOR;
3861 FinalOpcode = Mips::ADD_MM;
3863 case Mips::ADDiu_MM:
3864 FinalOpcode = Mips::ADDu_MM;
3867 FinalOpcode = Mips::AND_MM;
3870 FinalOpcode = Mips::OR_MM;
3873 FinalOpcode = Mips::SLT_MM;
3875 case Mips::SLTiu_MM:
3876 FinalOpcode = Mips::SLTu_MM;
3879 FinalOpcode = Mips::XOR_MM;
3882 FinalOpcode = Mips::AND64;
3884 case Mips::NORImm64:
3885 FinalOpcode = Mips::NOR64;
3888 FinalOpcode = Mips::OR64;
3890 case Mips::SLTImm64:
3891 FinalOpcode = Mips::SLT64;
3893 case Mips::SLTUImm64:
3894 FinalOpcode = Mips::SLTu64;
3897 FinalOpcode = Mips::XOR64;
3901 if (FinalDstReg == Mips::NoRegister)
3902 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
3904 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
3910 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3911 const MCSubtargetInfo *STI) {
3912 MipsTargetStreamer &TOut = getTargetStreamer();
3913 unsigned ATReg = Mips::NoRegister;
3914 unsigned DReg = Inst.getOperand(0).getReg();
3915 unsigned SReg = Inst.getOperand(1).getReg();
3916 unsigned TReg = Inst.getOperand(2).getReg();
3917 unsigned TmpReg = DReg;
3919 unsigned FirstShift = Mips::NOP;
3920 unsigned SecondShift = Mips::NOP;
3922 if (hasMips32r2()) {
3924 TmpReg = getATReg(Inst.getLoc());
3929 if (Inst.getOpcode() == Mips::ROL) {
3930 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3931 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3935 if (Inst.getOpcode() == Mips::ROR) {
3936 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3944 switch (Inst.getOpcode()) {
3946 llvm_unreachable("unexpected instruction opcode");
3948 FirstShift = Mips::SRLV;
3949 SecondShift = Mips::SLLV;
3952 FirstShift = Mips::SLLV;
3953 SecondShift = Mips::SRLV;
3957 ATReg = getATReg(Inst.getLoc());
3961 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3962 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3963 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3964 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3972 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3974 const MCSubtargetInfo *STI) {
3975 MipsTargetStreamer &TOut = getTargetStreamer();
3976 unsigned ATReg = Mips::NoRegister;
3977 unsigned DReg = Inst.getOperand(0).getReg();
3978 unsigned SReg = Inst.getOperand(1).getReg();
3979 int64_t ImmValue = Inst.getOperand(2).getImm();
3981 unsigned FirstShift = Mips::NOP;
3982 unsigned SecondShift = Mips::NOP;
3984 if (hasMips32r2()) {
3985 if (Inst.getOpcode() == Mips::ROLImm) {
3986 uint64_t MaxShift = 32;
3987 uint64_t ShiftValue = ImmValue;
3989 ShiftValue = MaxShift - ImmValue;
3990 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3994 if (Inst.getOpcode() == Mips::RORImm) {
3995 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4003 if (ImmValue == 0) {
4004 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4008 switch (Inst.getOpcode()) {
4010 llvm_unreachable("unexpected instruction opcode");
4012 FirstShift = Mips::SLL;
4013 SecondShift = Mips::SRL;
4016 FirstShift = Mips::SRL;
4017 SecondShift = Mips::SLL;
4021 ATReg = getATReg(Inst.getLoc());
4025 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4026 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4027 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4035 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4036 const MCSubtargetInfo *STI) {
4037 MipsTargetStreamer &TOut = getTargetStreamer();
4038 unsigned ATReg = Mips::NoRegister;
4039 unsigned DReg = Inst.getOperand(0).getReg();
4040 unsigned SReg = Inst.getOperand(1).getReg();
4041 unsigned TReg = Inst.getOperand(2).getReg();
4042 unsigned TmpReg = DReg;
4044 unsigned FirstShift = Mips::NOP;
4045 unsigned SecondShift = Mips::NOP;
4047 if (hasMips64r2()) {
4048 if (TmpReg == SReg) {
4049 TmpReg = getATReg(Inst.getLoc());
4054 if (Inst.getOpcode() == Mips::DROL) {
4055 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4056 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4060 if (Inst.getOpcode() == Mips::DROR) {
4061 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4069 switch (Inst.getOpcode()) {
4071 llvm_unreachable("unexpected instruction opcode");
4073 FirstShift = Mips::DSRLV;
4074 SecondShift = Mips::DSLLV;
4077 FirstShift = Mips::DSLLV;
4078 SecondShift = Mips::DSRLV;
4082 ATReg = getATReg(Inst.getLoc());
4086 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4087 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4088 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4089 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4097 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4099 const MCSubtargetInfo *STI) {
4100 MipsTargetStreamer &TOut = getTargetStreamer();
4101 unsigned ATReg = Mips::NoRegister;
4102 unsigned DReg = Inst.getOperand(0).getReg();
4103 unsigned SReg = Inst.getOperand(1).getReg();
4104 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4106 unsigned FirstShift = Mips::NOP;
4107 unsigned SecondShift = Mips::NOP;
4111 if (hasMips64r2()) {
4112 unsigned FinalOpcode = Mips::NOP;
4114 FinalOpcode = Mips::DROTR;
4115 else if (ImmValue % 32 == 0)
4116 FinalOpcode = Mips::DROTR32;
4117 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4118 if (Inst.getOpcode() == Mips::DROLImm)
4119 FinalOpcode = Mips::DROTR32;
4121 FinalOpcode = Mips::DROTR;
4122 } else if (ImmValue >= 33) {
4123 if (Inst.getOpcode() == Mips::DROLImm)
4124 FinalOpcode = Mips::DROTR;
4126 FinalOpcode = Mips::DROTR32;
4129 uint64_t ShiftValue = ImmValue % 32;
4130 if (Inst.getOpcode() == Mips::DROLImm)
4131 ShiftValue = (32 - ImmValue % 32) % 32;
4133 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4139 if (ImmValue == 0) {
4140 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4144 switch (Inst.getOpcode()) {
4146 llvm_unreachable("unexpected instruction opcode");
4148 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4149 FirstShift = Mips::DSLL;
4150 SecondShift = Mips::DSRL32;
4152 if (ImmValue == 32) {
4153 FirstShift = Mips::DSLL32;
4154 SecondShift = Mips::DSRL32;
4156 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4157 FirstShift = Mips::DSLL32;
4158 SecondShift = Mips::DSRL;
4162 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4163 FirstShift = Mips::DSRL;
4164 SecondShift = Mips::DSLL32;
4166 if (ImmValue == 32) {
4167 FirstShift = Mips::DSRL32;
4168 SecondShift = Mips::DSLL32;
4170 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4171 FirstShift = Mips::DSRL32;
4172 SecondShift = Mips::DSLL;
4177 ATReg = getATReg(Inst.getLoc());
4181 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4182 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4183 Inst.getLoc(), STI);
4184 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4192 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4193 const MCSubtargetInfo *STI) {
4194 MipsTargetStreamer &TOut = getTargetStreamer();
4195 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4196 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4198 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4199 if (FirstRegOp != SecondRegOp)
4200 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4202 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4203 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4208 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4209 const MCSubtargetInfo *STI) {
4210 MipsTargetStreamer &TOut = getTargetStreamer();
4211 unsigned ATReg = Mips::NoRegister;
4212 unsigned DstReg = Inst.getOperand(0).getReg();
4213 unsigned SrcReg = Inst.getOperand(1).getReg();
4214 int32_t ImmValue = Inst.getOperand(2).getImm();
4216 ATReg = getATReg(IDLoc);
4220 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, STI);
4222 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4223 SrcReg, ATReg, IDLoc, STI);
4225 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4230 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4231 const MCSubtargetInfo *STI) {
4232 MipsTargetStreamer &TOut = getTargetStreamer();
4233 unsigned ATReg = Mips::NoRegister;
4234 unsigned DstReg = Inst.getOperand(0).getReg();
4235 unsigned SrcReg = Inst.getOperand(1).getReg();
4236 unsigned TmpReg = Inst.getOperand(2).getReg();
4238 ATReg = getATReg(Inst.getLoc());
4242 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4243 SrcReg, TmpReg, IDLoc, STI);
4245 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4247 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4248 DstReg, DstReg, 0x1F, IDLoc, STI);
4250 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4253 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4255 MCContext & Context = TOut.getStreamer().getContext();
4256 MCSymbol * BrTarget = Context.createTempSymbol();
4258 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4260 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4261 if (AssemblerOptions.back()->isReorder())
4262 TOut.emitNop(IDLoc, STI);
4263 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4265 TOut.getStreamer().EmitLabel(BrTarget);
4267 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4272 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4273 const MCSubtargetInfo *STI) {
4274 MipsTargetStreamer &TOut = getTargetStreamer();
4275 unsigned ATReg = Mips::NoRegister;
4276 unsigned DstReg = Inst.getOperand(0).getReg();
4277 unsigned SrcReg = Inst.getOperand(1).getReg();
4278 unsigned TmpReg = Inst.getOperand(2).getReg();
4280 ATReg = getATReg(IDLoc);
4284 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4285 SrcReg, TmpReg, IDLoc, STI);
4287 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4288 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4290 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4292 MCContext & Context = TOut.getStreamer().getContext();
4293 MCSymbol * BrTarget = Context.createTempSymbol();
4295 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4297 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4298 if (AssemblerOptions.back()->isReorder())
4299 TOut.emitNop(IDLoc, STI);
4300 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4302 TOut.getStreamer().EmitLabel(BrTarget);
4308 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4309 const MCSubtargetInfo *STI) {
4310 MipsTargetStreamer &TOut = getTargetStreamer();
4311 unsigned DstReg = Inst.getOperand(0).getReg();
4312 unsigned SrcReg = Inst.getOperand(1).getReg();
4313 unsigned TmpReg = Inst.getOperand(2).getReg();
4315 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4316 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4321 static unsigned nextReg(unsigned Reg) {
4323 case Mips::ZERO: return Mips::AT;
4324 case Mips::AT: return Mips::V0;
4325 case Mips::V0: return Mips::V1;
4326 case Mips::V1: return Mips::A0;
4327 case Mips::A0: return Mips::A1;
4328 case Mips::A1: return Mips::A2;
4329 case Mips::A2: return Mips::A3;
4330 case Mips::A3: return Mips::T0;
4331 case Mips::T0: return Mips::T1;
4332 case Mips::T1: return Mips::T2;
4333 case Mips::T2: return Mips::T3;
4334 case Mips::T3: return Mips::T4;
4335 case Mips::T4: return Mips::T5;
4336 case Mips::T5: return Mips::T6;
4337 case Mips::T6: return Mips::T7;
4338 case Mips::T7: return Mips::S0;
4339 case Mips::S0: return Mips::S1;
4340 case Mips::S1: return Mips::S2;
4341 case Mips::S2: return Mips::S3;
4342 case Mips::S3: return Mips::S4;
4343 case Mips::S4: return Mips::S5;
4344 case Mips::S5: return Mips::S6;
4345 case Mips::S6: return Mips::S7;
4346 case Mips::S7: return Mips::T8;
4347 case Mips::T8: return Mips::T9;
4348 case Mips::T9: return Mips::K0;
4349 case Mips::K0: return Mips::K1;
4350 case Mips::K1: return Mips::GP;
4351 case Mips::GP: return Mips::SP;
4352 case Mips::SP: return Mips::FP;
4353 case Mips::FP: return Mips::RA;
4354 case Mips::RA: return Mips::ZERO;
4360 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4361 // lw $<reg+1>>, offset+4($reg2)'
4362 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4363 // sw $<reg+1>>, offset+4($reg2)'
4365 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4367 const MCSubtargetInfo *STI,
4372 warnIfNoMacro(IDLoc);
4374 MipsTargetStreamer &TOut = getTargetStreamer();
4375 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4376 unsigned FirstReg = Inst.getOperand(0).getReg();
4377 unsigned SecondReg = nextReg(FirstReg);
4378 unsigned BaseReg = Inst.getOperand(1).getReg();
4382 warnIfRegIndexIsAT(FirstReg, IDLoc);
4384 assert(Inst.getOperand(2).isImm() &&
4385 "Offset for load macro is not immediate!");
4387 MCOperand &FirstOffset = Inst.getOperand(2);
4388 signed NextOffset = FirstOffset.getImm() + 4;
4389 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4391 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4394 // For loads, clobber the base register with the second load instead of the
4395 // first if the BaseReg == FirstReg.
4396 if (FirstReg != BaseReg || !IsLoad) {
4397 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4398 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4400 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4401 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4407 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4408 const MCSubtargetInfo *STI) {
4410 warnIfNoMacro(IDLoc);
4411 MipsTargetStreamer &TOut = getTargetStreamer();
4413 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4414 Inst.getOperand(2).getReg() != Mips::ZERO) {
4415 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4416 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4418 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4419 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4424 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4425 Reg = Inst.getOperand(2).getReg();
4427 Reg = Inst.getOperand(1).getReg();
4429 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4433 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4434 const MCSubtargetInfo *STI) {
4435 warnIfNoMacro(IDLoc);
4436 MipsTargetStreamer &TOut = getTargetStreamer();
4439 int64_t Imm = Inst.getOperand(2).getImm();
4440 unsigned Reg = Inst.getOperand(1).getReg();
4443 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4444 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4448 if (Reg == Mips::ZERO) {
4449 Warning(IDLoc, "comparison is always false");
4450 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4451 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4455 if (Imm > -0x8000 && Imm < 0) {
4457 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4462 if (!isUInt<16>(Imm)) {
4463 unsigned ATReg = getATReg(IDLoc);
4467 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4471 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4472 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4473 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4474 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4478 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4480 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4481 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4486 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
4487 const OperandVector &Operands) {
4488 switch (Inst.getOpcode()) {
4490 return Match_Success;
4493 case Mips::DATI_MM64R6:
4494 case Mips::DAHI_MM64R6:
4495 if (static_cast<MipsOperand &>(*Operands[1])
4496 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4497 return Match_Success;
4498 return Match_RequiresSameSrcAndDst;
4502 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4503 switch (Inst.getOpcode()) {
4504 // As described by the MIPSR6 spec, daui must not use the zero operand for
4505 // its source operand.
4507 case Mips::DAUI_MM64R6:
4508 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4509 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4510 return Match_RequiresNoZeroRegister;
4511 return Match_Success;
4512 // As described by the Mips32r2 spec, the registers Rd and Rs for
4513 // jalr.hb must be different.
4514 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
4515 // and registers Rd and Base for microMIPS lwp instruction
4517 case Mips::JALRC_HB_MMR6:
4518 case Mips::JALRC_MMR6:
4519 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4520 return Match_RequiresDifferentSrcAndDst;
4521 return Match_Success;
4523 case Mips::LWP_MMR6:
4524 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
4525 return Match_RequiresDifferentSrcAndDst;
4526 return Match_Success;
4528 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
4529 return Match_NonZeroOperandForSync;
4530 return Match_Success;
4531 // As described the MIPSR6 spec, the compact branches that compare registers
4533 // a) Not use the zero register.
4534 // b) Not use the same register twice.
4535 // c) rs < rt for bnec, beqc.
4536 // NB: For this case, the encoding will swap the operands as their
4537 // ordering doesn't matter. GAS performs this transformation too.
4538 // Hence, that constraint does not have to be enforced.
4540 // The compact branches that branch iff the signed addition of two registers
4541 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
4542 // operand swapping. They do not have restriction of using the zero register.
4543 case Mips::BLEZC: case Mips::BLEZC_MMR6:
4544 case Mips::BGEZC: case Mips::BGEZC_MMR6:
4545 case Mips::BGTZC: case Mips::BGTZC_MMR6:
4546 case Mips::BLTZC: case Mips::BLTZC_MMR6:
4547 case Mips::BEQZC: case Mips::BEQZC_MMR6:
4548 case Mips::BNEZC: case Mips::BNEZC_MMR6:
4555 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4556 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4557 return Match_RequiresNoZeroRegister;
4558 return Match_Success;
4559 case Mips::BGEC: case Mips::BGEC_MMR6:
4560 case Mips::BLTC: case Mips::BLTC_MMR6:
4561 case Mips::BGEUC: case Mips::BGEUC_MMR6:
4562 case Mips::BLTUC: case Mips::BLTUC_MMR6:
4563 case Mips::BEQC: case Mips::BEQC_MMR6:
4564 case Mips::BNEC: case Mips::BNEC_MMR6:
4571 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4572 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4573 return Match_RequiresNoZeroRegister;
4574 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4575 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4576 return Match_RequiresNoZeroRegister;
4577 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4578 return Match_RequiresDifferentOperands;
4579 return Match_Success;
4582 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
4583 if ((TSFlags & MipsII::HasFCCRegOperand) &&
4584 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
4585 return Match_NoFCCRegisterForCurrentISA;
4587 return Match_Success;
4591 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
4592 uint64_t ErrorInfo) {
4593 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
4594 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4595 if (ErrorLoc == SMLoc())
4602 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4603 OperandVector &Operands,
4605 uint64_t &ErrorInfo,
4606 bool MatchingInlineAsm) {
4608 unsigned MatchResult =
4609 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
4611 switch (MatchResult) {
4613 if (processInstruction(Inst, IDLoc, Out, STI))
4616 case Match_MissingFeature:
4617 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4619 case Match_InvalidOperand: {
4620 SMLoc ErrorLoc = IDLoc;
4621 if (ErrorInfo != ~0ULL) {
4622 if (ErrorInfo >= Operands.size())
4623 return Error(IDLoc, "too few operands for instruction");
4625 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4626 if (ErrorLoc == SMLoc())
4630 return Error(ErrorLoc, "invalid operand for instruction");
4632 case Match_NonZeroOperandForSync:
4633 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
4634 case Match_MnemonicFail:
4635 return Error(IDLoc, "invalid instruction");
4636 case Match_RequiresDifferentSrcAndDst:
4637 return Error(IDLoc, "source and destination must be different");
4638 case Match_RequiresDifferentOperands:
4639 return Error(IDLoc, "registers must be different");
4640 case Match_RequiresNoZeroRegister:
4641 return Error(IDLoc, "invalid operand ($zero) for instruction");
4642 case Match_RequiresSameSrcAndDst:
4643 return Error(IDLoc, "source and destination must match");
4644 case Match_NoFCCRegisterForCurrentISA:
4645 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4646 "non-zero fcc register doesn't exist in current ISA level");
4648 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
4650 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4651 "expected 1-bit unsigned immediate");
4653 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4654 "expected 2-bit unsigned immediate");
4656 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4657 "expected immediate in range 1 .. 4");
4659 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4660 "expected 3-bit unsigned immediate");
4662 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4663 "expected 4-bit unsigned immediate");
4665 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4666 "expected 4-bit signed immediate");
4668 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4669 "expected 5-bit unsigned immediate");
4671 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4672 "expected 5-bit signed immediate");
4674 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4675 "expected immediate in range 1 .. 32");
4676 case Match_UImm5_32:
4677 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4678 "expected immediate in range 32 .. 63");
4679 case Match_UImm5_33:
4680 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4681 "expected immediate in range 33 .. 64");
4682 case Match_UImm5_0_Report_UImm6:
4683 // This is used on UImm5 operands that have a corresponding UImm5_32
4684 // operand to avoid confusing the user.
4685 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4686 "expected 6-bit unsigned immediate");
4687 case Match_UImm5_Lsl2:
4688 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4689 "expected both 7-bit unsigned immediate and multiple of 4");
4690 case Match_UImmRange2_64:
4691 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4692 "expected immediate in range 2 .. 64");
4694 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4695 "expected 6-bit unsigned immediate");
4696 case Match_UImm6_Lsl2:
4697 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4698 "expected both 8-bit unsigned immediate and multiple of 4");
4700 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4701 "expected 6-bit signed immediate");
4703 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4704 "expected 7-bit unsigned immediate");
4705 case Match_UImm7_N1:
4706 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4707 "expected immediate in range -1 .. 126");
4708 case Match_SImm7_Lsl2:
4709 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4710 "expected both 9-bit signed immediate and multiple of 4");
4712 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4713 "expected 8-bit unsigned immediate");
4714 case Match_UImm10_0:
4715 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4716 "expected 10-bit unsigned immediate");
4717 case Match_SImm10_0:
4718 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4719 "expected 10-bit signed immediate");
4720 case Match_SImm11_0:
4721 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4722 "expected 11-bit signed immediate");
4724 case Match_UImm16_Relaxed:
4725 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4726 "expected 16-bit unsigned immediate");
4728 case Match_SImm16_Relaxed:
4729 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4730 "expected 16-bit signed immediate");
4731 case Match_SImm19_Lsl2:
4732 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4733 "expected both 19-bit signed immediate and multiple of 4");
4734 case Match_UImm20_0:
4735 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4736 "expected 20-bit unsigned immediate");
4737 case Match_UImm26_0:
4738 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4739 "expected 26-bit unsigned immediate");
4741 case Match_SImm32_Relaxed:
4742 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4743 "expected 32-bit signed immediate");
4744 case Match_UImm32_Coerced:
4745 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4746 "expected 32-bit immediate");
4747 case Match_MemSImm9:
4748 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4749 "expected memory with 9-bit signed offset");
4750 case Match_MemSImm10:
4751 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4752 "expected memory with 10-bit signed offset");
4753 case Match_MemSImm10Lsl1:
4754 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4755 "expected memory with 11-bit signed offset and multiple of 2");
4756 case Match_MemSImm10Lsl2:
4757 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4758 "expected memory with 12-bit signed offset and multiple of 4");
4759 case Match_MemSImm10Lsl3:
4760 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4761 "expected memory with 13-bit signed offset and multiple of 8");
4762 case Match_MemSImm11:
4763 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4764 "expected memory with 11-bit signed offset");
4765 case Match_MemSImm12:
4766 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4767 "expected memory with 12-bit signed offset");
4768 case Match_MemSImm16:
4769 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4770 "expected memory with 16-bit signed offset");
4773 llvm_unreachable("Implement any new match types added!");
4776 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
4777 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
4778 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
4779 ") without \".set noat\"");
4782 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
4783 if (!AssemblerOptions.back()->isMacro())
4784 Warning(Loc, "macro instruction expanded into multiple instructions");
4788 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
4789 SMRange Range, bool ShowColors) {
4790 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
4791 Range, SMFixIt(Range, FixMsg),
4795 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
4798 CC = StringSwitch<unsigned>(Name)
4834 if (!(isABI_N32() || isABI_N64()))
4837 if (12 <= CC && CC <= 15) {
4838 // Name is one of t4-t7
4839 AsmToken RegTok = getLexer().peekTok();
4840 SMRange RegRange = RegTok.getLocRange();
4842 StringRef FixedName = StringSwitch<StringRef>(Name)
4848 assert(FixedName != "" && "Register name is not one of t4-t7.");
4850 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
4851 "Did you mean $" + FixedName + "?", RegRange);
4854 // Although SGI documentation just cuts out t0-t3 for n32/n64,
4855 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
4856 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
4857 if (8 <= CC && CC <= 11)
4861 CC = StringSwitch<unsigned>(Name)
4873 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
4876 CC = StringSwitch<unsigned>(Name)
4877 .Case("hwr_cpunum", 0)
4878 .Case("hwr_synci_step", 1)
4880 .Case("hwr_ccres", 3)
4881 .Case("hwr_ulr", 29)
4887 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
4888 if (Name[0] == 'f') {
4889 StringRef NumString = Name.substr(1);
4891 if (NumString.getAsInteger(10, IntVal))
4892 return -1; // This is not an integer.
4893 if (IntVal > 31) // Maximum index for fpu register.
4900 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
4901 if (Name.startswith("fcc")) {
4902 StringRef NumString = Name.substr(3);
4904 if (NumString.getAsInteger(10, IntVal))
4905 return -1; // This is not an integer.
4906 if (IntVal > 7) // There are only 8 fcc registers.
4913 int MipsAsmParser::matchACRegisterName(StringRef Name) {
4914 if (Name.startswith("ac")) {
4915 StringRef NumString = Name.substr(2);
4917 if (NumString.getAsInteger(10, IntVal))
4918 return -1; // This is not an integer.
4919 if (IntVal > 3) // There are only 3 acc registers.
4926 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
4929 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
4938 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4941 CC = StringSwitch<unsigned>(Name)
4944 .Case("msaaccess", 2)
4946 .Case("msamodify", 4)
4947 .Case("msarequest", 5)
4949 .Case("msaunmap", 7)
4955 bool MipsAsmParser::canUseATReg() {
4956 return AssemblerOptions.back()->getATRegIndex() != 0;
4959 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
4960 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4962 reportParseError(Loc,
4963 "pseudo-instruction requires $at, which is not available");
4966 unsigned AT = getReg(
4967 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4971 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
4972 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4975 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
4976 MCAsmParser &Parser = getParser();
4977 DEBUG(dbgs() << "parseOperand\n");
4979 // Check if the current operand has a custom associated parser, if so, try to
4980 // custom parse the operand, or fallback to the general approach.
4981 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4982 if (ResTy == MatchOperand_Success)
4984 // If there wasn't a custom match, try the generic matcher below. Otherwise,
4985 // there was a match, but an error occurred, in which case, just return that
4986 // the operand parsing failed.
4987 if (ResTy == MatchOperand_ParseFail)
4990 DEBUG(dbgs() << ".. Generic Parser\n");
4992 switch (getLexer().getKind()) {
4993 case AsmToken::Dollar: {
4994 // Parse the register.
4995 SMLoc S = Parser.getTok().getLoc();
4997 // Almost all registers have been parsed by custom parsers. There is only
4998 // one exception to this. $zero (and it's alias $0) will reach this point
4999 // for div, divu, and similar instructions because it is not an operand
5000 // to the instruction definition but an explicit register. Special case
5001 // this situation for now.
5002 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5005 // Maybe it is a symbol reference.
5006 StringRef Identifier;
5007 if (Parser.parseIdentifier(Identifier))
5010 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5011 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5012 // Otherwise create a symbol reference.
5014 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5016 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5020 DEBUG(dbgs() << ".. generic integer expression\n");
5023 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5024 if (getParser().parseExpression(Expr))
5027 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5029 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5032 } // switch(getLexer().getKind())
5036 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5037 switch (Expr->getKind()) {
5038 case MCExpr::Constant:
5040 case MCExpr::SymbolRef:
5041 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5042 case MCExpr::Binary:
5043 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
5044 if (!isEvaluated(BE->getLHS()))
5046 return isEvaluated(BE->getRHS());
5049 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5050 case MCExpr::Target:
5056 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5058 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5059 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5060 if (ResTy == MatchOperand_Success) {
5061 assert(Operands.size() == 1);
5062 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5063 StartLoc = Operand.getStartLoc();
5064 EndLoc = Operand.getEndLoc();
5066 // AFAIK, we only support numeric registers and named GPR's in CFI
5068 // Don't worry about eating tokens before failing. Using an unrecognised
5069 // register is a parse error.
5070 if (Operand.isGPRAsmReg()) {
5071 // Resolve to GPR32 or GPR64 appropriately.
5072 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5075 return (RegNo == (unsigned)-1);
5078 assert(Operands.size() == 0);
5079 return (RegNo == (unsigned)-1);
5082 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5086 return getParser().parseParenExprOfDepth(0, Res, S);
5087 return getParser().parseExpression(Res);
5090 OperandMatchResultTy
5091 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5092 MCAsmParser &Parser = getParser();
5093 DEBUG(dbgs() << "parseMemOperand\n");
5094 const MCExpr *IdVal = nullptr;
5096 bool isParenExpr = false;
5097 OperandMatchResultTy Res = MatchOperand_NoMatch;
5098 // First operand is the offset.
5099 S = Parser.getTok().getLoc();
5101 if (getLexer().getKind() == AsmToken::LParen) {
5106 if (getLexer().getKind() != AsmToken::Dollar) {
5107 if (parseMemOffset(IdVal, isParenExpr))
5108 return MatchOperand_ParseFail;
5110 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5111 if (Tok.isNot(AsmToken::LParen)) {
5112 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5113 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5115 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5116 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5117 return MatchOperand_Success;
5119 if (Tok.is(AsmToken::EndOfStatement)) {
5121 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5123 // Zero register assumed, add a memory operand with ZERO as its base.
5124 // "Base" will be managed by k_Memory.
5125 auto Base = MipsOperand::createGPRReg(
5126 0, "0", getContext().getRegisterInfo(), S, E, *this);
5128 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5129 return MatchOperand_Success;
5131 MCBinaryExpr::Opcode Opcode;
5132 // GAS and LLVM treat comparison operators different. GAS will generate -1
5133 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5134 // highly unlikely to be found in a memory offset expression, we don't
5136 switch (Tok.getKind()) {
5137 case AsmToken::Plus:
5138 Opcode = MCBinaryExpr::Add;
5141 case AsmToken::Minus:
5142 Opcode = MCBinaryExpr::Sub;
5145 case AsmToken::Star:
5146 Opcode = MCBinaryExpr::Mul;
5149 case AsmToken::Pipe:
5150 Opcode = MCBinaryExpr::Or;
5154 Opcode = MCBinaryExpr::And;
5157 case AsmToken::LessLess:
5158 Opcode = MCBinaryExpr::Shl;
5161 case AsmToken::GreaterGreater:
5162 Opcode = MCBinaryExpr::LShr;
5165 case AsmToken::Caret:
5166 Opcode = MCBinaryExpr::Xor;
5169 case AsmToken::Slash:
5170 Opcode = MCBinaryExpr::Div;
5173 case AsmToken::Percent:
5174 Opcode = MCBinaryExpr::Mod;
5178 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5179 return MatchOperand_ParseFail;
5181 const MCExpr * NextExpr;
5182 if (getParser().parseExpression(NextExpr))
5183 return MatchOperand_ParseFail;
5184 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5187 Parser.Lex(); // Eat the '(' token.
5190 Res = parseAnyRegister(Operands);
5191 if (Res != MatchOperand_Success)
5194 if (Parser.getTok().isNot(AsmToken::RParen)) {
5195 Error(Parser.getTok().getLoc(), "')' expected");
5196 return MatchOperand_ParseFail;
5199 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5201 Parser.Lex(); // Eat the ')' token.
5204 IdVal = MCConstantExpr::create(0, getContext());
5206 // Replace the register operand with the memory operand.
5207 std::unique_ptr<MipsOperand> op(
5208 static_cast<MipsOperand *>(Operands.back().release()));
5209 // Remove the register from the operands.
5210 // "op" will be managed by k_Memory.
5211 Operands.pop_back();
5212 // Add the memory operand.
5213 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5215 if (IdVal->evaluateAsAbsolute(Imm))
5216 IdVal = MCConstantExpr::create(Imm, getContext());
5217 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5218 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5222 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5223 return MatchOperand_Success;
5226 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5227 MCAsmParser &Parser = getParser();
5228 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5230 SMLoc S = Parser.getTok().getLoc();
5232 if (Sym->isVariable())
5233 Expr = Sym->getVariableValue();
5236 if (Expr->getKind() == MCExpr::SymbolRef) {
5237 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5238 StringRef DefSymbol = Ref->getSymbol().getName();
5239 if (DefSymbol.startswith("$")) {
5240 OperandMatchResultTy ResTy =
5241 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5242 if (ResTy == MatchOperand_Success) {
5245 } else if (ResTy == MatchOperand_ParseFail)
5246 llvm_unreachable("Should never ParseFail");
5254 OperandMatchResultTy
5255 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
5256 StringRef Identifier,
5258 int Index = matchCPURegisterName(Identifier);
5260 Operands.push_back(MipsOperand::createGPRReg(
5261 Index, Identifier, getContext().getRegisterInfo(), S,
5262 getLexer().getLoc(), *this));
5263 return MatchOperand_Success;
5266 Index = matchHWRegsRegisterName(Identifier);
5268 Operands.push_back(MipsOperand::createHWRegsReg(
5269 Index, Identifier, getContext().getRegisterInfo(), S,
5270 getLexer().getLoc(), *this));
5271 return MatchOperand_Success;
5274 Index = matchFPURegisterName(Identifier);
5276 Operands.push_back(MipsOperand::createFGRReg(
5277 Index, Identifier, getContext().getRegisterInfo(), S,
5278 getLexer().getLoc(), *this));
5279 return MatchOperand_Success;
5282 Index = matchFCCRegisterName(Identifier);
5284 Operands.push_back(MipsOperand::createFCCReg(
5285 Index, Identifier, getContext().getRegisterInfo(), S,
5286 getLexer().getLoc(), *this));
5287 return MatchOperand_Success;
5290 Index = matchACRegisterName(Identifier);
5292 Operands.push_back(MipsOperand::createACCReg(
5293 Index, Identifier, getContext().getRegisterInfo(), S,
5294 getLexer().getLoc(), *this));
5295 return MatchOperand_Success;
5298 Index = matchMSA128RegisterName(Identifier);
5300 Operands.push_back(MipsOperand::createMSA128Reg(
5301 Index, Identifier, getContext().getRegisterInfo(), S,
5302 getLexer().getLoc(), *this));
5303 return MatchOperand_Success;
5306 Index = matchMSA128CtrlRegisterName(Identifier);
5308 Operands.push_back(MipsOperand::createMSACtrlReg(
5309 Index, Identifier, getContext().getRegisterInfo(), S,
5310 getLexer().getLoc(), *this));
5311 return MatchOperand_Success;
5314 return MatchOperand_NoMatch;
5317 OperandMatchResultTy
5318 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
5319 MCAsmParser &Parser = getParser();
5320 auto Token = Parser.getLexer().peekTok(false);
5322 if (Token.is(AsmToken::Identifier)) {
5323 DEBUG(dbgs() << ".. identifier\n");
5324 StringRef Identifier = Token.getIdentifier();
5325 OperandMatchResultTy ResTy =
5326 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
5328 } else if (Token.is(AsmToken::Integer)) {
5329 DEBUG(dbgs() << ".. integer\n");
5330 Operands.push_back(MipsOperand::createNumericReg(
5331 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
5332 Token.getLoc(), *this));
5333 return MatchOperand_Success;
5336 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
5338 return MatchOperand_NoMatch;
5341 OperandMatchResultTy
5342 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
5343 MCAsmParser &Parser = getParser();
5344 DEBUG(dbgs() << "parseAnyRegister\n");
5346 auto Token = Parser.getTok();
5348 SMLoc S = Token.getLoc();
5350 if (Token.isNot(AsmToken::Dollar)) {
5351 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
5352 if (Token.is(AsmToken::Identifier)) {
5353 if (searchSymbolAlias(Operands))
5354 return MatchOperand_Success;
5356 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
5357 return MatchOperand_NoMatch;
5359 DEBUG(dbgs() << ".. $\n");
5361 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
5362 if (ResTy == MatchOperand_Success) {
5364 Parser.Lex(); // identifier
5369 OperandMatchResultTy
5370 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
5371 MCAsmParser &Parser = getParser();
5372 DEBUG(dbgs() << "parseJumpTarget\n");
5374 SMLoc S = getLexer().getLoc();
5376 // Registers are a valid target and have priority over symbols.
5377 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5378 if (ResTy != MatchOperand_NoMatch)
5381 // Integers and expressions are acceptable
5382 const MCExpr *Expr = nullptr;
5383 if (Parser.parseExpression(Expr)) {
5384 // We have no way of knowing if a symbol was consumed so we must ParseFail
5385 return MatchOperand_ParseFail;
5388 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
5389 return MatchOperand_Success;
5392 OperandMatchResultTy
5393 MipsAsmParser::parseInvNum(OperandVector &Operands) {
5394 MCAsmParser &Parser = getParser();
5395 const MCExpr *IdVal;
5396 // If the first token is '$' we may have register operand.
5397 if (Parser.getTok().is(AsmToken::Dollar))
5398 return MatchOperand_NoMatch;
5399 SMLoc S = Parser.getTok().getLoc();
5400 if (getParser().parseExpression(IdVal))
5401 return MatchOperand_ParseFail;
5402 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
5403 assert(MCE && "Unexpected MCExpr type.");
5404 int64_t Val = MCE->getValue();
5405 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5406 Operands.push_back(MipsOperand::CreateImm(
5407 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
5408 return MatchOperand_Success;
5411 OperandMatchResultTy
5412 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
5413 MCAsmParser &Parser = getParser();
5414 SmallVector<unsigned, 10> Regs;
5416 unsigned PrevReg = Mips::NoRegister;
5417 bool RegRange = false;
5418 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5420 if (Parser.getTok().isNot(AsmToken::Dollar))
5421 return MatchOperand_ParseFail;
5423 SMLoc S = Parser.getTok().getLoc();
5424 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
5425 SMLoc E = getLexer().getLoc();
5426 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
5427 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
5429 // Remove last register operand because registers from register range
5430 // should be inserted first.
5431 if ((isGP64bit() && RegNo == Mips::RA_64) ||
5432 (!isGP64bit() && RegNo == Mips::RA)) {
5433 Regs.push_back(RegNo);
5435 unsigned TmpReg = PrevReg + 1;
5436 while (TmpReg <= RegNo) {
5437 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
5438 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
5440 Error(E, "invalid register operand");
5441 return MatchOperand_ParseFail;
5445 Regs.push_back(TmpReg++);
5451 if ((PrevReg == Mips::NoRegister) &&
5452 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5453 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5454 Error(E, "$16 or $31 expected");
5455 return MatchOperand_ParseFail;
5456 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5457 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5459 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5460 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5462 Error(E, "invalid register operand");
5463 return MatchOperand_ParseFail;
5464 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5465 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5466 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5468 Error(E, "consecutive register numbers expected");
5469 return MatchOperand_ParseFail;
5472 Regs.push_back(RegNo);
5475 if (Parser.getTok().is(AsmToken::Minus))
5478 if (!Parser.getTok().isNot(AsmToken::Minus) &&
5479 !Parser.getTok().isNot(AsmToken::Comma)) {
5480 Error(E, "',' or '-' expected");
5481 return MatchOperand_ParseFail;
5484 Lex(); // Consume comma or minus
5485 if (Parser.getTok().isNot(AsmToken::Dollar))
5491 SMLoc E = Parser.getTok().getLoc();
5492 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5493 parseMemOperand(Operands);
5494 return MatchOperand_Success;
5497 OperandMatchResultTy
5498 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
5499 MCAsmParser &Parser = getParser();
5501 SMLoc S = Parser.getTok().getLoc();
5502 if (parseAnyRegister(Operands) != MatchOperand_Success)
5503 return MatchOperand_ParseFail;
5505 SMLoc E = Parser.getTok().getLoc();
5506 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
5508 Operands.pop_back();
5509 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
5510 return MatchOperand_Success;
5513 OperandMatchResultTy
5514 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
5515 MCAsmParser &Parser = getParser();
5516 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5517 SmallVector<unsigned, 10> Regs;
5519 if (Parser.getTok().isNot(AsmToken::Dollar))
5520 return MatchOperand_ParseFail;
5522 SMLoc S = Parser.getTok().getLoc();
5524 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5525 return MatchOperand_ParseFail;
5527 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5528 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5529 Regs.push_back(RegNo);
5531 SMLoc E = Parser.getTok().getLoc();
5532 if (Parser.getTok().isNot(AsmToken::Comma)) {
5533 Error(E, "',' expected");
5534 return MatchOperand_ParseFail;
5540 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5541 return MatchOperand_ParseFail;
5543 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5544 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5545 Regs.push_back(RegNo);
5547 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5549 return MatchOperand_Success;
5552 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
5554 /// ::= '(', register, ')'
5555 /// handle it before we iterate so we don't get tripped up by the lack of
5557 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
5558 MCAsmParser &Parser = getParser();
5559 if (getLexer().is(AsmToken::LParen)) {
5561 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
5563 if (parseOperand(Operands, Name)) {
5564 SMLoc Loc = getLexer().getLoc();
5565 return Error(Loc, "unexpected token in argument list");
5567 if (Parser.getTok().isNot(AsmToken::RParen)) {
5568 SMLoc Loc = getLexer().getLoc();
5569 return Error(Loc, "unexpected token, expected ')'");
5572 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
5578 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
5579 /// either one of these.
5580 /// ::= '[', register, ']'
5581 /// ::= '[', integer, ']'
5582 /// handle it before we iterate so we don't get tripped up by the lack of
5584 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
5585 OperandVector &Operands) {
5586 MCAsmParser &Parser = getParser();
5587 if (getLexer().is(AsmToken::LBrac)) {
5589 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
5591 if (parseOperand(Operands, Name)) {
5592 SMLoc Loc = getLexer().getLoc();
5593 return Error(Loc, "unexpected token in argument list");
5595 if (Parser.getTok().isNot(AsmToken::RBrac)) {
5596 SMLoc Loc = getLexer().getLoc();
5597 return Error(Loc, "unexpected token, expected ']'");
5600 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
5606 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
5607 SMLoc NameLoc, OperandVector &Operands) {
5608 MCAsmParser &Parser = getParser();
5609 DEBUG(dbgs() << "ParseInstruction\n");
5611 // We have reached first instruction, module directive are now forbidden.
5612 getTargetStreamer().forbidModuleDirective();
5614 // Check if we have valid mnemonic
5615 if (!mnemonicIsValid(Name, 0)) {
5616 return Error(NameLoc, "unknown instruction");
5618 // First operand in MCInst is instruction mnemonic.
5619 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
5621 // Read the remaining operands.
5622 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5623 // Read the first operand.
5624 if (parseOperand(Operands, Name)) {
5625 SMLoc Loc = getLexer().getLoc();
5626 return Error(Loc, "unexpected token in argument list");
5628 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
5630 // AFAIK, parenthesis suffixes are never on the first operand
5632 while (getLexer().is(AsmToken::Comma)) {
5633 Parser.Lex(); // Eat the comma.
5634 // Parse and remember the operand.
5635 if (parseOperand(Operands, Name)) {
5636 SMLoc Loc = getLexer().getLoc();
5637 return Error(Loc, "unexpected token in argument list");
5639 // Parse bracket and parenthesis suffixes before we iterate
5640 if (getLexer().is(AsmToken::LBrac)) {
5641 if (parseBracketSuffix(Name, Operands))
5643 } else if (getLexer().is(AsmToken::LParen) &&
5644 parseParenSuffix(Name, Operands))
5648 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5649 SMLoc Loc = getLexer().getLoc();
5650 return Error(Loc, "unexpected token in argument list");
5652 Parser.Lex(); // Consume the EndOfStatement.
5656 // FIXME: Given that these have the same name, these should both be
5657 // consistent on affecting the Parser.
5658 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
5659 SMLoc Loc = getLexer().getLoc();
5660 return Error(Loc, ErrorMsg);
5663 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
5664 return Error(Loc, ErrorMsg);
5667 bool MipsAsmParser::parseSetNoAtDirective() {
5668 MCAsmParser &Parser = getParser();
5669 // Line should look like: ".set noat".
5671 // Set the $at register to $0.
5672 AssemblerOptions.back()->setATRegIndex(0);
5674 Parser.Lex(); // Eat "noat".
5676 // If this is not the end of the statement, report an error.
5677 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5678 reportParseError("unexpected token, expected end of statement");
5682 getTargetStreamer().emitDirectiveSetNoAt();
5683 Parser.Lex(); // Consume the EndOfStatement.
5687 bool MipsAsmParser::parseSetAtDirective() {
5688 // Line can be: ".set at", which sets $at to $1
5689 // or ".set at=$reg", which sets $at to $reg.
5690 MCAsmParser &Parser = getParser();
5691 Parser.Lex(); // Eat "at".
5693 if (getLexer().is(AsmToken::EndOfStatement)) {
5694 // No register was specified, so we set $at to $1.
5695 AssemblerOptions.back()->setATRegIndex(1);
5697 getTargetStreamer().emitDirectiveSetAt();
5698 Parser.Lex(); // Consume the EndOfStatement.
5702 if (getLexer().isNot(AsmToken::Equal)) {
5703 reportParseError("unexpected token, expected equals sign");
5706 Parser.Lex(); // Eat "=".
5708 if (getLexer().isNot(AsmToken::Dollar)) {
5709 if (getLexer().is(AsmToken::EndOfStatement)) {
5710 reportParseError("no register specified");
5713 reportParseError("unexpected token, expected dollar sign '$'");
5717 Parser.Lex(); // Eat "$".
5719 // Find out what "reg" is.
5721 const AsmToken &Reg = Parser.getTok();
5722 if (Reg.is(AsmToken::Identifier)) {
5723 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
5724 } else if (Reg.is(AsmToken::Integer)) {
5725 AtRegNo = Reg.getIntVal();
5727 reportParseError("unexpected token, expected identifier or integer");
5731 // Check if $reg is a valid register. If it is, set $at to $reg.
5732 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
5733 reportParseError("invalid register");
5736 Parser.Lex(); // Eat "reg".
5738 // If this is not the end of the statement, report an error.
5739 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5740 reportParseError("unexpected token, expected end of statement");
5744 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
5746 Parser.Lex(); // Consume the EndOfStatement.
5750 bool MipsAsmParser::parseSetReorderDirective() {
5751 MCAsmParser &Parser = getParser();
5753 // If this is not the end of the statement, report an error.
5754 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5755 reportParseError("unexpected token, expected end of statement");
5758 AssemblerOptions.back()->setReorder();
5759 getTargetStreamer().emitDirectiveSetReorder();
5760 Parser.Lex(); // Consume the EndOfStatement.
5764 bool MipsAsmParser::parseSetNoReorderDirective() {
5765 MCAsmParser &Parser = getParser();
5767 // If this is not the end of the statement, report an error.
5768 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5769 reportParseError("unexpected token, expected end of statement");
5772 AssemblerOptions.back()->setNoReorder();
5773 getTargetStreamer().emitDirectiveSetNoReorder();
5774 Parser.Lex(); // Consume the EndOfStatement.
5778 bool MipsAsmParser::parseSetMacroDirective() {
5779 MCAsmParser &Parser = getParser();
5781 // If this is not the end of the statement, report an error.
5782 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5783 reportParseError("unexpected token, expected end of statement");
5786 AssemblerOptions.back()->setMacro();
5787 getTargetStreamer().emitDirectiveSetMacro();
5788 Parser.Lex(); // Consume the EndOfStatement.
5792 bool MipsAsmParser::parseSetNoMacroDirective() {
5793 MCAsmParser &Parser = getParser();
5795 // If this is not the end of the statement, report an error.
5796 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5797 reportParseError("unexpected token, expected end of statement");
5800 if (AssemblerOptions.back()->isReorder()) {
5801 reportParseError("`noreorder' must be set before `nomacro'");
5804 AssemblerOptions.back()->setNoMacro();
5805 getTargetStreamer().emitDirectiveSetNoMacro();
5806 Parser.Lex(); // Consume the EndOfStatement.
5810 bool MipsAsmParser::parseSetMsaDirective() {
5811 MCAsmParser &Parser = getParser();
5814 // If this is not the end of the statement, report an error.
5815 if (getLexer().isNot(AsmToken::EndOfStatement))
5816 return reportParseError("unexpected token, expected end of statement");
5818 setFeatureBits(Mips::FeatureMSA, "msa");
5819 getTargetStreamer().emitDirectiveSetMsa();
5823 bool MipsAsmParser::parseSetNoMsaDirective() {
5824 MCAsmParser &Parser = getParser();
5827 // If this is not the end of the statement, report an error.
5828 if (getLexer().isNot(AsmToken::EndOfStatement))
5829 return reportParseError("unexpected token, expected end of statement");
5831 clearFeatureBits(Mips::FeatureMSA, "msa");
5832 getTargetStreamer().emitDirectiveSetNoMsa();
5836 bool MipsAsmParser::parseSetNoDspDirective() {
5837 MCAsmParser &Parser = getParser();
5838 Parser.Lex(); // Eat "nodsp".
5840 // If this is not the end of the statement, report an error.
5841 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5842 reportParseError("unexpected token, expected end of statement");
5846 clearFeatureBits(Mips::FeatureDSP, "dsp");
5847 getTargetStreamer().emitDirectiveSetNoDsp();
5851 bool MipsAsmParser::parseSetMips16Directive() {
5852 MCAsmParser &Parser = getParser();
5853 Parser.Lex(); // Eat "mips16".
5855 // If this is not the end of the statement, report an error.
5856 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5857 reportParseError("unexpected token, expected end of statement");
5861 setFeatureBits(Mips::FeatureMips16, "mips16");
5862 getTargetStreamer().emitDirectiveSetMips16();
5863 Parser.Lex(); // Consume the EndOfStatement.
5867 bool MipsAsmParser::parseSetNoMips16Directive() {
5868 MCAsmParser &Parser = getParser();
5869 Parser.Lex(); // Eat "nomips16".
5871 // If this is not the end of the statement, report an error.
5872 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5873 reportParseError("unexpected token, expected end of statement");
5877 clearFeatureBits(Mips::FeatureMips16, "mips16");
5878 getTargetStreamer().emitDirectiveSetNoMips16();
5879 Parser.Lex(); // Consume the EndOfStatement.
5883 bool MipsAsmParser::parseSetFpDirective() {
5884 MCAsmParser &Parser = getParser();
5885 MipsABIFlagsSection::FpABIKind FpAbiVal;
5886 // Line can be: .set fp=32
5889 Parser.Lex(); // Eat fp token
5890 AsmToken Tok = Parser.getTok();
5891 if (Tok.isNot(AsmToken::Equal)) {
5892 reportParseError("unexpected token, expected equals sign '='");
5895 Parser.Lex(); // Eat '=' token.
5896 Tok = Parser.getTok();
5898 if (!parseFpABIValue(FpAbiVal, ".set"))
5901 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5902 reportParseError("unexpected token, expected end of statement");
5905 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5906 Parser.Lex(); // Consume the EndOfStatement.
5910 bool MipsAsmParser::parseSetOddSPRegDirective() {
5911 MCAsmParser &Parser = getParser();
5913 Parser.Lex(); // Eat "oddspreg".
5914 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5915 reportParseError("unexpected token, expected end of statement");
5919 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5920 getTargetStreamer().emitDirectiveSetOddSPReg();
5924 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5925 MCAsmParser &Parser = getParser();
5927 Parser.Lex(); // Eat "nooddspreg".
5928 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5929 reportParseError("unexpected token, expected end of statement");
5933 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5934 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5938 bool MipsAsmParser::parseSetPopDirective() {
5939 MCAsmParser &Parser = getParser();
5940 SMLoc Loc = getLexer().getLoc();
5943 if (getLexer().isNot(AsmToken::EndOfStatement))
5944 return reportParseError("unexpected token, expected end of statement");
5946 // Always keep an element on the options "stack" to prevent the user
5947 // from changing the initial options. This is how we remember them.
5948 if (AssemblerOptions.size() == 2)
5949 return reportParseError(Loc, ".set pop with no .set push");
5951 MCSubtargetInfo &STI = copySTI();
5952 AssemblerOptions.pop_back();
5953 setAvailableFeatures(
5954 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5955 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5957 getTargetStreamer().emitDirectiveSetPop();
5961 bool MipsAsmParser::parseSetPushDirective() {
5962 MCAsmParser &Parser = getParser();
5964 if (getLexer().isNot(AsmToken::EndOfStatement))
5965 return reportParseError("unexpected token, expected end of statement");
5967 // Create a copy of the current assembler options environment and push it.
5968 AssemblerOptions.push_back(
5969 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5971 getTargetStreamer().emitDirectiveSetPush();
5975 bool MipsAsmParser::parseSetSoftFloatDirective() {
5976 MCAsmParser &Parser = getParser();
5978 if (getLexer().isNot(AsmToken::EndOfStatement))
5979 return reportParseError("unexpected token, expected end of statement");
5981 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5982 getTargetStreamer().emitDirectiveSetSoftFloat();
5986 bool MipsAsmParser::parseSetHardFloatDirective() {
5987 MCAsmParser &Parser = getParser();
5989 if (getLexer().isNot(AsmToken::EndOfStatement))
5990 return reportParseError("unexpected token, expected end of statement");
5992 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5993 getTargetStreamer().emitDirectiveSetHardFloat();
5997 bool MipsAsmParser::parseSetAssignment() {
5999 const MCExpr *Value;
6000 MCAsmParser &Parser = getParser();
6002 if (Parser.parseIdentifier(Name))
6003 reportParseError("expected identifier after .set");
6005 if (getLexer().isNot(AsmToken::Comma))
6006 return reportParseError("unexpected token, expected comma");
6009 if (Parser.parseExpression(Value))
6010 return reportParseError("expected valid expression after comma");
6012 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6013 Sym->setVariableValue(Value);
6018 bool MipsAsmParser::parseSetMips0Directive() {
6019 MCAsmParser &Parser = getParser();
6021 if (getLexer().isNot(AsmToken::EndOfStatement))
6022 return reportParseError("unexpected token, expected end of statement");
6024 // Reset assembler options to their initial values.
6025 MCSubtargetInfo &STI = copySTI();
6026 setAvailableFeatures(
6027 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6028 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6029 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6031 getTargetStreamer().emitDirectiveSetMips0();
6035 bool MipsAsmParser::parseSetArchDirective() {
6036 MCAsmParser &Parser = getParser();
6038 if (getLexer().isNot(AsmToken::Equal))
6039 return reportParseError("unexpected token, expected equals sign");
6043 if (Parser.parseIdentifier(Arch))
6044 return reportParseError("expected arch identifier");
6046 StringRef ArchFeatureName =
6047 StringSwitch<StringRef>(Arch)
6048 .Case("mips1", "mips1")
6049 .Case("mips2", "mips2")
6050 .Case("mips3", "mips3")
6051 .Case("mips4", "mips4")
6052 .Case("mips5", "mips5")
6053 .Case("mips32", "mips32")
6054 .Case("mips32r2", "mips32r2")
6055 .Case("mips32r3", "mips32r3")
6056 .Case("mips32r5", "mips32r5")
6057 .Case("mips32r6", "mips32r6")
6058 .Case("mips64", "mips64")
6059 .Case("mips64r2", "mips64r2")
6060 .Case("mips64r3", "mips64r3")
6061 .Case("mips64r5", "mips64r5")
6062 .Case("mips64r6", "mips64r6")
6063 .Case("octeon", "cnmips")
6064 .Case("r4000", "mips3") // This is an implementation of Mips3.
6067 if (ArchFeatureName.empty())
6068 return reportParseError("unsupported architecture");
6070 selectArch(ArchFeatureName);
6071 getTargetStreamer().emitDirectiveSetArch(Arch);
6075 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6076 MCAsmParser &Parser = getParser();
6078 if (getLexer().isNot(AsmToken::EndOfStatement))
6079 return reportParseError("unexpected token, expected end of statement");
6083 llvm_unreachable("Unimplemented feature");
6084 case Mips::FeatureDSP:
6085 setFeatureBits(Mips::FeatureDSP, "dsp");
6086 getTargetStreamer().emitDirectiveSetDsp();
6088 case Mips::FeatureMicroMips:
6089 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6090 getTargetStreamer().emitDirectiveSetMicroMips();
6092 case Mips::FeatureMips1:
6093 selectArch("mips1");
6094 getTargetStreamer().emitDirectiveSetMips1();
6096 case Mips::FeatureMips2:
6097 selectArch("mips2");
6098 getTargetStreamer().emitDirectiveSetMips2();
6100 case Mips::FeatureMips3:
6101 selectArch("mips3");
6102 getTargetStreamer().emitDirectiveSetMips3();
6104 case Mips::FeatureMips4:
6105 selectArch("mips4");
6106 getTargetStreamer().emitDirectiveSetMips4();
6108 case Mips::FeatureMips5:
6109 selectArch("mips5");
6110 getTargetStreamer().emitDirectiveSetMips5();
6112 case Mips::FeatureMips32:
6113 selectArch("mips32");
6114 getTargetStreamer().emitDirectiveSetMips32();
6116 case Mips::FeatureMips32r2:
6117 selectArch("mips32r2");
6118 getTargetStreamer().emitDirectiveSetMips32R2();
6120 case Mips::FeatureMips32r3:
6121 selectArch("mips32r3");
6122 getTargetStreamer().emitDirectiveSetMips32R3();
6124 case Mips::FeatureMips32r5:
6125 selectArch("mips32r5");
6126 getTargetStreamer().emitDirectiveSetMips32R5();
6128 case Mips::FeatureMips32r6:
6129 selectArch("mips32r6");
6130 getTargetStreamer().emitDirectiveSetMips32R6();
6132 case Mips::FeatureMips64:
6133 selectArch("mips64");
6134 getTargetStreamer().emitDirectiveSetMips64();
6136 case Mips::FeatureMips64r2:
6137 selectArch("mips64r2");
6138 getTargetStreamer().emitDirectiveSetMips64R2();
6140 case Mips::FeatureMips64r3:
6141 selectArch("mips64r3");
6142 getTargetStreamer().emitDirectiveSetMips64R3();
6144 case Mips::FeatureMips64r5:
6145 selectArch("mips64r5");
6146 getTargetStreamer().emitDirectiveSetMips64R5();
6148 case Mips::FeatureMips64r6:
6149 selectArch("mips64r6");
6150 getTargetStreamer().emitDirectiveSetMips64R6();
6156 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6157 MCAsmParser &Parser = getParser();
6158 if (getLexer().isNot(AsmToken::Comma)) {
6159 SMLoc Loc = getLexer().getLoc();
6160 return Error(Loc, ErrorStr);
6163 Parser.Lex(); // Eat the comma.
6167 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
6168 // In this class, it is only used for .cprestore.
6169 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
6170 // MipsTargetELFStreamer and MipsAsmParser.
6171 bool MipsAsmParser::isPicAndNotNxxAbi() {
6172 return inPicMode() && !(isABI_N32() || isABI_N64());
6175 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
6176 if (AssemblerOptions.back()->isReorder())
6177 Warning(Loc, ".cpload should be inside a noreorder section");
6179 if (inMips16Mode()) {
6180 reportParseError(".cpload is not supported in Mips16 mode");
6184 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
6185 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
6186 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6187 reportParseError("expected register containing function address");
6191 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
6192 if (!RegOpnd.isGPRAsmReg()) {
6193 reportParseError(RegOpnd.getStartLoc(), "invalid register");
6197 // If this is not the end of the statement, report an error.
6198 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6199 reportParseError("unexpected token, expected end of statement");
6203 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
6207 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
6208 MCAsmParser &Parser = getParser();
6210 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
6211 // is used in non-PIC mode.
6213 if (inMips16Mode()) {
6214 reportParseError(".cprestore is not supported in Mips16 mode");
6218 // Get the stack offset value.
6219 const MCExpr *StackOffset;
6220 int64_t StackOffsetVal;
6221 if (Parser.parseExpression(StackOffset)) {
6222 reportParseError("expected stack offset value");
6226 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
6227 reportParseError("stack offset is not an absolute expression");
6231 if (StackOffsetVal < 0) {
6232 Warning(Loc, ".cprestore with negative stack offset has no effect");
6233 IsCpRestoreSet = false;
6235 IsCpRestoreSet = true;
6236 CpRestoreOffset = StackOffsetVal;
6239 // If this is not the end of the statement, report an error.
6240 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6241 reportParseError("unexpected token, expected end of statement");
6245 if (!getTargetStreamer().emitDirectiveCpRestore(
6246 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
6248 Parser.Lex(); // Consume the EndOfStatement.
6252 bool MipsAsmParser::parseDirectiveCPSetup() {
6253 MCAsmParser &Parser = getParser();
6256 bool SaveIsReg = true;
6258 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6259 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6260 if (ResTy == MatchOperand_NoMatch) {
6261 reportParseError("expected register containing function address");
6265 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6266 if (!FuncRegOpnd.isGPRAsmReg()) {
6267 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
6271 FuncReg = FuncRegOpnd.getGPR32Reg();
6274 if (!eatComma("unexpected token, expected comma"))
6277 ResTy = parseAnyRegister(TmpReg);
6278 if (ResTy == MatchOperand_NoMatch) {
6279 const MCExpr *OffsetExpr;
6281 SMLoc ExprLoc = getLexer().getLoc();
6283 if (Parser.parseExpression(OffsetExpr) ||
6284 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
6285 reportParseError(ExprLoc, "expected save register or stack offset");
6292 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6293 if (!SaveOpnd.isGPRAsmReg()) {
6294 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
6297 Save = SaveOpnd.getGPR32Reg();
6300 if (!eatComma("unexpected token, expected comma"))
6304 if (Parser.parseExpression(Expr)) {
6305 reportParseError("expected expression");
6309 if (Expr->getKind() != MCExpr::SymbolRef) {
6310 reportParseError("expected symbol");
6313 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6315 CpSaveLocation = Save;
6316 CpSaveLocationIsRegister = SaveIsReg;
6318 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
6323 bool MipsAsmParser::parseDirectiveCPReturn() {
6324 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
6325 CpSaveLocationIsRegister);
6329 bool MipsAsmParser::parseDirectiveNaN() {
6330 MCAsmParser &Parser = getParser();
6331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6332 const AsmToken &Tok = Parser.getTok();
6334 if (Tok.getString() == "2008") {
6336 getTargetStreamer().emitDirectiveNaN2008();
6338 } else if (Tok.getString() == "legacy") {
6340 getTargetStreamer().emitDirectiveNaNLegacy();
6344 // If we don't recognize the option passed to the .nan
6345 // directive (e.g. no option or unknown option), emit an error.
6346 reportParseError("invalid option in .nan directive");
6350 bool MipsAsmParser::parseDirectiveSet() {
6351 MCAsmParser &Parser = getParser();
6352 // Get the next token.
6353 const AsmToken &Tok = Parser.getTok();
6355 if (Tok.getString() == "noat") {
6356 return parseSetNoAtDirective();
6357 } else if (Tok.getString() == "at") {
6358 return parseSetAtDirective();
6359 } else if (Tok.getString() == "arch") {
6360 return parseSetArchDirective();
6361 } else if (Tok.getString() == "bopt") {
6362 Warning(Tok.getLoc(), "'bopt' feature is unsupported");
6365 } else if (Tok.getString() == "nobopt") {
6366 // We're already running in nobopt mode, so nothing to do.
6369 } else if (Tok.getString() == "fp") {
6370 return parseSetFpDirective();
6371 } else if (Tok.getString() == "oddspreg") {
6372 return parseSetOddSPRegDirective();
6373 } else if (Tok.getString() == "nooddspreg") {
6374 return parseSetNoOddSPRegDirective();
6375 } else if (Tok.getString() == "pop") {
6376 return parseSetPopDirective();
6377 } else if (Tok.getString() == "push") {
6378 return parseSetPushDirective();
6379 } else if (Tok.getString() == "reorder") {
6380 return parseSetReorderDirective();
6381 } else if (Tok.getString() == "noreorder") {
6382 return parseSetNoReorderDirective();
6383 } else if (Tok.getString() == "macro") {
6384 return parseSetMacroDirective();
6385 } else if (Tok.getString() == "nomacro") {
6386 return parseSetNoMacroDirective();
6387 } else if (Tok.getString() == "mips16") {
6388 return parseSetMips16Directive();
6389 } else if (Tok.getString() == "nomips16") {
6390 return parseSetNoMips16Directive();
6391 } else if (Tok.getString() == "nomicromips") {
6392 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
6393 getTargetStreamer().emitDirectiveSetNoMicroMips();
6394 Parser.eatToEndOfStatement();
6396 } else if (Tok.getString() == "micromips") {
6397 return parseSetFeature(Mips::FeatureMicroMips);
6398 } else if (Tok.getString() == "mips0") {
6399 return parseSetMips0Directive();
6400 } else if (Tok.getString() == "mips1") {
6401 return parseSetFeature(Mips::FeatureMips1);
6402 } else if (Tok.getString() == "mips2") {
6403 return parseSetFeature(Mips::FeatureMips2);
6404 } else if (Tok.getString() == "mips3") {
6405 return parseSetFeature(Mips::FeatureMips3);
6406 } else if (Tok.getString() == "mips4") {
6407 return parseSetFeature(Mips::FeatureMips4);
6408 } else if (Tok.getString() == "mips5") {
6409 return parseSetFeature(Mips::FeatureMips5);
6410 } else if (Tok.getString() == "mips32") {
6411 return parseSetFeature(Mips::FeatureMips32);
6412 } else if (Tok.getString() == "mips32r2") {
6413 return parseSetFeature(Mips::FeatureMips32r2);
6414 } else if (Tok.getString() == "mips32r3") {
6415 return parseSetFeature(Mips::FeatureMips32r3);
6416 } else if (Tok.getString() == "mips32r5") {
6417 return parseSetFeature(Mips::FeatureMips32r5);
6418 } else if (Tok.getString() == "mips32r6") {
6419 return parseSetFeature(Mips::FeatureMips32r6);
6420 } else if (Tok.getString() == "mips64") {
6421 return parseSetFeature(Mips::FeatureMips64);
6422 } else if (Tok.getString() == "mips64r2") {
6423 return parseSetFeature(Mips::FeatureMips64r2);
6424 } else if (Tok.getString() == "mips64r3") {
6425 return parseSetFeature(Mips::FeatureMips64r3);
6426 } else if (Tok.getString() == "mips64r5") {
6427 return parseSetFeature(Mips::FeatureMips64r5);
6428 } else if (Tok.getString() == "mips64r6") {
6429 return parseSetFeature(Mips::FeatureMips64r6);
6430 } else if (Tok.getString() == "dsp") {
6431 return parseSetFeature(Mips::FeatureDSP);
6432 } else if (Tok.getString() == "nodsp") {
6433 return parseSetNoDspDirective();
6434 } else if (Tok.getString() == "msa") {
6435 return parseSetMsaDirective();
6436 } else if (Tok.getString() == "nomsa") {
6437 return parseSetNoMsaDirective();
6438 } else if (Tok.getString() == "softfloat") {
6439 return parseSetSoftFloatDirective();
6440 } else if (Tok.getString() == "hardfloat") {
6441 return parseSetHardFloatDirective();
6443 // It is just an identifier, look for an assignment.
6444 parseSetAssignment();
6451 /// parseDataDirective
6452 /// ::= .word [ expression (, expression)* ]
6453 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
6454 MCAsmParser &Parser = getParser();
6455 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6457 const MCExpr *Value;
6458 if (getParser().parseExpression(Value))
6461 getParser().getStreamer().EmitValue(Value, Size);
6463 if (getLexer().is(AsmToken::EndOfStatement))
6466 if (getLexer().isNot(AsmToken::Comma))
6467 return Error(L, "unexpected token, expected comma");
6476 /// parseDirectiveGpWord
6477 /// ::= .gpword local_sym
6478 bool MipsAsmParser::parseDirectiveGpWord() {
6479 MCAsmParser &Parser = getParser();
6480 const MCExpr *Value;
6481 // EmitGPRel32Value requires an expression, so we are using base class
6482 // method to evaluate the expression.
6483 if (getParser().parseExpression(Value))
6485 getParser().getStreamer().EmitGPRel32Value(Value);
6487 if (getLexer().isNot(AsmToken::EndOfStatement))
6488 return Error(getLexer().getLoc(),
6489 "unexpected token, expected end of statement");
6490 Parser.Lex(); // Eat EndOfStatement token.
6494 /// parseDirectiveGpDWord
6495 /// ::= .gpdword local_sym
6496 bool MipsAsmParser::parseDirectiveGpDWord() {
6497 MCAsmParser &Parser = getParser();
6498 const MCExpr *Value;
6499 // EmitGPRel64Value requires an expression, so we are using base class
6500 // method to evaluate the expression.
6501 if (getParser().parseExpression(Value))
6503 getParser().getStreamer().EmitGPRel64Value(Value);
6505 if (getLexer().isNot(AsmToken::EndOfStatement))
6506 return Error(getLexer().getLoc(),
6507 "unexpected token, expected end of statement");
6508 Parser.Lex(); // Eat EndOfStatement token.
6512 /// parseDirectiveDtpRelWord
6513 /// ::= .dtprelword tls_sym
6514 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6515 MCAsmParser &Parser = getParser();
6516 const MCExpr *Value;
6517 // EmitDTPRel32Value requires an expression, so we are using base class
6518 // method to evaluate the expression.
6519 if (getParser().parseExpression(Value))
6521 getParser().getStreamer().EmitDTPRel32Value(Value);
6523 if (getLexer().isNot(AsmToken::EndOfStatement))
6524 return Error(getLexer().getLoc(),
6525 "unexpected token, expected end of statement");
6526 Parser.Lex(); // Eat EndOfStatement token.
6530 /// parseDirectiveDtpRelDWord
6531 /// ::= .dtpreldword tls_sym
6532 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6533 MCAsmParser &Parser = getParser();
6534 const MCExpr *Value;
6535 // EmitDTPRel64Value requires an expression, so we are using base class
6536 // method to evaluate the expression.
6537 if (getParser().parseExpression(Value))
6539 getParser().getStreamer().EmitDTPRel64Value(Value);
6541 if (getLexer().isNot(AsmToken::EndOfStatement))
6542 return Error(getLexer().getLoc(),
6543 "unexpected token, expected end of statement");
6544 Parser.Lex(); // Eat EndOfStatement token.
6548 /// parseDirectiveTpRelWord
6549 /// ::= .tprelword tls_sym
6550 bool MipsAsmParser::parseDirectiveTpRelWord() {
6551 MCAsmParser &Parser = getParser();
6552 const MCExpr *Value;
6553 // EmitTPRel32Value requires an expression, so we are using base class
6554 // method to evaluate the expression.
6555 if (getParser().parseExpression(Value))
6557 getParser().getStreamer().EmitTPRel32Value(Value);
6559 if (getLexer().isNot(AsmToken::EndOfStatement))
6560 return Error(getLexer().getLoc(),
6561 "unexpected token, expected end of statement");
6562 Parser.Lex(); // Eat EndOfStatement token.
6566 /// parseDirectiveTpRelDWord
6567 /// ::= .tpreldword tls_sym
6568 bool MipsAsmParser::parseDirectiveTpRelDWord() {
6569 MCAsmParser &Parser = getParser();
6570 const MCExpr *Value;
6571 // EmitTPRel64Value requires an expression, so we are using base class
6572 // method to evaluate the expression.
6573 if (getParser().parseExpression(Value))
6575 getParser().getStreamer().EmitTPRel64Value(Value);
6577 if (getLexer().isNot(AsmToken::EndOfStatement))
6578 return Error(getLexer().getLoc(),
6579 "unexpected token, expected end of statement");
6580 Parser.Lex(); // Eat EndOfStatement token.
6584 bool MipsAsmParser::parseDirectiveOption() {
6585 MCAsmParser &Parser = getParser();
6586 // Get the option token.
6587 AsmToken Tok = Parser.getTok();
6588 // At the moment only identifiers are supported.
6589 if (Tok.isNot(AsmToken::Identifier)) {
6590 return Error(Parser.getTok().getLoc(),
6591 "unexpected token, expected identifier");
6594 StringRef Option = Tok.getIdentifier();
6596 if (Option == "pic0") {
6597 // MipsAsmParser needs to know if the current PIC mode changes.
6598 IsPicEnabled = false;
6600 getTargetStreamer().emitDirectiveOptionPic0();
6602 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6603 return Error(Parser.getTok().getLoc(),
6604 "unexpected token, expected end of statement");
6609 if (Option == "pic2") {
6610 // MipsAsmParser needs to know if the current PIC mode changes.
6611 IsPicEnabled = true;
6613 getTargetStreamer().emitDirectiveOptionPic2();
6615 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6616 return Error(Parser.getTok().getLoc(),
6617 "unexpected token, expected end of statement");
6623 Warning(Parser.getTok().getLoc(),
6624 "unknown option, expected 'pic0' or 'pic2'");
6625 Parser.eatToEndOfStatement();
6629 /// parseInsnDirective
6631 bool MipsAsmParser::parseInsnDirective() {
6632 // If this is not the end of the statement, report an error.
6633 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6634 reportParseError("unexpected token, expected end of statement");
6638 // The actual label marking happens in
6639 // MipsELFStreamer::createPendingLabelRelocs().
6640 getTargetStreamer().emitDirectiveInsn();
6642 getParser().Lex(); // Eat EndOfStatement token.
6646 /// parseSSectionDirective
6649 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
6650 // If this is not the end of the statement, report an error.
6651 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6652 reportParseError("unexpected token, expected end of statement");
6656 MCSection *ELFSection = getContext().getELFSection(
6657 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
6658 getParser().getStreamer().SwitchSection(ELFSection);
6660 getParser().Lex(); // Eat EndOfStatement token.
6664 /// parseDirectiveModule
6665 /// ::= .module oddspreg
6666 /// ::= .module nooddspreg
6667 /// ::= .module fp=value
6668 /// ::= .module softfloat
6669 /// ::= .module hardfloat
6670 bool MipsAsmParser::parseDirectiveModule() {
6671 MCAsmParser &Parser = getParser();
6672 MCAsmLexer &Lexer = getLexer();
6673 SMLoc L = Lexer.getLoc();
6675 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
6676 // TODO : get a better message.
6677 reportParseError(".module directive must appear before any code");
6682 if (Parser.parseIdentifier(Option)) {
6683 reportParseError("expected .module option identifier");
6687 if (Option == "oddspreg") {
6688 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6690 // Synchronize the abiflags information with the FeatureBits information we
6692 getTargetStreamer().updateABIInfo(*this);
6694 // If printing assembly, use the recently updated abiflags information.
6695 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6696 // emitted at the end).
6697 getTargetStreamer().emitDirectiveModuleOddSPReg();
6699 // If this is not the end of the statement, report an error.
6700 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6701 reportParseError("unexpected token, expected end of statement");
6705 return false; // parseDirectiveModule has finished successfully.
6706 } else if (Option == "nooddspreg") {
6708 return Error(L, "'.module nooddspreg' requires the O32 ABI");
6711 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6713 // Synchronize the abiflags information with the FeatureBits information we
6715 getTargetStreamer().updateABIInfo(*this);
6717 // If printing assembly, use the recently updated abiflags information.
6718 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6719 // emitted at the end).
6720 getTargetStreamer().emitDirectiveModuleOddSPReg();
6722 // If this is not the end of the statement, report an error.
6723 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6724 reportParseError("unexpected token, expected end of statement");
6728 return false; // parseDirectiveModule has finished successfully.
6729 } else if (Option == "fp") {
6730 return parseDirectiveModuleFP();
6731 } else if (Option == "softfloat") {
6732 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6734 // Synchronize the ABI Flags information with the FeatureBits information we
6736 getTargetStreamer().updateABIInfo(*this);
6738 // If printing assembly, use the recently updated ABI Flags information.
6739 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6741 getTargetStreamer().emitDirectiveModuleSoftFloat();
6743 // If this is not the end of the statement, report an error.
6744 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6745 reportParseError("unexpected token, expected end of statement");
6749 return false; // parseDirectiveModule has finished successfully.
6750 } else if (Option == "hardfloat") {
6751 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6753 // Synchronize the ABI Flags information with the FeatureBits information we
6755 getTargetStreamer().updateABIInfo(*this);
6757 // If printing assembly, use the recently updated ABI Flags information.
6758 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6760 getTargetStreamer().emitDirectiveModuleHardFloat();
6762 // If this is not the end of the statement, report an error.
6763 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6764 reportParseError("unexpected token, expected end of statement");
6768 return false; // parseDirectiveModule has finished successfully.
6770 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
6774 /// parseDirectiveModuleFP
6778 bool MipsAsmParser::parseDirectiveModuleFP() {
6779 MCAsmParser &Parser = getParser();
6780 MCAsmLexer &Lexer = getLexer();
6782 if (Lexer.isNot(AsmToken::Equal)) {
6783 reportParseError("unexpected token, expected equals sign '='");
6786 Parser.Lex(); // Eat '=' token.
6788 MipsABIFlagsSection::FpABIKind FpABI;
6789 if (!parseFpABIValue(FpABI, ".module"))
6792 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6793 reportParseError("unexpected token, expected end of statement");
6797 // Synchronize the abiflags information with the FeatureBits information we
6799 getTargetStreamer().updateABIInfo(*this);
6801 // If printing assembly, use the recently updated abiflags information.
6802 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6803 // emitted at the end).
6804 getTargetStreamer().emitDirectiveModuleFP();
6806 Parser.Lex(); // Consume the EndOfStatement.
6810 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
6811 StringRef Directive) {
6812 MCAsmParser &Parser = getParser();
6813 MCAsmLexer &Lexer = getLexer();
6814 bool ModuleLevelOptions = Directive == ".module";
6816 if (Lexer.is(AsmToken::Identifier)) {
6817 StringRef Value = Parser.getTok().getString();
6820 if (Value != "xx") {
6821 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6826 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
6830 FpABI = MipsABIFlagsSection::FpABIKind::XX;
6831 if (ModuleLevelOptions) {
6832 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6833 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6835 setFeatureBits(Mips::FeatureFPXX, "fpxx");
6836 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6841 if (Lexer.is(AsmToken::Integer)) {
6842 unsigned Value = Parser.getTok().getIntVal();
6845 if (Value != 32 && Value != 64) {
6846 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6852 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6856 FpABI = MipsABIFlagsSection::FpABIKind::S32;
6857 if (ModuleLevelOptions) {
6858 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6859 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6861 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6862 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6865 FpABI = MipsABIFlagsSection::FpABIKind::S64;
6866 if (ModuleLevelOptions) {
6867 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6868 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6870 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6871 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6881 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6882 // This returns false if this function recognizes the directive
6883 // regardless of whether it is successfully handles or reports an
6884 // error. Otherwise it returns true to give the generic parser a
6885 // chance at recognizing it.
6887 MCAsmParser &Parser = getParser();
6888 StringRef IDVal = DirectiveID.getString();
6890 if (IDVal == ".cpload") {
6891 parseDirectiveCpLoad(DirectiveID.getLoc());
6894 if (IDVal == ".cprestore") {
6895 parseDirectiveCpRestore(DirectiveID.getLoc());
6898 if (IDVal == ".dword") {
6899 parseDataDirective(8, DirectiveID.getLoc());
6902 if (IDVal == ".ent") {
6903 StringRef SymbolName;
6905 if (Parser.parseIdentifier(SymbolName)) {
6906 reportParseError("expected identifier after .ent");
6910 // There's an undocumented extension that allows an integer to
6911 // follow the name of the procedure which AFAICS is ignored by GAS.
6912 // Example: .ent foo,2
6913 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6914 if (getLexer().isNot(AsmToken::Comma)) {
6915 // Even though we accept this undocumented extension for compatibility
6916 // reasons, the additional integer argument does not actually change
6917 // the behaviour of the '.ent' directive, so we would like to discourage
6918 // its use. We do this by not referring to the extended version in
6919 // error messages which are not directly related to its use.
6920 reportParseError("unexpected token, expected end of statement");
6923 Parser.Lex(); // Eat the comma.
6924 const MCExpr *DummyNumber;
6925 int64_t DummyNumberVal;
6926 // If the user was explicitly trying to use the extended version,
6927 // we still give helpful extension-related error messages.
6928 if (Parser.parseExpression(DummyNumber)) {
6929 reportParseError("expected number after comma");
6932 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6933 reportParseError("expected an absolute expression after comma");
6938 // If this is not the end of the statement, report an error.
6939 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6940 reportParseError("unexpected token, expected end of statement");
6944 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6946 getTargetStreamer().emitDirectiveEnt(*Sym);
6948 IsCpRestoreSet = false;
6952 if (IDVal == ".end") {
6953 StringRef SymbolName;
6955 if (Parser.parseIdentifier(SymbolName)) {
6956 reportParseError("expected identifier after .end");
6960 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6961 reportParseError("unexpected token, expected end of statement");
6965 if (CurrentFn == nullptr) {
6966 reportParseError(".end used without .ent");
6970 if ((SymbolName != CurrentFn->getName())) {
6971 reportParseError(".end symbol does not match .ent symbol");
6975 getTargetStreamer().emitDirectiveEnd(SymbolName);
6976 CurrentFn = nullptr;
6977 IsCpRestoreSet = false;
6981 if (IDVal == ".frame") {
6982 // .frame $stack_reg, frame_size_in_bytes, $return_reg
6983 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6984 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6985 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6986 reportParseError("expected stack register");
6990 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6991 if (!StackRegOpnd.isGPRAsmReg()) {
6992 reportParseError(StackRegOpnd.getStartLoc(),
6993 "expected general purpose register");
6996 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6998 if (Parser.getTok().is(AsmToken::Comma))
7001 reportParseError("unexpected token, expected comma");
7005 // Parse the frame size.
7006 const MCExpr *FrameSize;
7007 int64_t FrameSizeVal;
7009 if (Parser.parseExpression(FrameSize)) {
7010 reportParseError("expected frame size value");
7014 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
7015 reportParseError("frame size not an absolute expression");
7019 if (Parser.getTok().is(AsmToken::Comma))
7022 reportParseError("unexpected token, expected comma");
7026 // Parse the return register.
7028 ResTy = parseAnyRegister(TmpReg);
7029 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7030 reportParseError("expected return register");
7034 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7035 if (!ReturnRegOpnd.isGPRAsmReg()) {
7036 reportParseError(ReturnRegOpnd.getStartLoc(),
7037 "expected general purpose register");
7041 // If this is not the end of the statement, report an error.
7042 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7043 reportParseError("unexpected token, expected end of statement");
7047 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
7048 ReturnRegOpnd.getGPR32Reg());
7049 IsCpRestoreSet = false;
7053 if (IDVal == ".set") {
7054 parseDirectiveSet();
7058 if (IDVal == ".mask" || IDVal == ".fmask") {
7059 // .mask bitmask, frame_offset
7060 // bitmask: One bit for each register used.
7061 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
7062 // first register is expected to be saved.
7064 // .mask 0x80000000, -4
7065 // .fmask 0x80000000, -4
7068 // Parse the bitmask
7069 const MCExpr *BitMask;
7072 if (Parser.parseExpression(BitMask)) {
7073 reportParseError("expected bitmask value");
7077 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
7078 reportParseError("bitmask not an absolute expression");
7082 if (Parser.getTok().is(AsmToken::Comma))
7085 reportParseError("unexpected token, expected comma");
7089 // Parse the frame_offset
7090 const MCExpr *FrameOffset;
7091 int64_t FrameOffsetVal;
7093 if (Parser.parseExpression(FrameOffset)) {
7094 reportParseError("expected frame offset value");
7098 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
7099 reportParseError("frame offset not an absolute expression");
7103 // If this is not the end of the statement, report an error.
7104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7105 reportParseError("unexpected token, expected end of statement");
7109 if (IDVal == ".mask")
7110 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
7112 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
7116 if (IDVal == ".nan")
7117 return parseDirectiveNaN();
7119 if (IDVal == ".gpword") {
7120 parseDirectiveGpWord();
7124 if (IDVal == ".gpdword") {
7125 parseDirectiveGpDWord();
7129 if (IDVal == ".dtprelword") {
7130 parseDirectiveDtpRelWord();
7134 if (IDVal == ".dtpreldword") {
7135 parseDirectiveDtpRelDWord();
7139 if (IDVal == ".tprelword") {
7140 parseDirectiveTpRelWord();
7144 if (IDVal == ".tpreldword") {
7145 parseDirectiveTpRelDWord();
7149 if (IDVal == ".word") {
7150 parseDataDirective(4, DirectiveID.getLoc());
7154 if (IDVal == ".hword") {
7155 parseDataDirective(2, DirectiveID.getLoc());
7159 if (IDVal == ".option") {
7160 parseDirectiveOption();
7164 if (IDVal == ".abicalls") {
7165 getTargetStreamer().emitDirectiveAbiCalls();
7166 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7167 Error(Parser.getTok().getLoc(),
7168 "unexpected token, expected end of statement");
7173 if (IDVal == ".cpsetup") {
7174 parseDirectiveCPSetup();
7177 if (IDVal == ".cpreturn") {
7178 parseDirectiveCPReturn();
7181 if (IDVal == ".module") {
7182 parseDirectiveModule();
7185 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
7186 parseInternalDirectiveReallowModule();
7189 if (IDVal == ".insn") {
7190 parseInsnDirective();
7193 if (IDVal == ".sbss") {
7194 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
7197 if (IDVal == ".sdata") {
7198 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
7205 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
7206 // If this is not the end of the statement, report an error.
7207 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7208 reportParseError("unexpected token, expected end of statement");
7212 getTargetStreamer().reallowModuleDirective();
7214 getParser().Lex(); // Eat EndOfStatement token.
7218 extern "C" void LLVMInitializeMipsAsmParser() {
7219 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
7220 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
7221 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
7222 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
7225 #define GET_REGISTER_MATCHER
7226 #define GET_MATCHER_IMPLEMENTATION
7227 #include "MipsGenAsmMatcher.inc"
7229 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
7230 // Find the appropriate table for this asm variant.
7231 const MatchEntry *Start, *End;
7232 switch (VariantID) {
7233 default: llvm_unreachable("invalid variant!");
7234 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
7236 // Search the table.
7237 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
7238 return MnemonicRange.first != MnemonicRange.second;