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/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "MCTargetDesc/MipsBaseInfo.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
26 #include "llvm/MC/MCSectionELF.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ELF.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include "llvm/Support/raw_ostream.h"
40 #define DEBUG_TYPE "mips-asm-parser"
47 class MipsAssemblerOptions {
49 MipsAssemblerOptions(const FeatureBitset &Features_) :
50 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
52 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
53 ATReg = Opts->getATRegIndex();
54 Reorder = Opts->isReorder();
55 Macro = Opts->isMacro();
56 Features = Opts->getFeatures();
59 unsigned getATRegIndex() const { return ATReg; }
60 bool setATRegIndex(unsigned Reg) {
68 bool isReorder() const { return Reorder; }
69 void setReorder() { Reorder = true; }
70 void setNoReorder() { Reorder = false; }
72 bool isMacro() const { return Macro; }
73 void setMacro() { Macro = true; }
74 void setNoMacro() { Macro = false; }
76 const FeatureBitset &getFeatures() const { return Features; }
77 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
79 // Set of features that are either architecture features or referenced
80 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
81 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
82 // The reason we need this mask is explained in the selectArch function.
83 // FIXME: Ideally we would like TableGen to generate this information.
84 static const FeatureBitset AllArchRelatedMask;
90 FeatureBitset Features;
94 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
95 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
96 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
97 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
98 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
99 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
100 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
101 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
102 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
106 class MipsAsmParser : public MCTargetAsmParser {
107 MipsTargetStreamer &getTargetStreamer() {
108 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
109 return static_cast<MipsTargetStreamer &>(TS);
113 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
114 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
115 // nullptr, which indicates that no function is currently
116 // selected. This usually happens after an '.end func'
122 unsigned CpSaveLocation;
123 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
124 bool CpSaveLocationIsRegister;
126 // Print a warning along with its fix-it message at the given range.
127 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
128 SMRange Range, bool ShowColors = true);
130 #define GET_ASSEMBLER_HEADER
131 #include "MipsGenAsmMatcher.inc"
134 checkEarlyTargetMatchPredicate(MCInst &Inst,
135 const OperandVector &Operands) override;
136 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
138 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
139 OperandVector &Operands, MCStreamer &Out,
141 bool MatchingInlineAsm) override;
143 /// Parse a register as used in CFI directives
144 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
146 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
148 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
150 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
151 SMLoc NameLoc, OperandVector &Operands) override;
153 bool ParseDirective(AsmToken DirectiveID) override;
155 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
157 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
158 StringRef Identifier, SMLoc S);
159 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
161 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
162 OperandMatchResultTy parseImm(OperandVector &Operands);
163 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
164 OperandMatchResultTy parseInvNum(OperandVector &Operands);
165 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
166 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
167 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
169 bool searchSymbolAlias(OperandVector &Operands);
171 bool parseOperand(OperandVector &, StringRef Mnemonic);
173 enum MacroExpanderResultTy {
179 // Expands assembly pseudo instructions.
180 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
182 const MCSubtargetInfo *STI);
184 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
185 const MCSubtargetInfo *STI);
187 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
188 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
189 MCStreamer &Out, const MCSubtargetInfo *STI);
191 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
192 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
193 MCStreamer &Out, const MCSubtargetInfo *STI);
195 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196 MCStreamer &Out, const MCSubtargetInfo *STI);
198 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
199 const MCOperand &Offset, bool Is32BitAddress,
200 SMLoc IDLoc, MCStreamer &Out,
201 const MCSubtargetInfo *STI);
203 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
204 const MCSubtargetInfo *STI);
206 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
207 const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
209 void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
210 const MCSubtargetInfo *STI, bool IsImmOpnd);
212 void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
213 const MCSubtargetInfo *STI, bool IsImmOpnd);
215 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
216 const MCSubtargetInfo *STI);
218 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
219 const MCSubtargetInfo *STI);
221 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
222 const MCSubtargetInfo *STI);
224 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
225 const MCSubtargetInfo *STI);
227 bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
228 const MCSubtargetInfo *STI, const bool IsMips64,
231 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
232 MCStreamer &Out, const MCSubtargetInfo *STI);
234 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
235 const MCSubtargetInfo *STI);
237 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
238 const MCSubtargetInfo *STI);
240 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI);
243 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
244 MCStreamer &Out, const MCSubtargetInfo *STI);
245 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
247 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
248 const MCSubtargetInfo *STI);
249 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
250 const MCSubtargetInfo *STI);
252 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
255 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI, bool IsLoad);
258 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI);
261 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI);
264 bool reportParseError(Twine ErrorMsg);
265 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
267 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
269 bool isEvaluated(const MCExpr *Expr);
270 bool parseSetMips0Directive();
271 bool parseSetArchDirective();
272 bool parseSetFeature(uint64_t Feature);
273 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
274 bool parseDirectiveCpLoad(SMLoc Loc);
275 bool parseDirectiveCpRestore(SMLoc Loc);
276 bool parseDirectiveCPSetup();
277 bool parseDirectiveCPReturn();
278 bool parseDirectiveNaN();
279 bool parseDirectiveSet();
280 bool parseDirectiveOption();
281 bool parseInsnDirective();
282 bool parseSSectionDirective(StringRef Section, unsigned Type);
284 bool parseSetAtDirective();
285 bool parseSetNoAtDirective();
286 bool parseSetMacroDirective();
287 bool parseSetNoMacroDirective();
288 bool parseSetMsaDirective();
289 bool parseSetNoMsaDirective();
290 bool parseSetNoDspDirective();
291 bool parseSetReorderDirective();
292 bool parseSetNoReorderDirective();
293 bool parseSetMips16Directive();
294 bool parseSetNoMips16Directive();
295 bool parseSetFpDirective();
296 bool parseSetOddSPRegDirective();
297 bool parseSetNoOddSPRegDirective();
298 bool parseSetPopDirective();
299 bool parseSetPushDirective();
300 bool parseSetSoftFloatDirective();
301 bool parseSetHardFloatDirective();
303 bool parseSetAssignment();
305 bool parseDataDirective(unsigned Size, SMLoc L);
306 bool parseDirectiveGpWord();
307 bool parseDirectiveGpDWord();
308 bool parseDirectiveDtpRelWord();
309 bool parseDirectiveDtpRelDWord();
310 bool parseDirectiveTpRelWord();
311 bool parseDirectiveTpRelDWord();
312 bool parseDirectiveModule();
313 bool parseDirectiveModuleFP();
314 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
315 StringRef Directive);
317 bool parseInternalDirectiveReallowModule();
319 bool eatComma(StringRef ErrorStr);
321 int matchCPURegisterName(StringRef Symbol);
323 int matchHWRegsRegisterName(StringRef Symbol);
325 int matchFPURegisterName(StringRef Name);
327 int matchFCCRegisterName(StringRef Name);
329 int matchACRegisterName(StringRef Name);
331 int matchMSA128RegisterName(StringRef Name);
333 int matchMSA128CtrlRegisterName(StringRef Name);
335 unsigned getReg(int RC, int RegNo);
337 /// Returns the internal register number for the current AT. Also checks if
338 /// the current AT is unavailable (set to $0) and gives an error if it is.
339 /// This should be used in pseudo-instruction expansions which need AT.
340 unsigned getATReg(SMLoc Loc);
342 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
343 const MCSubtargetInfo *STI);
345 // Helper function that checks if the value of a vector index is within the
346 // boundaries of accepted values for each RegisterKind
347 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
348 bool validateMSAIndex(int Val, int RegKind);
350 // Selects a new architecture by updating the FeatureBits with the necessary
351 // info including implied dependencies.
352 // Internally, it clears all the feature bits related to *any* architecture
353 // and selects the new one using the ToggleFeature functionality of the
354 // MCSubtargetInfo object that handles implied dependencies. The reason we
355 // clear all the arch related bits manually is because ToggleFeature only
356 // clears the features that imply the feature being cleared and not the
357 // features implied by the feature being cleared. This is easier to see
359 // --------------------------------------------------
360 // | Feature | Implies |
361 // | -------------------------------------------------|
362 // | FeatureMips1 | None |
363 // | FeatureMips2 | FeatureMips1 |
364 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
365 // | FeatureMips4 | FeatureMips3 |
367 // --------------------------------------------------
369 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
370 // FeatureMipsGP64 | FeatureMips1)
371 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
372 void selectArch(StringRef ArchFeature) {
373 MCSubtargetInfo &STI = copySTI();
374 FeatureBitset FeatureBits = STI.getFeatureBits();
375 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
376 STI.setFeatureBits(FeatureBits);
377 setAvailableFeatures(
378 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
379 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
382 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
383 if (!(getSTI().getFeatureBits()[Feature])) {
384 MCSubtargetInfo &STI = copySTI();
385 setAvailableFeatures(
386 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
387 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
391 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
392 if (getSTI().getFeatureBits()[Feature]) {
393 MCSubtargetInfo &STI = copySTI();
394 setAvailableFeatures(
395 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
396 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
400 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
401 setFeatureBits(Feature, FeatureString);
402 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
405 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
406 clearFeatureBits(Feature, FeatureString);
407 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
411 enum MipsMatchResultTy {
412 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
413 Match_RequiresDifferentOperands,
414 Match_RequiresNoZeroRegister,
415 Match_RequiresSameSrcAndDst,
416 Match_NoFCCRegisterForCurrentISA,
417 Match_NonZeroOperandForSync,
418 #define GET_OPERAND_DIAGNOSTIC_TYPES
419 #include "MipsGenAsmMatcher.inc"
420 #undef GET_OPERAND_DIAGNOSTIC_TYPES
423 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
424 const MCInstrInfo &MII, const MCTargetOptions &Options)
425 : MCTargetAsmParser(Options, sti),
426 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
427 sti.getCPU(), Options)) {
428 MCAsmParserExtension::Initialize(parser);
430 parser.addAliasForDirective(".asciiz", ".asciz");
432 // Initialize the set of available features.
433 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
435 // Remember the initial assembler options. The user can not modify these.
436 AssemblerOptions.push_back(
437 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
439 // Create an assembler options environment for the user to modify.
440 AssemblerOptions.push_back(
441 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
443 getTargetStreamer().updateABIInfo(*this);
445 if (!isABI_O32() && !useOddSPReg() != 0)
446 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
450 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
452 IsCpRestoreSet = false;
453 CpRestoreOffset = -1;
455 const Triple &TheTriple = sti.getTargetTriple();
456 if ((TheTriple.getArch() == Triple::mips) ||
457 (TheTriple.getArch() == Triple::mips64))
458 IsLittleEndian = false;
460 IsLittleEndian = true;
463 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
464 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
466 bool isGP64bit() const {
467 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
469 bool isFP64bit() const {
470 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
472 const MipsABIInfo &getABI() const { return ABI; }
473 bool isABI_N32() const { return ABI.IsN32(); }
474 bool isABI_N64() const { return ABI.IsN64(); }
475 bool isABI_O32() const { return ABI.IsO32(); }
476 bool isABI_FPXX() const {
477 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
480 bool useOddSPReg() const {
481 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
484 bool inMicroMipsMode() const {
485 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
487 bool hasMips1() const {
488 return getSTI().getFeatureBits()[Mips::FeatureMips1];
490 bool hasMips2() const {
491 return getSTI().getFeatureBits()[Mips::FeatureMips2];
493 bool hasMips3() const {
494 return getSTI().getFeatureBits()[Mips::FeatureMips3];
496 bool hasMips4() const {
497 return getSTI().getFeatureBits()[Mips::FeatureMips4];
499 bool hasMips5() const {
500 return getSTI().getFeatureBits()[Mips::FeatureMips5];
502 bool hasMips32() const {
503 return getSTI().getFeatureBits()[Mips::FeatureMips32];
505 bool hasMips64() const {
506 return getSTI().getFeatureBits()[Mips::FeatureMips64];
508 bool hasMips32r2() const {
509 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
511 bool hasMips64r2() const {
512 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
514 bool hasMips32r3() const {
515 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
517 bool hasMips64r3() const {
518 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
520 bool hasMips32r5() const {
521 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
523 bool hasMips64r5() const {
524 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
526 bool hasMips32r6() const {
527 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
529 bool hasMips64r6() const {
530 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
533 bool hasDSP() const {
534 return getSTI().getFeatureBits()[Mips::FeatureDSP];
536 bool hasDSPR2() const {
537 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
539 bool hasDSPR3() const {
540 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
542 bool hasMSA() const {
543 return getSTI().getFeatureBits()[Mips::FeatureMSA];
545 bool hasCnMips() const {
546 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
553 bool inMips16Mode() const {
554 return getSTI().getFeatureBits()[Mips::FeatureMips16];
557 bool useTraps() const {
558 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
561 bool useSoftFloat() const {
562 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
565 /// Warn if RegIndex is the same as the current AT.
566 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
568 void warnIfNoMacro(SMLoc Loc);
570 bool isLittle() const { return IsLittleEndian; }
572 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
573 AsmToken::TokenKind OperatorToken,
574 MCContext &Ctx) override {
575 switch(OperatorToken) {
577 llvm_unreachable("Unknown token");
579 case AsmToken::PercentCall16:
580 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
581 case AsmToken::PercentCall_Hi:
582 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
583 case AsmToken::PercentCall_Lo:
584 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
585 case AsmToken::PercentDtprel_Hi:
586 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
587 case AsmToken::PercentDtprel_Lo:
588 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
589 case AsmToken::PercentGot:
590 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
591 case AsmToken::PercentGot_Disp:
592 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
593 case AsmToken::PercentGot_Hi:
594 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
595 case AsmToken::PercentGot_Lo:
596 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
597 case AsmToken::PercentGot_Ofst:
598 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
599 case AsmToken::PercentGot_Page:
600 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
601 case AsmToken::PercentGottprel:
602 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
603 case AsmToken::PercentGp_Rel:
604 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
605 case AsmToken::PercentHi:
606 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
607 case AsmToken::PercentHigher:
608 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
609 case AsmToken::PercentHighest:
610 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
611 case AsmToken::PercentLo:
612 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
613 case AsmToken::PercentNeg:
614 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
615 case AsmToken::PercentPcrel_Hi:
616 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
617 case AsmToken::PercentPcrel_Lo:
618 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
619 case AsmToken::PercentTlsgd:
620 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
621 case AsmToken::PercentTlsldm:
622 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
623 case AsmToken::PercentTprel_Hi:
624 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
625 case AsmToken::PercentTprel_Lo:
626 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
634 /// MipsOperand - Instances of this class represent a parsed Mips machine
636 class MipsOperand : public MCParsedAsmOperand {
638 /// Broad categories of register classes
639 /// The exact class is finalized by the render method.
641 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
642 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
644 RegKind_FCC = 4, /// FCC
645 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
646 RegKind_MSACtrl = 16, /// MSA control registers
647 RegKind_COP2 = 32, /// COP2
648 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
650 RegKind_CCR = 128, /// CCR
651 RegKind_HWRegs = 256, /// HWRegs
652 RegKind_COP3 = 512, /// COP3
653 RegKind_COP0 = 1024, /// COP0
654 /// Potentially any (e.g. $1)
655 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
656 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
657 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
662 k_Immediate, /// An immediate (possibly involving symbol references)
663 k_Memory, /// Base + Offset Memory Address
664 k_RegisterIndex, /// A register index in one or more RegKind.
665 k_Token, /// A simple token
666 k_RegList, /// A physical register list
667 k_RegPair /// A pair of physical register
671 MipsOperand(KindTy K, MipsAsmParser &Parser)
672 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
675 /// For diagnostics, and checking the assembler temporary
676 MipsAsmParser &AsmParser;
684 unsigned Index; /// Index into the register class
685 RegKind Kind; /// Bitfield of the kinds it could possibly be
686 struct Token Tok; /// The input token this operand originated from.
687 const MCRegisterInfo *RegInfo;
700 SmallVector<unsigned, 10> *List;
705 struct RegIdxOp RegIdx;
708 struct RegListOp RegList;
711 SMLoc StartLoc, EndLoc;
713 /// Internal constructor for register kinds
714 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
716 const MCRegisterInfo *RegInfo,
718 MipsAsmParser &Parser) {
719 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
720 Op->RegIdx.Index = Index;
721 Op->RegIdx.RegInfo = RegInfo;
722 Op->RegIdx.Kind = RegKind;
723 Op->RegIdx.Tok.Data = Str.data();
724 Op->RegIdx.Tok.Length = Str.size();
731 /// Coerce the register to GPR32 and return the real register for the current
733 unsigned getGPR32Reg() const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
735 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
736 unsigned ClassID = Mips::GPR32RegClassID;
737 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
740 /// Coerce the register to GPR32 and return the real register for the current
742 unsigned getGPRMM16Reg() const {
743 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
744 unsigned ClassID = Mips::GPR32RegClassID;
745 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
748 /// Coerce the register to GPR64 and return the real register for the current
750 unsigned getGPR64Reg() const {
751 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
752 unsigned ClassID = Mips::GPR64RegClassID;
753 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
757 /// Coerce the register to AFGR64 and return the real register for the current
759 unsigned getAFGR64Reg() const {
760 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
761 if (RegIdx.Index % 2 != 0)
762 AsmParser.Warning(StartLoc, "Float register should be even.");
763 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
764 .getRegister(RegIdx.Index / 2);
767 /// Coerce the register to FGR64 and return the real register for the current
769 unsigned getFGR64Reg() const {
770 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
771 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
772 .getRegister(RegIdx.Index);
775 /// Coerce the register to FGR32 and return the real register for the current
777 unsigned getFGR32Reg() const {
778 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
779 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
780 .getRegister(RegIdx.Index);
783 /// Coerce the register to FGRH32 and return the real register for the current
785 unsigned getFGRH32Reg() const {
786 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
787 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
788 .getRegister(RegIdx.Index);
791 /// Coerce the register to FCC and return the real register for the current
793 unsigned getFCCReg() const {
794 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
795 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
796 .getRegister(RegIdx.Index);
799 /// Coerce the register to MSA128 and return the real register for the current
801 unsigned getMSA128Reg() const {
802 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
803 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
805 unsigned ClassID = Mips::MSA128BRegClassID;
806 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
809 /// Coerce the register to MSACtrl and return the real register for the
811 unsigned getMSACtrlReg() const {
812 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
813 unsigned ClassID = Mips::MSACtrlRegClassID;
814 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
817 /// Coerce the register to COP0 and return the real register for the
819 unsigned getCOP0Reg() const {
820 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
821 unsigned ClassID = Mips::COP0RegClassID;
822 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
825 /// Coerce the register to COP2 and return the real register for the
827 unsigned getCOP2Reg() const {
828 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
829 unsigned ClassID = Mips::COP2RegClassID;
830 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
833 /// Coerce the register to COP3 and return the real register for the
835 unsigned getCOP3Reg() const {
836 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
837 unsigned ClassID = Mips::COP3RegClassID;
838 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
841 /// Coerce the register to ACC64DSP and return the real register for the
843 unsigned getACC64DSPReg() const {
844 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
845 unsigned ClassID = Mips::ACC64DSPRegClassID;
846 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
849 /// Coerce the register to HI32DSP and return the real register for the
851 unsigned getHI32DSPReg() const {
852 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
853 unsigned ClassID = Mips::HI32DSPRegClassID;
854 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
857 /// Coerce the register to LO32DSP and return the real register for the
859 unsigned getLO32DSPReg() const {
860 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
861 unsigned ClassID = Mips::LO32DSPRegClassID;
862 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
865 /// Coerce the register to CCR and return the real register for the
867 unsigned getCCRReg() const {
868 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
869 unsigned ClassID = Mips::CCRRegClassID;
870 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
873 /// Coerce the register to HWRegs and return the real register for the
875 unsigned getHWRegsReg() const {
876 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
877 unsigned ClassID = Mips::HWRegsRegClassID;
878 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
882 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
883 // Add as immediate when possible. Null MCExpr = 0.
885 Inst.addOperand(MCOperand::createImm(0));
886 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
887 Inst.addOperand(MCOperand::createImm(CE->getValue()));
889 Inst.addOperand(MCOperand::createExpr(Expr));
892 void addRegOperands(MCInst &Inst, unsigned N) const {
893 llvm_unreachable("Use a custom parser instead");
896 /// Render the operand to an MCInst as a GPR32
897 /// Asserts if the wrong number of operands are requested, or the operand
898 /// is not a k_RegisterIndex compatible with RegKind_GPR
899 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
900 assert(N == 1 && "Invalid number of operands!");
901 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
904 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
905 assert(N == 1 && "Invalid number of operands!");
906 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
909 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
910 assert(N == 1 && "Invalid number of operands!");
911 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
914 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
915 assert(N == 1 && "Invalid number of operands!");
916 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
919 /// Render the operand to an MCInst as a GPR64
920 /// Asserts if the wrong number of operands are requested, or the operand
921 /// is not a k_RegisterIndex compatible with RegKind_GPR
922 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
923 assert(N == 1 && "Invalid number of operands!");
924 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
927 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
928 assert(N == 1 && "Invalid number of operands!");
929 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
932 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
933 assert(N == 1 && "Invalid number of operands!");
934 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
937 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
938 assert(N == 1 && "Invalid number of operands!");
939 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
940 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
941 // FIXME: This should propagate failure up to parseStatement.
942 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
943 AsmParser.getParser().printError(
944 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
948 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
949 assert(N == 1 && "Invalid number of operands!");
950 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
953 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
954 assert(N == 1 && "Invalid number of operands!");
955 Inst.addOperand(MCOperand::createReg(getFCCReg()));
958 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
959 assert(N == 1 && "Invalid number of operands!");
960 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
963 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
964 assert(N == 1 && "Invalid number of operands!");
965 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
968 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
969 assert(N == 1 && "Invalid number of operands!");
970 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
973 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
974 assert(N == 1 && "Invalid number of operands!");
975 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
978 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
979 assert(N == 1 && "Invalid number of operands!");
980 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
983 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
984 assert(N == 1 && "Invalid number of operands!");
985 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
988 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
989 assert(N == 1 && "Invalid number of operands!");
990 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
993 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
994 assert(N == 1 && "Invalid number of operands!");
995 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
998 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
999 assert(N == 1 && "Invalid number of operands!");
1000 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1003 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1004 assert(N == 1 && "Invalid number of operands!");
1005 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1008 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1009 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1010 assert(N == 1 && "Invalid number of operands!");
1011 uint64_t Imm = getConstantImm() - Offset;
1012 Imm &= (1ULL << Bits) - 1;
1014 Imm += AdjustOffset;
1015 Inst.addOperand(MCOperand::createImm(Imm));
1018 template <unsigned Bits>
1019 void addSImmOperands(MCInst &Inst, unsigned N) const {
1020 if (isImm() && !isConstantImm()) {
1021 addExpr(Inst, getImm());
1024 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1027 template <unsigned Bits>
1028 void addUImmOperands(MCInst &Inst, unsigned N) const {
1029 if (isImm() && !isConstantImm()) {
1030 addExpr(Inst, getImm());
1033 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1036 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1037 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1038 assert(N == 1 && "Invalid number of operands!");
1039 int64_t Imm = getConstantImm() - Offset;
1040 Imm = SignExtend64<Bits>(Imm);
1042 Imm += AdjustOffset;
1043 Inst.addOperand(MCOperand::createImm(Imm));
1046 void addImmOperands(MCInst &Inst, unsigned N) const {
1047 assert(N == 1 && "Invalid number of operands!");
1048 const MCExpr *Expr = getImm();
1049 addExpr(Inst, Expr);
1052 void addMemOperands(MCInst &Inst, unsigned N) const {
1053 assert(N == 2 && "Invalid number of operands!");
1055 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1056 ? getMemBase()->getGPR64Reg()
1057 : getMemBase()->getGPR32Reg()));
1059 const MCExpr *Expr = getMemOff();
1060 addExpr(Inst, Expr);
1063 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1064 assert(N == 2 && "Invalid number of operands!");
1066 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1068 const MCExpr *Expr = getMemOff();
1069 addExpr(Inst, Expr);
1072 void addRegListOperands(MCInst &Inst, unsigned N) const {
1073 assert(N == 1 && "Invalid number of operands!");
1075 for (auto RegNo : getRegList())
1076 Inst.addOperand(MCOperand::createReg(RegNo));
1079 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1080 assert(N == 2 && "Invalid number of operands!");
1081 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1082 unsigned RegNo = getRegPair();
1083 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1084 Inst.addOperand(MCOperand::createReg(
1085 RegIdx.RegInfo->getRegClass(
1086 AsmParser.getABI().AreGprs64bit()
1087 ? Mips::GPR64RegClassID
1088 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1089 Inst.addOperand(MCOperand::createReg(
1090 RegIdx.RegInfo->getRegClass(
1091 AsmParser.getABI().AreGprs64bit()
1092 ? Mips::GPR64RegClassID
1093 : Mips::GPR32RegClassID).getRegister(RegNo)));
1096 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1097 assert(N == 2 && "Invalid number of operands!");
1098 for (auto RegNo : getRegList())
1099 Inst.addOperand(MCOperand::createReg(RegNo));
1102 bool isReg() const override {
1103 // As a special case until we sort out the definition of div/divu, accept
1104 // $0/$zero here so that MCK_ZERO works correctly.
1105 return isGPRAsmReg() && RegIdx.Index == 0;
1107 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1108 bool isImm() const override { return Kind == k_Immediate; }
1109 bool isConstantImm() const {
1111 return isImm() && getImm()->evaluateAsAbsolute(Res);
1113 bool isConstantImmz() const {
1114 return isConstantImm() && getConstantImm() == 0;
1116 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1117 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1119 template <unsigned Bits> bool isSImm() const {
1120 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1122 template <unsigned Bits> bool isUImm() const {
1123 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1125 template <unsigned Bits> bool isAnyImm() const {
1126 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1127 isUInt<Bits>(getConstantImm()))
1130 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1131 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1133 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1134 return isConstantImm() && getConstantImm() >= Bottom &&
1135 getConstantImm() <= Top;
1137 bool isToken() const override {
1138 // Note: It's not possible to pretend that other operand kinds are tokens.
1139 // The matcher emitter checks tokens first.
1140 return Kind == k_Token;
1142 bool isMem() const override { return Kind == k_Memory; }
1143 bool isConstantMemOff() const {
1144 return isMem() && isa<MCConstantExpr>(getMemOff());
1146 // Allow relocation operators.
1147 // FIXME: This predicate and others need to look through binary expressions
1148 // and determine whether a Value is a constant or not.
1149 template <unsigned Bits, unsigned ShiftAmount = 0>
1150 bool isMemWithSimmOffset() const {
1153 if (!getMemBase()->isGPRAsmReg())
1155 if (isa<MCTargetExpr>(getMemOff()) ||
1156 (isConstantMemOff() &&
1157 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1160 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1161 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1163 bool isMemWithGRPMM16Base() const {
1164 return isMem() && getMemBase()->isMM16AsmReg();
1166 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1167 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1168 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1170 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1171 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1172 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1173 && (getMemBase()->getGPR32Reg() == Mips::SP);
1175 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1176 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1177 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1178 && (getMemBase()->getGPR32Reg() == Mips::GP);
1180 template <unsigned Bits, unsigned ShiftLeftAmount>
1181 bool isScaledUImm() const {
1182 return isConstantImm() &&
1183 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1185 template <unsigned Bits, unsigned ShiftLeftAmount>
1186 bool isScaledSImm() const {
1187 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1189 // Operand can also be a symbol or symbol plus offset in case of relocations.
1190 if (Kind != k_Immediate)
1193 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1194 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1196 bool isRegList16() const {
1200 int Size = RegList.List->size();
1201 if (Size < 2 || Size > 5)
1204 unsigned R0 = RegList.List->front();
1205 unsigned R1 = RegList.List->back();
1206 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1207 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1210 int PrevReg = *RegList.List->begin();
1211 for (int i = 1; i < Size - 1; i++) {
1212 int Reg = (*(RegList.List))[i];
1213 if ( Reg != PrevReg + 1)
1220 bool isInvNum() const { return Kind == k_Immediate; }
1221 bool isLSAImm() const {
1222 if (!isConstantImm())
1224 int64_t Val = getConstantImm();
1225 return 1 <= Val && Val <= 4;
1227 bool isRegList() const { return Kind == k_RegList; }
1228 bool isMovePRegPair() const {
1229 if (Kind != k_RegList || RegList.List->size() != 2)
1232 unsigned R0 = RegList.List->front();
1233 unsigned R1 = RegList.List->back();
1235 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1236 (R0 == Mips::A1 && R1 == Mips::A3) ||
1237 (R0 == Mips::A2 && R1 == Mips::A3) ||
1238 (R0 == Mips::A0 && R1 == Mips::S5) ||
1239 (R0 == Mips::A0 && R1 == Mips::S6) ||
1240 (R0 == Mips::A0 && R1 == Mips::A1) ||
1241 (R0 == Mips::A0 && R1 == Mips::A2) ||
1242 (R0 == Mips::A0 && R1 == Mips::A3) ||
1243 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1244 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1245 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1246 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1247 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1248 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1249 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1250 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1256 StringRef getToken() const {
1257 assert(Kind == k_Token && "Invalid access!");
1258 return StringRef(Tok.Data, Tok.Length);
1260 bool isRegPair() const {
1261 return Kind == k_RegPair && RegIdx.Index <= 30;
1264 unsigned getReg() const override {
1265 // As a special case until we sort out the definition of div/divu, accept
1266 // $0/$zero here so that MCK_ZERO works correctly.
1267 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1268 RegIdx.Kind & RegKind_GPR)
1269 return getGPR32Reg(); // FIXME: GPR64 too
1271 llvm_unreachable("Invalid access!");
1275 const MCExpr *getImm() const {
1276 assert((Kind == k_Immediate) && "Invalid access!");
1280 int64_t getConstantImm() const {
1281 const MCExpr *Val = getImm();
1283 (void)Val->evaluateAsAbsolute(Value);
1287 MipsOperand *getMemBase() const {
1288 assert((Kind == k_Memory) && "Invalid access!");
1292 const MCExpr *getMemOff() const {
1293 assert((Kind == k_Memory) && "Invalid access!");
1297 int64_t getConstantMemOff() const {
1298 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1301 const SmallVectorImpl<unsigned> &getRegList() const {
1302 assert((Kind == k_RegList) && "Invalid access!");
1303 return *(RegList.List);
1306 unsigned getRegPair() const {
1307 assert((Kind == k_RegPair) && "Invalid access!");
1308 return RegIdx.Index;
1311 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1312 MipsAsmParser &Parser) {
1313 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1314 Op->Tok.Data = Str.data();
1315 Op->Tok.Length = Str.size();
1321 /// Create a numeric register (e.g. $1). The exact register remains
1322 /// unresolved until an instruction successfully matches
1323 static std::unique_ptr<MipsOperand>
1324 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1325 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1326 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1327 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1330 /// Create a register that is definitely a GPR.
1331 /// This is typically only used for named registers such as $gp.
1332 static std::unique_ptr<MipsOperand>
1333 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1334 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1335 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1338 /// Create a register that is definitely a FGR.
1339 /// This is typically only used for named registers such as $f0.
1340 static std::unique_ptr<MipsOperand>
1341 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1342 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1343 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1346 /// Create a register that is definitely a HWReg.
1347 /// This is typically only used for named registers such as $hwr_cpunum.
1348 static std::unique_ptr<MipsOperand>
1349 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1350 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1351 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1354 /// Create a register that is definitely an FCC.
1355 /// This is typically only used for named registers such as $fcc0.
1356 static std::unique_ptr<MipsOperand>
1357 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1358 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1359 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1362 /// Create a register that is definitely an ACC.
1363 /// This is typically only used for named registers such as $ac0.
1364 static std::unique_ptr<MipsOperand>
1365 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1366 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1367 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1370 /// Create a register that is definitely an MSA128.
1371 /// This is typically only used for named registers such as $w0.
1372 static std::unique_ptr<MipsOperand>
1373 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1374 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1375 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1378 /// Create a register that is definitely an MSACtrl.
1379 /// This is typically only used for named registers such as $msaaccess.
1380 static std::unique_ptr<MipsOperand>
1381 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1382 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1383 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1386 static std::unique_ptr<MipsOperand>
1387 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1388 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1395 static std::unique_ptr<MipsOperand>
1396 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1397 SMLoc E, MipsAsmParser &Parser) {
1398 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1399 Op->Mem.Base = Base.release();
1406 static std::unique_ptr<MipsOperand>
1407 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1408 MipsAsmParser &Parser) {
1409 assert (Regs.size() > 0 && "Empty list not allowed");
1411 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1412 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1413 Op->StartLoc = StartLoc;
1414 Op->EndLoc = EndLoc;
1418 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1420 MipsAsmParser &Parser) {
1421 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1422 Op->RegIdx.Index = MOP.RegIdx.Index;
1423 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1424 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1430 bool isGPRAsmReg() const {
1431 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1433 bool isMM16AsmReg() const {
1434 if (!(isRegIdx() && RegIdx.Kind))
1436 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1437 || RegIdx.Index == 16 || RegIdx.Index == 17);
1439 bool isMM16AsmRegZero() const {
1440 if (!(isRegIdx() && RegIdx.Kind))
1442 return (RegIdx.Index == 0 ||
1443 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1444 RegIdx.Index == 17);
1446 bool isMM16AsmRegMoveP() const {
1447 if (!(isRegIdx() && RegIdx.Kind))
1449 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1450 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1452 bool isFGRAsmReg() const {
1453 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1454 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1456 bool isHWRegsAsmReg() const {
1457 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1459 bool isCCRAsmReg() const {
1460 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1462 bool isFCCAsmReg() const {
1463 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1465 return RegIdx.Index <= 7;
1467 bool isACCAsmReg() const {
1468 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1470 bool isCOP0AsmReg() const {
1471 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1473 bool isCOP2AsmReg() const {
1474 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1476 bool isCOP3AsmReg() const {
1477 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1479 bool isMSA128AsmReg() const {
1480 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1482 bool isMSACtrlAsmReg() const {
1483 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1486 /// getStartLoc - Get the location of the first token of this operand.
1487 SMLoc getStartLoc() const override { return StartLoc; }
1488 /// getEndLoc - Get the location of the last token of this operand.
1489 SMLoc getEndLoc() const override { return EndLoc; }
1491 virtual ~MipsOperand() {
1499 delete RegList.List;
1500 case k_RegisterIndex:
1507 void print(raw_ostream &OS) const override {
1516 Mem.Base->print(OS);
1521 case k_RegisterIndex:
1522 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1523 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1530 for (auto Reg : (*RegList.List))
1535 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1540 bool isValidForTie(const MipsOperand &Other) const {
1541 if (Kind != Other.Kind)
1546 llvm_unreachable("Unexpected kind");
1548 case k_RegisterIndex: {
1549 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1550 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1551 return Token == OtherToken;
1555 }; // class MipsOperand
1559 extern const MCInstrDesc MipsInsts[];
1561 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1562 return MipsInsts[Opcode];
1565 static bool hasShortDelaySlot(unsigned Opcode) {
1568 case Mips::JALRS_MM:
1569 case Mips::JALRS16_MM:
1570 case Mips::BGEZALS_MM:
1571 case Mips::BLTZALS_MM:
1578 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1579 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1580 return &SRExpr->getSymbol();
1583 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1584 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1585 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1596 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1597 return getSingleMCSymbol(UExpr->getSubExpr());
1602 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1603 if (isa<MCSymbolRefExpr>(Expr))
1606 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1607 return countMCSymbolRefExpr(BExpr->getLHS()) +
1608 countMCSymbolRefExpr(BExpr->getRHS());
1610 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1611 return countMCSymbolRefExpr(UExpr->getSubExpr());
1616 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1618 const MCSubtargetInfo *STI) {
1619 MipsTargetStreamer &TOut = getTargetStreamer();
1620 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1621 bool ExpandedJalSym = false;
1625 if (MCID.isBranch() || MCID.isCall()) {
1626 const unsigned Opcode = Inst.getOpcode();
1636 assert(hasCnMips() && "instruction only valid for octeon cpus");
1643 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1644 Offset = Inst.getOperand(2);
1645 if (!Offset.isImm())
1646 break; // We'll deal with this situation later on when applying fixups.
1647 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1648 return Error(IDLoc, "branch target out of range");
1649 if (OffsetToAlignment(Offset.getImm(),
1650 1LL << (inMicroMipsMode() ? 1 : 2)))
1651 return Error(IDLoc, "branch to misaligned address");
1665 case Mips::BGEZAL_MM:
1666 case Mips::BLTZAL_MM:
1669 case Mips::BC1EQZC_MMR6:
1670 case Mips::BC1NEZC_MMR6:
1671 case Mips::BC2EQZC_MMR6:
1672 case Mips::BC2NEZC_MMR6:
1673 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1674 Offset = Inst.getOperand(1);
1675 if (!Offset.isImm())
1676 break; // We'll deal with this situation later on when applying fixups.
1677 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1678 return Error(IDLoc, "branch target out of range");
1679 if (OffsetToAlignment(Offset.getImm(),
1680 1LL << (inMicroMipsMode() ? 1 : 2)))
1681 return Error(IDLoc, "branch to misaligned address");
1683 case Mips::BGEC: case Mips::BGEC_MMR6:
1684 case Mips::BLTC: case Mips::BLTC_MMR6:
1685 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1686 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1687 case Mips::BEQC: case Mips::BEQC_MMR6:
1688 case Mips::BNEC: case Mips::BNEC_MMR6:
1689 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1690 Offset = Inst.getOperand(2);
1691 if (!Offset.isImm())
1692 break; // We'll deal with this situation later on when applying fixups.
1693 if (!isIntN(18, Offset.getImm()))
1694 return Error(IDLoc, "branch target out of range");
1695 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1696 return Error(IDLoc, "branch to misaligned address");
1698 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1699 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1700 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1701 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1702 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1703 Offset = Inst.getOperand(1);
1704 if (!Offset.isImm())
1705 break; // We'll deal with this situation later on when applying fixups.
1706 if (!isIntN(18, Offset.getImm()))
1707 return Error(IDLoc, "branch target out of range");
1708 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1709 return Error(IDLoc, "branch to misaligned address");
1711 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1712 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1713 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1714 Offset = Inst.getOperand(1);
1715 if (!Offset.isImm())
1716 break; // We'll deal with this situation later on when applying fixups.
1717 if (!isIntN(23, Offset.getImm()))
1718 return Error(IDLoc, "branch target out of range");
1719 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1720 return Error(IDLoc, "branch to misaligned address");
1722 case Mips::BEQZ16_MM:
1723 case Mips::BEQZC16_MMR6:
1724 case Mips::BNEZ16_MM:
1725 case Mips::BNEZC16_MMR6:
1726 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1727 Offset = Inst.getOperand(1);
1728 if (!Offset.isImm())
1729 break; // We'll deal with this situation later on when applying fixups.
1730 if (!isInt<8>(Offset.getImm()))
1731 return Error(IDLoc, "branch target out of range");
1732 if (OffsetToAlignment(Offset.getImm(), 2LL))
1733 return Error(IDLoc, "branch to misaligned address");
1738 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1739 // We still accept it but it is a normal nop.
1740 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1741 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1742 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1747 const unsigned Opcode = Inst.getOpcode();
1759 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1760 // The offset is handled above
1761 Opnd = Inst.getOperand(1);
1763 return Error(IDLoc, "expected immediate operand kind");
1764 Imm = Opnd.getImm();
1765 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1766 Opcode == Mips::BBIT1 ? 63 : 31))
1767 return Error(IDLoc, "immediate operand value out of range");
1769 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1771 Inst.getOperand(1).setImm(Imm - 32);
1777 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1778 Opnd = Inst.getOperand(2);
1780 return Error(IDLoc, "expected immediate operand kind");
1781 Imm = Opnd.getImm();
1782 if (!isInt<10>(Imm))
1783 return Error(IDLoc, "immediate operand value out of range");
1788 // For PIC code convert unconditional jump to unconditional branch.
1789 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1792 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1793 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1794 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1795 BInst.addOperand(Inst.getOperand(0));
1799 // This expansion is not in a function called by tryExpandInstruction()
1800 // because the pseudo-instruction doesn't have a distinct opcode.
1801 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1803 warnIfNoMacro(IDLoc);
1805 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1807 // We can do this expansion if there's only 1 symbol in the argument
1809 if (countMCSymbolRefExpr(JalExpr) > 1)
1810 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1812 // FIXME: This is checking the expression can be handled by the later stages
1813 // of the assembler. We ought to leave it to those later stages.
1814 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1816 // FIXME: Add support for label+offset operands (currently causes an error).
1817 // FIXME: Add support for forward-declared local symbols.
1818 // FIXME: Add expansion for when the LargeGOT option is enabled.
1819 if (JalSym->isInSection() || JalSym->isTemporary() ||
1820 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
1822 // If it's a local symbol and the O32 ABI is being used, we expand to:
1824 // R_(MICRO)MIPS_GOT16 label
1825 // addiu $25, $25, 0
1826 // R_(MICRO)MIPS_LO16 label
1828 const MCExpr *Got16RelocExpr =
1829 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
1830 const MCExpr *Lo16RelocExpr =
1831 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
1833 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
1834 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
1835 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1836 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
1837 } else if (isABI_N32() || isABI_N64()) {
1838 // If it's a local symbol and the N32/N64 ABIs are being used,
1840 // lw/ld $25, 0($gp)
1841 // R_(MICRO)MIPS_GOT_DISP label
1843 const MCExpr *GotDispRelocExpr =
1844 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
1846 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
1847 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
1851 // If it's an external/weak symbol, we expand to:
1852 // lw/ld $25, 0($gp)
1853 // R_(MICRO)MIPS_CALL16 label
1855 const MCExpr *Call16RelocExpr =
1856 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
1858 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1859 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
1863 if (IsCpRestoreSet && inMicroMipsMode())
1864 JalrInst.setOpcode(Mips::JALRS_MM);
1866 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1867 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1868 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1870 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1871 // This relocation is supposed to be an optimization hint for the linker
1872 // and is not necessary for correctness.
1875 ExpandedJalSym = true;
1878 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
1879 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
1880 // Check the offset of memory operand, if it is a symbol
1881 // reference or immediate we may have to expand instructions.
1882 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1883 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1884 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1885 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1886 MCOperand &Op = Inst.getOperand(i);
1888 int MemOffset = Op.getImm();
1889 if (MemOffset < -32768 || MemOffset > 32767) {
1890 // Offset can't exceed 16bit value.
1891 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
1892 return getParser().hasPendingError();
1894 } else if (Op.isExpr()) {
1895 const MCExpr *Expr = Op.getExpr();
1896 if (Expr->getKind() == MCExpr::SymbolRef) {
1897 const MCSymbolRefExpr *SR =
1898 static_cast<const MCSymbolRefExpr *>(Expr);
1899 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1901 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1902 return getParser().hasPendingError();
1904 } else if (!isEvaluated(Expr)) {
1905 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1906 return getParser().hasPendingError();
1913 if (inMicroMipsMode()) {
1914 if (MCID.mayLoad()) {
1915 // Try to create 16-bit GP relative load instruction.
1916 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1917 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1918 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1919 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1920 MCOperand &Op = Inst.getOperand(i);
1922 int MemOffset = Op.getImm();
1923 MCOperand &DstReg = Inst.getOperand(0);
1924 MCOperand &BaseReg = Inst.getOperand(1);
1925 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1926 getContext().getRegisterInfo()->getRegClass(
1927 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1928 (BaseReg.getReg() == Mips::GP ||
1929 BaseReg.getReg() == Mips::GP_64)) {
1931 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1940 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1945 switch (Inst.getOpcode()) {
1948 case Mips::ADDIUSP_MM:
1949 Opnd = Inst.getOperand(0);
1951 return Error(IDLoc, "expected immediate operand kind");
1952 Imm = Opnd.getImm();
1953 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1955 return Error(IDLoc, "immediate operand value out of range");
1957 case Mips::SLL16_MM:
1958 case Mips::SRL16_MM:
1959 Opnd = Inst.getOperand(2);
1961 return Error(IDLoc, "expected immediate operand kind");
1962 Imm = Opnd.getImm();
1963 if (Imm < 1 || Imm > 8)
1964 return Error(IDLoc, "immediate operand value out of range");
1967 Opnd = Inst.getOperand(1);
1969 return Error(IDLoc, "expected immediate operand kind");
1970 Imm = Opnd.getImm();
1971 if (Imm < -1 || Imm > 126)
1972 return Error(IDLoc, "immediate operand value out of range");
1974 case Mips::ADDIUR2_MM:
1975 Opnd = Inst.getOperand(2);
1977 return Error(IDLoc, "expected immediate operand kind");
1978 Imm = Opnd.getImm();
1979 if (!(Imm == 1 || Imm == -1 ||
1980 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1981 return Error(IDLoc, "immediate operand value out of range");
1983 case Mips::ANDI16_MM:
1984 Opnd = Inst.getOperand(2);
1986 return Error(IDLoc, "expected immediate operand kind");
1987 Imm = Opnd.getImm();
1988 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1989 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1990 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1991 return Error(IDLoc, "immediate operand value out of range");
1993 case Mips::LBU16_MM:
1994 Opnd = Inst.getOperand(2);
1996 return Error(IDLoc, "expected immediate operand kind");
1997 Imm = Opnd.getImm();
1998 if (Imm < -1 || Imm > 14)
1999 return Error(IDLoc, "immediate operand value out of range");
2002 case Mips::SB16_MMR6:
2003 Opnd = Inst.getOperand(2);
2005 return Error(IDLoc, "expected immediate operand kind");
2006 Imm = Opnd.getImm();
2007 if (Imm < 0 || Imm > 15)
2008 return Error(IDLoc, "immediate operand value out of range");
2010 case Mips::LHU16_MM:
2012 case Mips::SH16_MMR6:
2013 Opnd = Inst.getOperand(2);
2015 return Error(IDLoc, "expected immediate operand kind");
2016 Imm = Opnd.getImm();
2017 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2018 return Error(IDLoc, "immediate operand value out of range");
2022 case Mips::SW16_MMR6:
2023 Opnd = Inst.getOperand(2);
2025 return Error(IDLoc, "expected immediate operand kind");
2026 Imm = Opnd.getImm();
2027 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2028 return Error(IDLoc, "immediate operand value out of range");
2030 case Mips::ADDIUPC_MM:
2031 MCOperand Opnd = Inst.getOperand(1);
2033 return Error(IDLoc, "expected immediate operand kind");
2034 int Imm = Opnd.getImm();
2035 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2036 return Error(IDLoc, "immediate operand value out of range");
2041 bool FillDelaySlot =
2042 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2044 TOut.emitDirectiveSetNoReorder();
2046 MacroExpanderResultTy ExpandResult =
2047 tryExpandInstruction(Inst, IDLoc, Out, STI);
2048 switch (ExpandResult) {
2050 Out.EmitInstruction(Inst, *STI);
2058 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2059 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2060 if (inMicroMipsMode())
2061 TOut.setUsesMicroMips();
2063 // If this instruction has a delay slot and .set reorder is active,
2064 // emit a NOP after it.
2065 if (FillDelaySlot) {
2066 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2067 TOut.emitDirectiveSetReorder();
2070 if ((Inst.getOpcode() == Mips::JalOneReg ||
2071 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2072 isPicAndNotNxxAbi()) {
2073 if (IsCpRestoreSet) {
2074 // We need a NOP between the JALR and the LW:
2075 // If .set reorder has been used, we've already emitted a NOP.
2076 // If .set noreorder has been used, we need to emit a NOP at this point.
2077 if (!AssemblerOptions.back()->isReorder())
2078 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2081 // Load the $gp from the stack.
2082 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2084 Warning(IDLoc, "no .cprestore used in PIC mode");
2090 MipsAsmParser::MacroExpanderResultTy
2091 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2092 const MCSubtargetInfo *STI) {
2093 switch (Inst.getOpcode()) {
2095 return MER_NotAMacro;
2096 case Mips::LoadImm32:
2097 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2098 case Mips::LoadImm64:
2099 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2100 case Mips::LoadAddrImm32:
2101 case Mips::LoadAddrImm64:
2102 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2103 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2104 "expected immediate operand kind");
2106 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2108 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2112 case Mips::LoadAddrReg32:
2113 case Mips::LoadAddrReg64:
2114 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2115 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2116 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2117 "expected immediate operand kind");
2119 return expandLoadAddress(Inst.getOperand(0).getReg(),
2120 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2121 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2125 case Mips::B_MM_Pseudo:
2126 case Mips::B_MMR6_Pseudo:
2127 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2131 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2133 case Mips::JalOneReg:
2134 case Mips::JalTwoReg:
2135 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2138 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2155 case Mips::BLTImmMacro:
2156 case Mips::BLEImmMacro:
2157 case Mips::BGEImmMacro:
2158 case Mips::BGTImmMacro:
2159 case Mips::BLTUImmMacro:
2160 case Mips::BLEUImmMacro:
2161 case Mips::BGEUImmMacro:
2162 case Mips::BGTUImmMacro:
2163 case Mips::BLTLImmMacro:
2164 case Mips::BLELImmMacro:
2165 case Mips::BGELImmMacro:
2166 case Mips::BGTLImmMacro:
2167 case Mips::BLTULImmMacro:
2168 case Mips::BLEULImmMacro:
2169 case Mips::BGEULImmMacro:
2170 case Mips::BGTULImmMacro:
2171 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2172 case Mips::SDivMacro:
2173 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2175 case Mips::DSDivMacro:
2176 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2178 case Mips::UDivMacro:
2179 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2181 case Mips::DUDivMacro:
2182 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2184 case Mips::PseudoTRUNC_W_S:
2185 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2187 case Mips::PseudoTRUNC_W_D32:
2188 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2190 case Mips::PseudoTRUNC_W_D:
2191 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2194 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2196 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2198 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2201 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2203 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2208 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2209 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2210 int64_t ImmValue = Inst.getOperand(2).getImm();
2211 if (isInt<16>(ImmValue))
2212 return MER_NotAMacro;
2213 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2216 return MER_NotAMacro;
2220 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2221 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2222 int64_t ImmValue = Inst.getOperand(2).getImm();
2223 if (isUInt<16>(ImmValue))
2224 return MER_NotAMacro;
2225 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2228 return MER_NotAMacro;
2231 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2234 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2237 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2240 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2241 case Mips::ABSMacro:
2242 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2245 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2246 Inst.getOpcode() == Mips::LDMacro)
2249 case Mips::SEQMacro:
2250 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2251 case Mips::SEQIMacro:
2252 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2256 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2258 const MCSubtargetInfo *STI) {
2259 MipsTargetStreamer &TOut = getTargetStreamer();
2261 // Create a JALR instruction which is going to replace the pseudo-JAL.
2263 JalrInst.setLoc(IDLoc);
2264 const MCOperand FirstRegOp = Inst.getOperand(0);
2265 const unsigned Opcode = Inst.getOpcode();
2267 if (Opcode == Mips::JalOneReg) {
2268 // jal $rs => jalr $rs
2269 if (IsCpRestoreSet && inMicroMipsMode()) {
2270 JalrInst.setOpcode(Mips::JALRS16_MM);
2271 JalrInst.addOperand(FirstRegOp);
2272 } else if (inMicroMipsMode()) {
2273 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2274 JalrInst.addOperand(FirstRegOp);
2276 JalrInst.setOpcode(Mips::JALR);
2277 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2278 JalrInst.addOperand(FirstRegOp);
2280 } else if (Opcode == Mips::JalTwoReg) {
2281 // jal $rd, $rs => jalr $rd, $rs
2282 if (IsCpRestoreSet && inMicroMipsMode())
2283 JalrInst.setOpcode(Mips::JALRS_MM);
2285 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2286 JalrInst.addOperand(FirstRegOp);
2287 const MCOperand SecondRegOp = Inst.getOperand(1);
2288 JalrInst.addOperand(SecondRegOp);
2290 Out.EmitInstruction(JalrInst, *STI);
2292 // If .set reorder is active and branch instruction has a delay slot,
2293 // emit a NOP after it.
2294 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2295 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2296 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2302 /// Can the value be represented by a unsigned N-bit value and a shift left?
2303 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2304 unsigned BitNum = findFirstSet(x);
2306 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2309 /// Load (or add) an immediate into a register.
2311 /// @param ImmValue The immediate to load.
2312 /// @param DstReg The register that will hold the immediate.
2313 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2314 /// for a simple initialization.
2315 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2316 /// @param IsAddress True if the immediate represents an address. False if it
2318 /// @param IDLoc Location of the immediate in the source file.
2319 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2320 unsigned SrcReg, bool Is32BitImm,
2321 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2322 const MCSubtargetInfo *STI) {
2323 MipsTargetStreamer &TOut = getTargetStreamer();
2325 if (!Is32BitImm && !isGP64bit()) {
2326 Error(IDLoc, "instruction requires a 64-bit architecture");
2331 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2332 // Sign extend up to 64-bit so that the predicates match the hardware
2333 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2335 ImmValue = SignExtend64<32>(ImmValue);
2337 Error(IDLoc, "instruction requires a 32-bit immediate");
2342 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2343 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2345 bool UseSrcReg = false;
2346 if (SrcReg != Mips::NoRegister)
2349 unsigned TmpReg = DstReg;
2351 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2352 // At this point we need AT to perform the expansions and we exit if it is
2354 unsigned ATReg = getATReg(IDLoc);
2360 if (isInt<16>(ImmValue)) {
2364 // This doesn't quite follow the usual ABI expectations for N32 but matches
2365 // traditional assembler behaviour. N32 would normally use addiu for both
2366 // integers and addresses.
2367 if (IsAddress && !Is32BitImm) {
2368 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2372 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2376 if (isUInt<16>(ImmValue)) {
2377 unsigned TmpReg = DstReg;
2378 if (SrcReg == DstReg) {
2379 TmpReg = getATReg(IDLoc);
2384 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2386 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2390 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2391 warnIfNoMacro(IDLoc);
2393 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2394 uint16_t Bits15To0 = ImmValue & 0xffff;
2396 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2397 // Traditional behaviour seems to special case this particular value. It's
2398 // not clear why other masks are handled differently.
2399 if (ImmValue == 0xffffffff) {
2400 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2401 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2403 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2407 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2409 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2410 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2412 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2414 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2418 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2420 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2422 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2426 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2428 Error(IDLoc, "instruction requires a 32-bit immediate");
2432 // Traditionally, these immediates are shifted as little as possible and as
2433 // such we align the most significant bit to bit 15 of our temporary.
2434 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2435 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2436 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2437 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2438 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2439 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2442 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2447 warnIfNoMacro(IDLoc);
2449 // The remaining case is packed with a sequence of dsll and ori with zeros
2450 // being omitted and any neighbouring dsll's being coalesced.
2451 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2453 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2454 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2458 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2459 // skip it and defer the shift to the next chunk.
2460 unsigned ShiftCarriedForwards = 16;
2461 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2462 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2464 if (ImmChunk != 0) {
2465 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2466 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2467 ShiftCarriedForwards = 0;
2470 ShiftCarriedForwards += 16;
2472 ShiftCarriedForwards -= 16;
2474 // Finish any remaining shifts left by trailing zeros.
2475 if (ShiftCarriedForwards)
2476 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2479 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2484 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2485 MCStreamer &Out, const MCSubtargetInfo *STI) {
2486 const MCOperand &ImmOp = Inst.getOperand(1);
2487 assert(ImmOp.isImm() && "expected immediate operand kind");
2488 const MCOperand &DstRegOp = Inst.getOperand(0);
2489 assert(DstRegOp.isReg() && "expected register operand kind");
2491 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2492 Is32BitImm, false, IDLoc, Out, STI))
2498 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2499 const MCOperand &Offset,
2500 bool Is32BitAddress, SMLoc IDLoc,
2502 const MCSubtargetInfo *STI) {
2503 // la can't produce a usable address when addresses are 64-bit.
2504 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2505 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2506 // We currently can't do this because we depend on the equality
2507 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2508 Error(IDLoc, "la used to load 64-bit address");
2509 // Continue as if we had 'dla' instead.
2510 Is32BitAddress = false;
2514 // dla requires 64-bit addresses.
2515 if (!Is32BitAddress && !hasMips3()) {
2516 Error(IDLoc, "instruction requires a 64-bit architecture");
2520 if (!Offset.isImm())
2521 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2522 Is32BitAddress, IDLoc, Out, STI);
2524 if (!ABI.ArePtrs64bit()) {
2525 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2526 Is32BitAddress = true;
2529 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2533 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2534 unsigned DstReg, unsigned SrcReg,
2535 bool Is32BitSym, SMLoc IDLoc,
2537 const MCSubtargetInfo *STI) {
2538 MipsTargetStreamer &TOut = getTargetStreamer();
2539 bool UseSrcReg = SrcReg != Mips::NoRegister;
2540 warnIfNoMacro(IDLoc);
2542 if (inPicMode() && ABI.IsO32()) {
2544 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2545 Error(IDLoc, "expected relocatable expression");
2548 if (Res.getSymB() != nullptr) {
2549 Error(IDLoc, "expected relocatable expression with only one symbol");
2553 // The case where the result register is $25 is somewhat special. If the
2554 // symbol in the final relocation is external and not modified with a
2555 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2556 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2557 Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
2558 !Res.getSymA()->getSymbol().isTemporary()) {
2559 const MCExpr *CallExpr =
2560 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2561 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2562 MCOperand::createExpr(CallExpr), IDLoc, STI);
2566 // The remaining cases are:
2567 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2568 // >addiu $tmp, $tmp, %lo(offset)
2569 // >addiu $rd, $tmp, $rs
2570 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2571 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2572 // >addiu $rd, $tmp, $rs
2573 // The addiu's marked with a '>' may be omitted if they are redundant. If
2574 // this happens then the last instruction must use $rd as the result
2576 const MipsMCExpr *GotExpr =
2577 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2578 const MCExpr *LoExpr = nullptr;
2579 if (Res.getSymA()->getSymbol().isInSection() ||
2580 Res.getSymA()->getSymbol().isTemporary())
2581 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2582 else if (Res.getConstant() != 0) {
2583 // External symbols fully resolve the symbol with just the %got(symbol)
2584 // but we must still account for any offset to the symbol for expressions
2586 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2589 unsigned TmpReg = DstReg;
2591 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2593 // If $rs is the same as $rd, we need to use AT.
2594 // If it is not available we exit.
2595 unsigned ATReg = getATReg(IDLoc);
2601 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2602 MCOperand::createExpr(GotExpr), IDLoc, STI);
2605 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2609 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2614 const MipsMCExpr *HiExpr =
2615 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2616 const MipsMCExpr *LoExpr =
2617 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2619 // This is the 64-bit symbol address expansion.
2620 if (ABI.ArePtrs64bit() && isGP64bit()) {
2621 // We always need AT for the 64-bit expansion.
2622 // If it is not available we exit.
2623 unsigned ATReg = getATReg(IDLoc);
2627 const MipsMCExpr *HighestExpr =
2628 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2629 const MipsMCExpr *HigherExpr =
2630 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2633 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2635 // If $rs is the same as $rd:
2636 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2637 // daddiu $at, $at, %higher(sym)
2638 // dsll $at, $at, 16
2639 // daddiu $at, $at, %hi(sym)
2640 // dsll $at, $at, 16
2641 // daddiu $at, $at, %lo(sym)
2642 // daddu $rd, $at, $rd
2643 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2645 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2646 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2647 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2648 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2650 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2651 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2653 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2658 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2659 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2660 // lui $at, %hi(sym)
2661 // daddiu $rd, $rd, %higher(sym)
2662 // daddiu $at, $at, %lo(sym)
2663 // dsll32 $rd, $rd, 0
2664 // daddu $rd, $rd, $at
2665 // (daddu $rd, $rd, $rs)
2666 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2668 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2669 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2670 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2671 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2673 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2674 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2676 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2681 // And now, the 32-bit symbol address expansion:
2682 // If $rs is the same as $rd:
2683 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2684 // ori $at, $at, %lo(sym)
2685 // addu $rd, $at, $rd
2686 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2687 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2688 // ori $rd, $rd, %lo(sym)
2689 // (addu $rd, $rd, $rs)
2690 unsigned TmpReg = DstReg;
2692 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2693 // If $rs is the same as $rd, we need to use AT.
2694 // If it is not available we exit.
2695 unsigned ATReg = getATReg(IDLoc);
2701 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2702 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2706 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2709 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2714 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
2716 const MCSubtargetInfo *STI) {
2717 MipsTargetStreamer &TOut = getTargetStreamer();
2719 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2720 "unexpected number of operands");
2722 MCOperand Offset = Inst.getOperand(0);
2723 if (Offset.isExpr()) {
2725 Inst.setOpcode(Mips::BEQ_MM);
2726 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2727 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2728 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2730 assert(Offset.isImm() && "expected immediate operand kind");
2731 if (isInt<11>(Offset.getImm())) {
2732 // If offset fits into 11 bits then this instruction becomes microMIPS
2733 // 16-bit unconditional branch instruction.
2734 if (inMicroMipsMode())
2735 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2737 if (!isInt<17>(Offset.getImm()))
2738 return Error(IDLoc, "branch target out of range");
2739 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2740 return Error(IDLoc, "branch to misaligned address");
2742 Inst.setOpcode(Mips::BEQ_MM);
2743 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2744 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2745 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2748 Out.EmitInstruction(Inst, *STI);
2750 // If .set reorder is active and branch instruction has a delay slot,
2751 // emit a NOP after it.
2752 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2753 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2754 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
2759 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2760 const MCSubtargetInfo *STI) {
2761 MipsTargetStreamer &TOut = getTargetStreamer();
2762 const MCOperand &DstRegOp = Inst.getOperand(0);
2763 assert(DstRegOp.isReg() && "expected register operand kind");
2765 const MCOperand &ImmOp = Inst.getOperand(1);
2766 assert(ImmOp.isImm() && "expected immediate operand kind");
2768 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2769 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
2770 "expected immediate or expression operand");
2772 unsigned OpCode = 0;
2773 switch(Inst.getOpcode()) {
2781 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2785 int64_t ImmValue = ImmOp.getImm();
2787 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2790 warnIfNoMacro(IDLoc);
2792 unsigned ATReg = getATReg(IDLoc);
2796 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2800 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
2805 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2806 const MCSubtargetInfo *STI, bool IsLoad,
2809 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2812 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2815 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2816 const MCSubtargetInfo *STI, bool IsImmOpnd) {
2817 MipsTargetStreamer &TOut = getTargetStreamer();
2819 unsigned DstReg = Inst.getOperand(0).getReg();
2820 unsigned BaseReg = Inst.getOperand(1).getReg();
2822 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2823 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
2824 unsigned DstRegClassID =
2825 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
2826 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
2827 (DstRegClassID == Mips::GPR64RegClassID);
2830 // Try to use DstReg as the temporary.
2831 if (IsGPR && (BaseReg != DstReg)) {
2832 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2833 Inst.getOperand(2).getImm(), DstReg, IDLoc,
2838 // At this point we need AT to perform the expansions and we exit if it is
2840 unsigned ATReg = getATReg(IDLoc);
2844 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2845 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
2849 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2850 MCOperand LoOperand = MCOperand::createExpr(
2851 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2852 MCOperand HiOperand = MCOperand::createExpr(
2853 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2855 // Try to use DstReg as the temporary.
2856 if (IsGPR && (BaseReg != DstReg)) {
2857 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2858 LoOperand, DstReg, IDLoc, STI);
2862 // At this point we need AT to perform the expansions and we exit if it is
2864 unsigned ATReg = getATReg(IDLoc);
2868 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2869 LoOperand, ATReg, IDLoc, STI);
2872 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2873 const MCSubtargetInfo *STI,
2875 MipsTargetStreamer &TOut = getTargetStreamer();
2877 unsigned SrcReg = Inst.getOperand(0).getReg();
2878 unsigned BaseReg = Inst.getOperand(1).getReg();
2881 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
2882 Inst.getOperand(2).getImm(),
2883 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
2887 unsigned ATReg = getATReg(IDLoc);
2891 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2892 MCOperand LoOperand = MCOperand::createExpr(
2893 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2894 MCOperand HiOperand = MCOperand::createExpr(
2895 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2896 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
2897 LoOperand, ATReg, IDLoc, STI);
2900 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2902 const MCSubtargetInfo *STI) {
2903 unsigned OpNum = Inst.getNumOperands();
2904 unsigned Opcode = Inst.getOpcode();
2905 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2907 assert (Inst.getOperand(OpNum - 1).isImm() &&
2908 Inst.getOperand(OpNum - 2).isReg() &&
2909 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2911 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2912 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2913 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2914 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2915 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2916 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2917 // It can be implemented as SWM16 or LWM16 instruction.
2918 if (inMicroMipsMode() && hasMips32r6())
2919 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2921 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2924 Inst.setOpcode(NewOpcode);
2925 Out.EmitInstruction(Inst, *STI);
2929 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2931 const MCSubtargetInfo *STI) {
2932 MipsTargetStreamer &TOut = getTargetStreamer();
2933 bool EmittedNoMacroWarning = false;
2934 unsigned PseudoOpcode = Inst.getOpcode();
2935 unsigned SrcReg = Inst.getOperand(0).getReg();
2936 const MCOperand &TrgOp = Inst.getOperand(1);
2937 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2939 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2940 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2944 TrgReg = TrgOp.getReg();
2945 else if (TrgOp.isImm()) {
2946 warnIfNoMacro(IDLoc);
2947 EmittedNoMacroWarning = true;
2949 TrgReg = getATReg(IDLoc);
2953 switch(PseudoOpcode) {
2955 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2956 case Mips::BLTImmMacro:
2957 PseudoOpcode = Mips::BLT;
2959 case Mips::BLEImmMacro:
2960 PseudoOpcode = Mips::BLE;
2962 case Mips::BGEImmMacro:
2963 PseudoOpcode = Mips::BGE;
2965 case Mips::BGTImmMacro:
2966 PseudoOpcode = Mips::BGT;
2968 case Mips::BLTUImmMacro:
2969 PseudoOpcode = Mips::BLTU;
2971 case Mips::BLEUImmMacro:
2972 PseudoOpcode = Mips::BLEU;
2974 case Mips::BGEUImmMacro:
2975 PseudoOpcode = Mips::BGEU;
2977 case Mips::BGTUImmMacro:
2978 PseudoOpcode = Mips::BGTU;
2980 case Mips::BLTLImmMacro:
2981 PseudoOpcode = Mips::BLTL;
2983 case Mips::BLELImmMacro:
2984 PseudoOpcode = Mips::BLEL;
2986 case Mips::BGELImmMacro:
2987 PseudoOpcode = Mips::BGEL;
2989 case Mips::BGTLImmMacro:
2990 PseudoOpcode = Mips::BGTL;
2992 case Mips::BLTULImmMacro:
2993 PseudoOpcode = Mips::BLTUL;
2995 case Mips::BLEULImmMacro:
2996 PseudoOpcode = Mips::BLEUL;
2998 case Mips::BGEULImmMacro:
2999 PseudoOpcode = Mips::BGEUL;
3001 case Mips::BGTULImmMacro:
3002 PseudoOpcode = Mips::BGTUL;
3006 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3007 false, IDLoc, Out, STI))
3011 switch (PseudoOpcode) {
3016 AcceptsEquality = false;
3017 ReverseOrderSLT = false;
3018 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3019 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3020 ZeroSrcOpcode = Mips::BGTZ;
3021 ZeroTrgOpcode = Mips::BLTZ;
3027 AcceptsEquality = true;
3028 ReverseOrderSLT = true;
3029 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3030 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3031 ZeroSrcOpcode = Mips::BGEZ;
3032 ZeroTrgOpcode = Mips::BLEZ;
3038 AcceptsEquality = true;
3039 ReverseOrderSLT = false;
3040 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3041 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3042 ZeroSrcOpcode = Mips::BLEZ;
3043 ZeroTrgOpcode = Mips::BGEZ;
3049 AcceptsEquality = false;
3050 ReverseOrderSLT = true;
3051 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3052 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3053 ZeroSrcOpcode = Mips::BLTZ;
3054 ZeroTrgOpcode = Mips::BGTZ;
3057 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3060 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3061 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3062 if (IsSrcRegZero && IsTrgRegZero) {
3063 // FIXME: All of these Opcode-specific if's are needed for compatibility
3064 // with GAS' behaviour. However, they may not generate the most efficient
3065 // code in some circumstances.
3066 if (PseudoOpcode == Mips::BLT) {
3067 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3071 if (PseudoOpcode == Mips::BLE) {
3072 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3074 Warning(IDLoc, "branch is always taken");
3077 if (PseudoOpcode == Mips::BGE) {
3078 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3080 Warning(IDLoc, "branch is always taken");
3083 if (PseudoOpcode == Mips::BGT) {
3084 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3088 if (PseudoOpcode == Mips::BGTU) {
3089 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3090 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3093 if (AcceptsEquality) {
3094 // If both registers are $0 and the pseudo-branch accepts equality, it
3095 // will always be taken, so we emit an unconditional branch.
3096 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3097 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3098 Warning(IDLoc, "branch is always taken");
3101 // If both registers are $0 and the pseudo-branch does not accept
3102 // equality, it will never be taken, so we don't have to emit anything.
3105 if (IsSrcRegZero || IsTrgRegZero) {
3106 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3107 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3108 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3109 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3110 // the pseudo-branch will never be taken, so we don't emit anything.
3111 // This only applies to unsigned pseudo-branches.
3114 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3115 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3116 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3117 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3118 // the pseudo-branch will always be taken, so we emit an unconditional
3120 // This only applies to unsigned pseudo-branches.
3121 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3122 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3123 Warning(IDLoc, "branch is always taken");
3127 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3128 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3129 // the pseudo-branch will be taken only when the non-zero register is
3130 // different from 0, so we emit a BNEZ.
3132 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3133 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3134 // the pseudo-branch will be taken only when the non-zero register is
3135 // equal to 0, so we emit a BEQZ.
3137 // Because only BLEU and BGEU branch on equality, we can use the
3138 // AcceptsEquality variable to decide when to emit the BEQZ.
3139 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3140 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3141 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3144 // If we have a signed pseudo-branch and one of the registers is $0,
3145 // we can use an appropriate compare-to-zero branch. We select which one
3146 // to use in the switch statement above.
3147 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3148 IsSrcRegZero ? TrgReg : SrcReg,
3149 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3153 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3154 // expansions. If it is not available, we return.
3155 unsigned ATRegNum = getATReg(IDLoc);
3159 if (!EmittedNoMacroWarning)
3160 warnIfNoMacro(IDLoc);
3162 // SLT fits well with 2 of our 4 pseudo-branches:
3163 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3164 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3165 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3166 // This is accomplished by using a BNEZ with the result of the SLT.
3168 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3169 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3170 // Because only BGE and BLE branch on equality, we can use the
3171 // AcceptsEquality variable to decide when to emit the BEQZ.
3172 // Note that the order of the SLT arguments doesn't change between
3175 // The same applies to the unsigned variants, except that SLTu is used
3177 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3178 ReverseOrderSLT ? TrgReg : SrcReg,
3179 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3181 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3182 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3183 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3188 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3189 const MCSubtargetInfo *STI, const bool IsMips64,
3190 const bool Signed) {
3191 MipsTargetStreamer &TOut = getTargetStreamer();
3193 warnIfNoMacro(IDLoc);
3195 const MCOperand &RdRegOp = Inst.getOperand(0);
3196 assert(RdRegOp.isReg() && "expected register operand kind");
3197 unsigned RdReg = RdRegOp.getReg();
3199 const MCOperand &RsRegOp = Inst.getOperand(1);
3200 assert(RsRegOp.isReg() && "expected register operand kind");
3201 unsigned RsReg = RsRegOp.getReg();
3203 const MCOperand &RtRegOp = Inst.getOperand(2);
3204 assert(RtRegOp.isReg() && "expected register operand kind");
3205 unsigned RtReg = RtRegOp.getReg();
3210 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3211 ZeroReg = Mips::ZERO_64;
3213 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3214 ZeroReg = Mips::ZERO;
3217 bool UseTraps = useTraps();
3219 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3220 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
3221 Warning(IDLoc, "dividing zero by zero");
3223 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3225 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3229 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3233 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3238 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3239 Warning(IDLoc, "division by zero");
3242 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3246 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3251 // FIXME: The values for these two BranchTarget variables may be different in
3252 // micromips. These magic numbers need to be removed.
3253 unsigned BranchTargetNoTraps;
3254 unsigned BranchTarget;
3257 BranchTarget = IsMips64 ? 12 : 8;
3258 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3260 BranchTarget = IsMips64 ? 20 : 16;
3261 BranchTargetNoTraps = 8;
3262 // Branch to the li instruction.
3263 TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI);
3266 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3269 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3272 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3276 unsigned ATReg = getATReg(IDLoc);
3280 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3282 // Branch to the mflo instruction.
3283 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3284 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3285 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3287 // Branch to the mflo instruction.
3288 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3289 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3293 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3295 // Branch to the mflo instruction.
3296 TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI);
3297 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3298 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3300 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3304 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3305 SMLoc IDLoc, MCStreamer &Out,
3306 const MCSubtargetInfo *STI) {
3307 MipsTargetStreamer &TOut = getTargetStreamer();
3309 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3310 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
3311 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
3313 unsigned FirstReg = Inst.getOperand(0).getReg();
3314 unsigned SecondReg = Inst.getOperand(1).getReg();
3315 unsigned ThirdReg = Inst.getOperand(2).getReg();
3317 if (hasMips1() && !hasMips2()) {
3318 unsigned ATReg = getATReg(IDLoc);
3321 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3322 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3323 TOut.emitNop(IDLoc, STI);
3324 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3325 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3326 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3327 TOut.emitNop(IDLoc, STI);
3328 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3330 FirstReg, SecondReg, IDLoc, STI);
3331 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3332 TOut.emitNop(IDLoc, STI);
3336 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3338 FirstReg, SecondReg, IDLoc, STI);
3343 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3344 MCStreamer &Out, const MCSubtargetInfo *STI) {
3345 if (hasMips32r6() || hasMips64r6()) {
3346 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3349 const MCOperand &DstRegOp = Inst.getOperand(0);
3350 assert(DstRegOp.isReg() && "expected register operand kind");
3351 const MCOperand &SrcRegOp = Inst.getOperand(1);
3352 assert(SrcRegOp.isReg() && "expected register operand kind");
3353 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3354 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3356 MipsTargetStreamer &TOut = getTargetStreamer();
3357 unsigned DstReg = DstRegOp.getReg();
3358 unsigned SrcReg = SrcRegOp.getReg();
3359 int64_t OffsetValue = OffsetImmOp.getImm();
3361 // NOTE: We always need AT for ULHU, as it is always used as the source
3362 // register for one of the LBu's.
3363 warnIfNoMacro(IDLoc);
3364 unsigned ATReg = getATReg(IDLoc);
3368 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3369 if (IsLargeOffset) {
3370 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3375 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
3376 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3378 std::swap(FirstOffset, SecondOffset);
3380 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
3381 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
3383 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
3384 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
3386 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3387 FirstOffset, IDLoc, STI);
3388 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
3389 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
3390 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3395 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3396 const MCSubtargetInfo *STI) {
3397 if (hasMips32r6() || hasMips64r6()) {
3398 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3401 const MCOperand &DstRegOp = Inst.getOperand(0);
3402 assert(DstRegOp.isReg() && "expected register operand kind");
3403 const MCOperand &SrcRegOp = Inst.getOperand(1);
3404 assert(SrcRegOp.isReg() && "expected register operand kind");
3405 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3406 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3408 MipsTargetStreamer &TOut = getTargetStreamer();
3409 unsigned DstReg = DstRegOp.getReg();
3410 unsigned SrcReg = SrcRegOp.getReg();
3411 int64_t OffsetValue = OffsetImmOp.getImm();
3413 warnIfNoMacro(IDLoc);
3414 unsigned ATReg = getATReg(IDLoc);
3418 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3419 if (IsLargeOffset) {
3420 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3425 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3426 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
3428 std::swap(FirstOffset, SecondOffset);
3430 if (IsLargeOffset) {
3431 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
3432 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
3433 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
3434 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
3435 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
3436 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3438 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
3439 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
3440 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
3446 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3447 const MCSubtargetInfo *STI) {
3448 if (hasMips32r6() || hasMips64r6()) {
3449 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3452 const MCOperand &DstRegOp = Inst.getOperand(0);
3453 assert(DstRegOp.isReg() && "expected register operand kind");
3454 const MCOperand &SrcRegOp = Inst.getOperand(1);
3455 assert(SrcRegOp.isReg() && "expected register operand kind");
3456 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3457 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3459 MipsTargetStreamer &TOut = getTargetStreamer();
3460 unsigned DstReg = DstRegOp.getReg();
3461 unsigned SrcReg = SrcRegOp.getReg();
3462 int64_t OffsetValue = OffsetImmOp.getImm();
3464 // Compute left/right load/store offsets.
3465 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
3466 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
3467 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
3469 std::swap(LxlOffset, LxrOffset);
3471 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
3472 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
3473 unsigned TmpReg = SrcReg;
3474 if (IsLargeOffset || DoMove) {
3475 warnIfNoMacro(IDLoc);
3476 TmpReg = getATReg(IDLoc);
3481 if (IsLargeOffset) {
3482 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
3488 std::swap(DstReg, TmpReg);
3490 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
3491 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
3492 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
3493 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
3496 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
3501 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3503 const MCSubtargetInfo *STI) {
3504 MipsTargetStreamer &TOut = getTargetStreamer();
3506 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3507 assert (Inst.getOperand(0).isReg() &&
3508 Inst.getOperand(1).isReg() &&
3509 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3511 unsigned ATReg = Mips::NoRegister;
3512 unsigned FinalDstReg = Mips::NoRegister;
3513 unsigned DstReg = Inst.getOperand(0).getReg();
3514 unsigned SrcReg = Inst.getOperand(1).getReg();
3515 int64_t ImmValue = Inst.getOperand(2).getImm();
3517 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3519 unsigned FinalOpcode = Inst.getOpcode();
3521 if (DstReg == SrcReg) {
3522 ATReg = getATReg(Inst.getLoc());
3525 FinalDstReg = DstReg;
3529 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
3530 switch (FinalOpcode) {
3532 llvm_unreachable("unimplemented expansion");
3534 FinalOpcode = Mips::ADD;
3537 FinalOpcode = Mips::ADDu;
3540 FinalOpcode = Mips::AND;
3542 case (Mips::NORImm):
3543 FinalOpcode = Mips::NOR;
3546 FinalOpcode = Mips::OR;
3549 FinalOpcode = Mips::SLT;
3552 FinalOpcode = Mips::SLTu;
3555 FinalOpcode = Mips::XOR;
3559 if (FinalDstReg == Mips::NoRegister)
3560 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
3562 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
3568 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3569 const MCSubtargetInfo *STI) {
3570 MipsTargetStreamer &TOut = getTargetStreamer();
3571 unsigned ATReg = Mips::NoRegister;
3572 unsigned DReg = Inst.getOperand(0).getReg();
3573 unsigned SReg = Inst.getOperand(1).getReg();
3574 unsigned TReg = Inst.getOperand(2).getReg();
3575 unsigned TmpReg = DReg;
3577 unsigned FirstShift = Mips::NOP;
3578 unsigned SecondShift = Mips::NOP;
3580 if (hasMips32r2()) {
3583 TmpReg = getATReg(Inst.getLoc());
3588 if (Inst.getOpcode() == Mips::ROL) {
3589 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3590 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3594 if (Inst.getOpcode() == Mips::ROR) {
3595 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3604 switch (Inst.getOpcode()) {
3606 llvm_unreachable("unexpected instruction opcode");
3608 FirstShift = Mips::SRLV;
3609 SecondShift = Mips::SLLV;
3612 FirstShift = Mips::SLLV;
3613 SecondShift = Mips::SRLV;
3617 ATReg = getATReg(Inst.getLoc());
3621 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3622 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3623 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3624 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3632 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3634 const MCSubtargetInfo *STI) {
3635 MipsTargetStreamer &TOut = getTargetStreamer();
3636 unsigned ATReg = Mips::NoRegister;
3637 unsigned DReg = Inst.getOperand(0).getReg();
3638 unsigned SReg = Inst.getOperand(1).getReg();
3639 int64_t ImmValue = Inst.getOperand(2).getImm();
3641 unsigned FirstShift = Mips::NOP;
3642 unsigned SecondShift = Mips::NOP;
3644 if (hasMips32r2()) {
3646 if (Inst.getOpcode() == Mips::ROLImm) {
3647 uint64_t MaxShift = 32;
3648 uint64_t ShiftValue = ImmValue;
3650 ShiftValue = MaxShift - ImmValue;
3651 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3655 if (Inst.getOpcode() == Mips::RORImm) {
3656 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
3665 if (ImmValue == 0) {
3666 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
3670 switch (Inst.getOpcode()) {
3672 llvm_unreachable("unexpected instruction opcode");
3674 FirstShift = Mips::SLL;
3675 SecondShift = Mips::SRL;
3678 FirstShift = Mips::SRL;
3679 SecondShift = Mips::SLL;
3683 ATReg = getATReg(Inst.getLoc());
3687 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
3688 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
3689 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3697 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3698 const MCSubtargetInfo *STI) {
3699 MipsTargetStreamer &TOut = getTargetStreamer();
3700 unsigned ATReg = Mips::NoRegister;
3701 unsigned DReg = Inst.getOperand(0).getReg();
3702 unsigned SReg = Inst.getOperand(1).getReg();
3703 unsigned TReg = Inst.getOperand(2).getReg();
3704 unsigned TmpReg = DReg;
3706 unsigned FirstShift = Mips::NOP;
3707 unsigned SecondShift = Mips::NOP;
3709 if (hasMips64r2()) {
3711 if (TmpReg == SReg) {
3712 TmpReg = getATReg(Inst.getLoc());
3717 if (Inst.getOpcode() == Mips::DROL) {
3718 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3719 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3723 if (Inst.getOpcode() == Mips::DROR) {
3724 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3733 switch (Inst.getOpcode()) {
3735 llvm_unreachable("unexpected instruction opcode");
3737 FirstShift = Mips::DSRLV;
3738 SecondShift = Mips::DSLLV;
3741 FirstShift = Mips::DSLLV;
3742 SecondShift = Mips::DSRLV;
3746 ATReg = getATReg(Inst.getLoc());
3750 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3751 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3752 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3753 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3761 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3763 const MCSubtargetInfo *STI) {
3764 MipsTargetStreamer &TOut = getTargetStreamer();
3765 unsigned ATReg = Mips::NoRegister;
3766 unsigned DReg = Inst.getOperand(0).getReg();
3767 unsigned SReg = Inst.getOperand(1).getReg();
3768 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3770 unsigned FirstShift = Mips::NOP;
3771 unsigned SecondShift = Mips::NOP;
3775 if (hasMips64r2()) {
3777 unsigned FinalOpcode = Mips::NOP;
3779 FinalOpcode = Mips::DROTR;
3780 else if (ImmValue % 32 == 0)
3781 FinalOpcode = Mips::DROTR32;
3782 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3783 if (Inst.getOpcode() == Mips::DROLImm)
3784 FinalOpcode = Mips::DROTR32;
3786 FinalOpcode = Mips::DROTR;
3787 } else if (ImmValue >= 33) {
3788 if (Inst.getOpcode() == Mips::DROLImm)
3789 FinalOpcode = Mips::DROTR;
3791 FinalOpcode = Mips::DROTR32;
3794 uint64_t ShiftValue = ImmValue % 32;
3795 if (Inst.getOpcode() == Mips::DROLImm)
3796 ShiftValue = (32 - ImmValue % 32) % 32;
3798 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3805 if (ImmValue == 0) {
3806 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
3810 switch (Inst.getOpcode()) {
3812 llvm_unreachable("unexpected instruction opcode");
3814 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3815 FirstShift = Mips::DSLL;
3816 SecondShift = Mips::DSRL32;
3818 if (ImmValue == 32) {
3819 FirstShift = Mips::DSLL32;
3820 SecondShift = Mips::DSRL32;
3822 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3823 FirstShift = Mips::DSLL32;
3824 SecondShift = Mips::DSRL;
3828 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3829 FirstShift = Mips::DSRL;
3830 SecondShift = Mips::DSLL32;
3832 if (ImmValue == 32) {
3833 FirstShift = Mips::DSRL32;
3834 SecondShift = Mips::DSLL32;
3836 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3837 FirstShift = Mips::DSRL32;
3838 SecondShift = Mips::DSLL;
3843 ATReg = getATReg(Inst.getLoc());
3847 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
3848 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
3849 Inst.getLoc(), STI);
3850 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3858 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3859 const MCSubtargetInfo *STI) {
3860 MipsTargetStreamer &TOut = getTargetStreamer();
3861 unsigned FirstRegOp = Inst.getOperand(0).getReg();
3862 unsigned SecondRegOp = Inst.getOperand(1).getReg();
3864 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
3865 if (FirstRegOp != SecondRegOp)
3866 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
3868 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
3869 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
3874 static unsigned nextReg(unsigned Reg) {
3876 case Mips::ZERO: return Mips::AT;
3877 case Mips::AT: return Mips::V0;
3878 case Mips::V0: return Mips::V1;
3879 case Mips::V1: return Mips::A0;
3880 case Mips::A0: return Mips::A1;
3881 case Mips::A1: return Mips::A2;
3882 case Mips::A2: return Mips::A3;
3883 case Mips::A3: return Mips::T0;
3884 case Mips::T0: return Mips::T1;
3885 case Mips::T1: return Mips::T2;
3886 case Mips::T2: return Mips::T3;
3887 case Mips::T3: return Mips::T4;
3888 case Mips::T4: return Mips::T5;
3889 case Mips::T5: return Mips::T6;
3890 case Mips::T6: return Mips::T7;
3891 case Mips::T7: return Mips::S0;
3892 case Mips::S0: return Mips::S1;
3893 case Mips::S1: return Mips::S2;
3894 case Mips::S2: return Mips::S3;
3895 case Mips::S3: return Mips::S4;
3896 case Mips::S4: return Mips::S5;
3897 case Mips::S5: return Mips::S6;
3898 case Mips::S6: return Mips::S7;
3899 case Mips::S7: return Mips::T8;
3900 case Mips::T8: return Mips::T9;
3901 case Mips::T9: return Mips::K0;
3902 case Mips::K0: return Mips::K1;
3903 case Mips::K1: return Mips::GP;
3904 case Mips::GP: return Mips::SP;
3905 case Mips::SP: return Mips::FP;
3906 case Mips::FP: return Mips::RA;
3907 case Mips::RA: return Mips::ZERO;
3913 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
3914 // lw $<reg+1>>, offset+4($reg2)'
3915 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
3916 // sw $<reg+1>>, offset+4($reg2)'
3918 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
3920 const MCSubtargetInfo *STI,
3925 warnIfNoMacro(IDLoc);
3927 MipsTargetStreamer &TOut = getTargetStreamer();
3928 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
3929 unsigned FirstReg = Inst.getOperand(0).getReg();
3930 unsigned SecondReg = nextReg(FirstReg);
3931 unsigned BaseReg = Inst.getOperand(1).getReg();
3935 warnIfRegIndexIsAT(FirstReg, IDLoc);
3937 assert(Inst.getOperand(2).isImm() &&
3938 "Offset for load macro is not immediate!");
3940 MCOperand &FirstOffset = Inst.getOperand(2);
3941 signed NextOffset = FirstOffset.getImm() + 4;
3942 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
3944 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
3947 // For loads, clobber the base register with the second load instead of the
3948 // first if the BaseReg == FirstReg.
3949 if (FirstReg != BaseReg || !IsLoad) {
3950 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3951 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3953 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3954 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3960 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3961 const MCSubtargetInfo *STI) {
3963 warnIfNoMacro(IDLoc);
3964 MipsTargetStreamer &TOut = getTargetStreamer();
3966 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
3967 Inst.getOperand(2).getReg() != Mips::ZERO) {
3968 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
3969 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
3971 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
3972 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
3977 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
3978 Reg = Inst.getOperand(2).getReg();
3980 Reg = Inst.getOperand(1).getReg();
3982 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
3986 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3987 const MCSubtargetInfo *STI) {
3989 warnIfNoMacro(IDLoc);
3990 MipsTargetStreamer &TOut = getTargetStreamer();
3993 int64_t Imm = Inst.getOperand(2).getImm();
3994 unsigned Reg = Inst.getOperand(1).getReg();
3997 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
3998 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4002 if (Reg == Mips::ZERO) {
4003 Warning(IDLoc, "comparison is always false");
4004 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4005 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4009 if (Imm > -0x8000 && Imm < 0) {
4011 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4016 if (!isUInt<16>(Imm)) {
4017 unsigned ATReg = getATReg(IDLoc);
4021 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4025 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4026 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4027 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4028 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4032 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4034 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4035 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4040 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
4041 const OperandVector &Operands) {
4042 switch (Inst.getOpcode()) {
4044 return Match_Success;
4047 case Mips::DATI_MM64R6:
4048 case Mips::DAHI_MM64R6:
4049 if (static_cast<MipsOperand &>(*Operands[1])
4050 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4051 return Match_Success;
4052 return Match_RequiresSameSrcAndDst;
4056 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4057 switch (Inst.getOpcode()) {
4058 // As described by the MIPSR6 spec, daui must not use the zero operand for
4059 // its source operand.
4061 case Mips::DAUI_MM64R6:
4062 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4063 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4064 return Match_RequiresNoZeroRegister;
4065 return Match_Success;
4066 // As described by the Mips32r2 spec, the registers Rd and Rs for
4067 // jalr.hb must be different.
4068 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
4069 // and registers Rd and Base for microMIPS lwp instruction
4071 case Mips::JALRC_HB_MMR6:
4072 case Mips::JALRC_MMR6:
4073 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4074 return Match_RequiresDifferentSrcAndDst;
4075 return Match_Success;
4077 case Mips::LWP_MMR6:
4078 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
4079 return Match_RequiresDifferentSrcAndDst;
4080 return Match_Success;
4082 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
4083 return Match_NonZeroOperandForSync;
4084 return Match_Success;
4085 // As described the MIPSR6 spec, the compact branches that compare registers
4087 // a) Not use the zero register.
4088 // b) Not use the same register twice.
4089 // c) rs < rt for bnec, beqc.
4090 // NB: For this case, the encoding will swap the operands as their
4091 // ordering doesn't matter. GAS performs this transformation too.
4092 // Hence, that constraint does not have to be enforced.
4094 // The compact branches that branch iff the signed addition of two registers
4095 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
4096 // operand swapping. They do not have restriction of using the zero register.
4097 case Mips::BLEZC: case Mips::BLEZC_MMR6:
4098 case Mips::BGEZC: case Mips::BGEZC_MMR6:
4099 case Mips::BGTZC: case Mips::BGTZC_MMR6:
4100 case Mips::BLTZC: case Mips::BLTZC_MMR6:
4101 case Mips::BEQZC: case Mips::BEQZC_MMR6:
4102 case Mips::BNEZC: case Mips::BNEZC_MMR6:
4109 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4110 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4111 return Match_RequiresNoZeroRegister;
4112 return Match_Success;
4113 case Mips::BGEC: case Mips::BGEC_MMR6:
4114 case Mips::BLTC: case Mips::BLTC_MMR6:
4115 case Mips::BGEUC: case Mips::BGEUC_MMR6:
4116 case Mips::BLTUC: case Mips::BLTUC_MMR6:
4117 case Mips::BEQC: case Mips::BEQC_MMR6:
4118 case Mips::BNEC: case Mips::BNEC_MMR6:
4125 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4126 Inst.getOperand(0).getReg() == Mips::ZERO_64)
4127 return Match_RequiresNoZeroRegister;
4128 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4129 Inst.getOperand(1).getReg() == Mips::ZERO_64)
4130 return Match_RequiresNoZeroRegister;
4131 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4132 return Match_RequiresDifferentOperands;
4133 return Match_Success;
4136 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
4137 if ((TSFlags & MipsII::HasFCCRegOperand) &&
4138 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
4139 return Match_NoFCCRegisterForCurrentISA;
4141 return Match_Success;
4145 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
4146 uint64_t ErrorInfo) {
4147 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
4148 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4149 if (ErrorLoc == SMLoc())
4156 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4157 OperandVector &Operands,
4159 uint64_t &ErrorInfo,
4160 bool MatchingInlineAsm) {
4163 unsigned MatchResult =
4164 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
4166 switch (MatchResult) {
4167 case Match_Success: {
4168 if (processInstruction(Inst, IDLoc, Out, STI))
4172 case Match_MissingFeature:
4173 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4175 case Match_InvalidOperand: {
4176 SMLoc ErrorLoc = IDLoc;
4177 if (ErrorInfo != ~0ULL) {
4178 if (ErrorInfo >= Operands.size())
4179 return Error(IDLoc, "too few operands for instruction");
4181 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4182 if (ErrorLoc == SMLoc())
4186 return Error(ErrorLoc, "invalid operand for instruction");
4188 case Match_NonZeroOperandForSync:
4189 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
4190 case Match_MnemonicFail:
4191 return Error(IDLoc, "invalid instruction");
4192 case Match_RequiresDifferentSrcAndDst:
4193 return Error(IDLoc, "source and destination must be different");
4194 case Match_RequiresDifferentOperands:
4195 return Error(IDLoc, "registers must be different");
4196 case Match_RequiresNoZeroRegister:
4197 return Error(IDLoc, "invalid operand ($zero) for instruction");
4198 case Match_RequiresSameSrcAndDst:
4199 return Error(IDLoc, "source and destination must match");
4200 case Match_NoFCCRegisterForCurrentISA:
4201 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4202 "non-zero fcc register doesn't exist in current ISA level");
4204 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
4206 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4207 "expected 1-bit unsigned immediate");
4209 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4210 "expected 2-bit unsigned immediate");
4212 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4213 "expected immediate in range 1 .. 4");
4215 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4216 "expected 3-bit unsigned immediate");
4218 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4219 "expected 4-bit unsigned immediate");
4221 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4222 "expected 4-bit signed immediate");
4224 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4225 "expected 5-bit unsigned immediate");
4227 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4228 "expected 5-bit signed immediate");
4230 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4231 "expected immediate in range 1 .. 32");
4232 case Match_UImm5_32:
4233 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4234 "expected immediate in range 32 .. 63");
4235 case Match_UImm5_33:
4236 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4237 "expected immediate in range 33 .. 64");
4238 case Match_UImm5_0_Report_UImm6:
4239 // This is used on UImm5 operands that have a corresponding UImm5_32
4240 // operand to avoid confusing the user.
4241 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4242 "expected 6-bit unsigned immediate");
4243 case Match_UImm5_Lsl2:
4244 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4245 "expected both 7-bit unsigned immediate and multiple of 4");
4246 case Match_UImmRange2_64:
4247 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4248 "expected immediate in range 2 .. 64");
4250 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4251 "expected 6-bit unsigned immediate");
4252 case Match_UImm6_Lsl2:
4253 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4254 "expected both 8-bit unsigned immediate and multiple of 4");
4256 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4257 "expected 6-bit signed immediate");
4259 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4260 "expected 7-bit unsigned immediate");
4261 case Match_UImm7_N1:
4262 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4263 "expected immediate in range -1 .. 126");
4264 case Match_SImm7_Lsl2:
4265 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4266 "expected both 9-bit signed immediate and multiple of 4");
4268 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4269 "expected 8-bit unsigned immediate");
4270 case Match_UImm10_0:
4271 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4272 "expected 10-bit unsigned immediate");
4273 case Match_SImm10_0:
4274 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4275 "expected 10-bit signed immediate");
4276 case Match_SImm11_0:
4277 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4278 "expected 11-bit signed immediate");
4280 case Match_UImm16_Relaxed:
4281 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4282 "expected 16-bit unsigned immediate");
4284 case Match_SImm16_Relaxed:
4285 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4286 "expected 16-bit signed immediate");
4287 case Match_SImm19_Lsl2:
4288 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4289 "expected both 19-bit signed immediate and multiple of 4");
4290 case Match_UImm20_0:
4291 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4292 "expected 20-bit unsigned immediate");
4293 case Match_UImm26_0:
4294 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4295 "expected 26-bit unsigned immediate");
4297 case Match_SImm32_Relaxed:
4298 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4299 "expected 32-bit signed immediate");
4300 case Match_UImm32_Coerced:
4301 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4302 "expected 32-bit immediate");
4303 case Match_MemSImm9:
4304 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4305 "expected memory with 9-bit signed offset");
4306 case Match_MemSImm10:
4307 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4308 "expected memory with 10-bit signed offset");
4309 case Match_MemSImm10Lsl1:
4310 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4311 "expected memory with 11-bit signed offset and multiple of 2");
4312 case Match_MemSImm10Lsl2:
4313 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4314 "expected memory with 12-bit signed offset and multiple of 4");
4315 case Match_MemSImm10Lsl3:
4316 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4317 "expected memory with 13-bit signed offset and multiple of 8");
4318 case Match_MemSImm11:
4319 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4320 "expected memory with 11-bit signed offset");
4321 case Match_MemSImm12:
4322 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4323 "expected memory with 12-bit signed offset");
4324 case Match_MemSImm16:
4325 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4326 "expected memory with 16-bit signed offset");
4329 llvm_unreachable("Implement any new match types added!");
4332 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
4333 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
4334 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
4335 ") without \".set noat\"");
4338 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
4339 if (!AssemblerOptions.back()->isMacro())
4340 Warning(Loc, "macro instruction expanded into multiple instructions");
4344 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
4345 SMRange Range, bool ShowColors) {
4346 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
4347 Range, SMFixIt(Range, FixMsg),
4351 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
4354 CC = StringSwitch<unsigned>(Name)
4390 if (!(isABI_N32() || isABI_N64()))
4393 if (12 <= CC && CC <= 15) {
4394 // Name is one of t4-t7
4395 AsmToken RegTok = getLexer().peekTok();
4396 SMRange RegRange = RegTok.getLocRange();
4398 StringRef FixedName = StringSwitch<StringRef>(Name)
4404 assert(FixedName != "" && "Register name is not one of t4-t7.");
4406 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
4407 "Did you mean $" + FixedName + "?", RegRange);
4410 // Although SGI documentation just cuts out t0-t3 for n32/n64,
4411 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
4412 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
4413 if (8 <= CC && CC <= 11)
4417 CC = StringSwitch<unsigned>(Name)
4429 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
4432 CC = StringSwitch<unsigned>(Name)
4433 .Case("hwr_cpunum", 0)
4434 .Case("hwr_synci_step", 1)
4436 .Case("hwr_ccres", 3)
4437 .Case("hwr_ulr", 29)
4443 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
4445 if (Name[0] == 'f') {
4446 StringRef NumString = Name.substr(1);
4448 if (NumString.getAsInteger(10, IntVal))
4449 return -1; // This is not an integer.
4450 if (IntVal > 31) // Maximum index for fpu register.
4457 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
4459 if (Name.startswith("fcc")) {
4460 StringRef NumString = Name.substr(3);
4462 if (NumString.getAsInteger(10, IntVal))
4463 return -1; // This is not an integer.
4464 if (IntVal > 7) // There are only 8 fcc registers.
4471 int MipsAsmParser::matchACRegisterName(StringRef Name) {
4473 if (Name.startswith("ac")) {
4474 StringRef NumString = Name.substr(2);
4476 if (NumString.getAsInteger(10, IntVal))
4477 return -1; // This is not an integer.
4478 if (IntVal > 3) // There are only 3 acc registers.
4485 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
4488 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
4497 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4500 CC = StringSwitch<unsigned>(Name)
4503 .Case("msaaccess", 2)
4505 .Case("msamodify", 4)
4506 .Case("msarequest", 5)
4508 .Case("msaunmap", 7)
4514 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
4515 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4517 reportParseError(Loc,
4518 "pseudo-instruction requires $at, which is not available");
4521 unsigned AT = getReg(
4522 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4526 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
4527 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4530 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
4531 MCAsmParser &Parser = getParser();
4532 DEBUG(dbgs() << "parseOperand\n");
4534 // Check if the current operand has a custom associated parser, if so, try to
4535 // custom parse the operand, or fallback to the general approach.
4536 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4537 if (ResTy == MatchOperand_Success)
4539 // If there wasn't a custom match, try the generic matcher below. Otherwise,
4540 // there was a match, but an error occurred, in which case, just return that
4541 // the operand parsing failed.
4542 if (ResTy == MatchOperand_ParseFail)
4545 DEBUG(dbgs() << ".. Generic Parser\n");
4547 switch (getLexer().getKind()) {
4548 case AsmToken::Dollar: {
4549 // Parse the register.
4550 SMLoc S = Parser.getTok().getLoc();
4552 // Almost all registers have been parsed by custom parsers. There is only
4553 // one exception to this. $zero (and it's alias $0) will reach this point
4554 // for div, divu, and similar instructions because it is not an operand
4555 // to the instruction definition but an explicit register. Special case
4556 // this situation for now.
4557 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
4560 // Maybe it is a symbol reference.
4561 StringRef Identifier;
4562 if (Parser.parseIdentifier(Identifier))
4565 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4566 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
4567 // Otherwise create a symbol reference.
4569 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
4571 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
4575 DEBUG(dbgs() << ".. generic integer expression\n");
4578 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
4579 if (getParser().parseExpression(Expr))
4582 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4584 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
4587 } // switch(getLexer().getKind())
4591 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4593 switch (Expr->getKind()) {
4594 case MCExpr::Constant:
4596 case MCExpr::SymbolRef:
4597 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4598 case MCExpr::Binary:
4599 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4600 if (!isEvaluated(BE->getLHS()))
4602 return isEvaluated(BE->getRHS());
4605 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4606 case MCExpr::Target:
4612 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4614 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4615 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4616 if (ResTy == MatchOperand_Success) {
4617 assert(Operands.size() == 1);
4618 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4619 StartLoc = Operand.getStartLoc();
4620 EndLoc = Operand.getEndLoc();
4622 // AFAIK, we only support numeric registers and named GPR's in CFI
4624 // Don't worry about eating tokens before failing. Using an unrecognised
4625 // register is a parse error.
4626 if (Operand.isGPRAsmReg()) {
4627 // Resolve to GPR32 or GPR64 appropriately.
4628 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4631 return (RegNo == (unsigned)-1);
4634 assert(Operands.size() == 0);
4635 return (RegNo == (unsigned)-1);
4638 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4642 return getParser().parseParenExprOfDepth(0, Res, S);
4643 return getParser().parseExpression(Res);
4646 OperandMatchResultTy
4647 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4648 MCAsmParser &Parser = getParser();
4649 DEBUG(dbgs() << "parseMemOperand\n");
4650 const MCExpr *IdVal = nullptr;
4652 bool isParenExpr = false;
4653 OperandMatchResultTy Res = MatchOperand_NoMatch;
4654 // First operand is the offset.
4655 S = Parser.getTok().getLoc();
4657 if (getLexer().getKind() == AsmToken::LParen) {
4662 if (getLexer().getKind() != AsmToken::Dollar) {
4663 if (parseMemOffset(IdVal, isParenExpr))
4664 return MatchOperand_ParseFail;
4666 const AsmToken &Tok = Parser.getTok(); // Get the next token.
4667 if (Tok.isNot(AsmToken::LParen)) {
4668 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4669 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4671 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4672 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4673 return MatchOperand_Success;
4675 if (Tok.is(AsmToken::EndOfStatement)) {
4677 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4679 // Zero register assumed, add a memory operand with ZERO as its base.
4680 // "Base" will be managed by k_Memory.
4681 auto Base = MipsOperand::createGPRReg(
4682 0, "0", getContext().getRegisterInfo(), S, E, *this);
4684 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4685 return MatchOperand_Success;
4687 MCBinaryExpr::Opcode Opcode;
4688 // GAS and LLVM treat comparison operators different. GAS will generate -1
4689 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
4690 // highly unlikely to be found in a memory offset expression, we don't
4692 switch (Tok.getKind()) {
4693 case AsmToken::Plus:
4694 Opcode = MCBinaryExpr::Add;
4697 case AsmToken::Minus:
4698 Opcode = MCBinaryExpr::Sub;
4701 case AsmToken::Star:
4702 Opcode = MCBinaryExpr::Mul;
4705 case AsmToken::Pipe:
4706 Opcode = MCBinaryExpr::Or;
4710 Opcode = MCBinaryExpr::And;
4713 case AsmToken::LessLess:
4714 Opcode = MCBinaryExpr::Shl;
4717 case AsmToken::GreaterGreater:
4718 Opcode = MCBinaryExpr::LShr;
4721 case AsmToken::Caret:
4722 Opcode = MCBinaryExpr::Xor;
4725 case AsmToken::Slash:
4726 Opcode = MCBinaryExpr::Div;
4729 case AsmToken::Percent:
4730 Opcode = MCBinaryExpr::Mod;
4734 Error(Parser.getTok().getLoc(), "'(' or expression expected");
4735 return MatchOperand_ParseFail;
4737 const MCExpr * NextExpr;
4738 if (getParser().parseExpression(NextExpr))
4739 return MatchOperand_ParseFail;
4740 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
4743 Parser.Lex(); // Eat the '(' token.
4746 Res = parseAnyRegister(Operands);
4747 if (Res != MatchOperand_Success)
4750 if (Parser.getTok().isNot(AsmToken::RParen)) {
4751 Error(Parser.getTok().getLoc(), "')' expected");
4752 return MatchOperand_ParseFail;
4755 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4757 Parser.Lex(); // Eat the ')' token.
4760 IdVal = MCConstantExpr::create(0, getContext());
4762 // Replace the register operand with the memory operand.
4763 std::unique_ptr<MipsOperand> op(
4764 static_cast<MipsOperand *>(Operands.back().release()));
4765 // Remove the register from the operands.
4766 // "op" will be managed by k_Memory.
4767 Operands.pop_back();
4768 // Add the memory operand.
4769 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4771 if (IdVal->evaluateAsAbsolute(Imm))
4772 IdVal = MCConstantExpr::create(Imm, getContext());
4773 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4774 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4778 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4779 return MatchOperand_Success;
4782 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4783 MCAsmParser &Parser = getParser();
4784 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4786 SMLoc S = Parser.getTok().getLoc();
4788 if (Sym->isVariable())
4789 Expr = Sym->getVariableValue();
4792 if (Expr->getKind() == MCExpr::SymbolRef) {
4793 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4794 StringRef DefSymbol = Ref->getSymbol().getName();
4795 if (DefSymbol.startswith("$")) {
4796 OperandMatchResultTy ResTy =
4797 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4798 if (ResTy == MatchOperand_Success) {
4801 } else if (ResTy == MatchOperand_ParseFail)
4802 llvm_unreachable("Should never ParseFail");
4810 OperandMatchResultTy
4811 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4812 StringRef Identifier,
4814 int Index = matchCPURegisterName(Identifier);
4816 Operands.push_back(MipsOperand::createGPRReg(
4817 Index, Identifier, getContext().getRegisterInfo(), S,
4818 getLexer().getLoc(), *this));
4819 return MatchOperand_Success;
4822 Index = matchHWRegsRegisterName(Identifier);
4824 Operands.push_back(MipsOperand::createHWRegsReg(
4825 Index, Identifier, getContext().getRegisterInfo(), S,
4826 getLexer().getLoc(), *this));
4827 return MatchOperand_Success;
4830 Index = matchFPURegisterName(Identifier);
4832 Operands.push_back(MipsOperand::createFGRReg(
4833 Index, Identifier, getContext().getRegisterInfo(), S,
4834 getLexer().getLoc(), *this));
4835 return MatchOperand_Success;
4838 Index = matchFCCRegisterName(Identifier);
4840 Operands.push_back(MipsOperand::createFCCReg(
4841 Index, Identifier, getContext().getRegisterInfo(), S,
4842 getLexer().getLoc(), *this));
4843 return MatchOperand_Success;
4846 Index = matchACRegisterName(Identifier);
4848 Operands.push_back(MipsOperand::createACCReg(
4849 Index, Identifier, getContext().getRegisterInfo(), S,
4850 getLexer().getLoc(), *this));
4851 return MatchOperand_Success;
4854 Index = matchMSA128RegisterName(Identifier);
4856 Operands.push_back(MipsOperand::createMSA128Reg(
4857 Index, Identifier, getContext().getRegisterInfo(), S,
4858 getLexer().getLoc(), *this));
4859 return MatchOperand_Success;
4862 Index = matchMSA128CtrlRegisterName(Identifier);
4864 Operands.push_back(MipsOperand::createMSACtrlReg(
4865 Index, Identifier, getContext().getRegisterInfo(), S,
4866 getLexer().getLoc(), *this));
4867 return MatchOperand_Success;
4870 return MatchOperand_NoMatch;
4873 OperandMatchResultTy
4874 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4875 MCAsmParser &Parser = getParser();
4876 auto Token = Parser.getLexer().peekTok(false);
4878 if (Token.is(AsmToken::Identifier)) {
4879 DEBUG(dbgs() << ".. identifier\n");
4880 StringRef Identifier = Token.getIdentifier();
4881 OperandMatchResultTy ResTy =
4882 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4884 } else if (Token.is(AsmToken::Integer)) {
4885 DEBUG(dbgs() << ".. integer\n");
4886 Operands.push_back(MipsOperand::createNumericReg(
4887 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
4888 Token.getLoc(), *this));
4889 return MatchOperand_Success;
4892 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4894 return MatchOperand_NoMatch;
4897 OperandMatchResultTy
4898 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4899 MCAsmParser &Parser = getParser();
4900 DEBUG(dbgs() << "parseAnyRegister\n");
4902 auto Token = Parser.getTok();
4904 SMLoc S = Token.getLoc();
4906 if (Token.isNot(AsmToken::Dollar)) {
4907 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4908 if (Token.is(AsmToken::Identifier)) {
4909 if (searchSymbolAlias(Operands))
4910 return MatchOperand_Success;
4912 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4913 return MatchOperand_NoMatch;
4915 DEBUG(dbgs() << ".. $\n");
4917 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4918 if (ResTy == MatchOperand_Success) {
4920 Parser.Lex(); // identifier
4925 OperandMatchResultTy
4926 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4927 MCAsmParser &Parser = getParser();
4928 DEBUG(dbgs() << "parseJumpTarget\n");
4930 SMLoc S = getLexer().getLoc();
4932 // Registers are a valid target and have priority over symbols.
4933 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4934 if (ResTy != MatchOperand_NoMatch)
4937 // Integers and expressions are acceptable
4938 const MCExpr *Expr = nullptr;
4939 if (Parser.parseExpression(Expr)) {
4940 // We have no way of knowing if a symbol was consumed so we must ParseFail
4941 return MatchOperand_ParseFail;
4944 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4945 return MatchOperand_Success;
4948 OperandMatchResultTy
4949 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4950 MCAsmParser &Parser = getParser();
4951 const MCExpr *IdVal;
4952 // If the first token is '$' we may have register operand.
4953 if (Parser.getTok().is(AsmToken::Dollar))
4954 return MatchOperand_NoMatch;
4955 SMLoc S = Parser.getTok().getLoc();
4956 if (getParser().parseExpression(IdVal))
4957 return MatchOperand_ParseFail;
4958 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4959 assert(MCE && "Unexpected MCExpr type.");
4960 int64_t Val = MCE->getValue();
4961 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4962 Operands.push_back(MipsOperand::CreateImm(
4963 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4964 return MatchOperand_Success;
4967 OperandMatchResultTy
4968 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4969 MCAsmParser &Parser = getParser();
4970 SmallVector<unsigned, 10> Regs;
4972 unsigned PrevReg = Mips::NoRegister;
4973 bool RegRange = false;
4974 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4976 if (Parser.getTok().isNot(AsmToken::Dollar))
4977 return MatchOperand_ParseFail;
4979 SMLoc S = Parser.getTok().getLoc();
4980 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4981 SMLoc E = getLexer().getLoc();
4982 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4983 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4985 // Remove last register operand because registers from register range
4986 // should be inserted first.
4987 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4988 (!isGP64bit() && RegNo == Mips::RA)) {
4989 Regs.push_back(RegNo);
4991 unsigned TmpReg = PrevReg + 1;
4992 while (TmpReg <= RegNo) {
4993 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4994 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4996 Error(E, "invalid register operand");
4997 return MatchOperand_ParseFail;
5001 Regs.push_back(TmpReg++);
5007 if ((PrevReg == Mips::NoRegister) &&
5008 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5009 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5010 Error(E, "$16 or $31 expected");
5011 return MatchOperand_ParseFail;
5012 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5013 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5015 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5016 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5018 Error(E, "invalid register operand");
5019 return MatchOperand_ParseFail;
5020 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5021 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5022 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5024 Error(E, "consecutive register numbers expected");
5025 return MatchOperand_ParseFail;
5028 Regs.push_back(RegNo);
5031 if (Parser.getTok().is(AsmToken::Minus))
5034 if (!Parser.getTok().isNot(AsmToken::Minus) &&
5035 !Parser.getTok().isNot(AsmToken::Comma)) {
5036 Error(E, "',' or '-' expected");
5037 return MatchOperand_ParseFail;
5040 Lex(); // Consume comma or minus
5041 if (Parser.getTok().isNot(AsmToken::Dollar))
5047 SMLoc E = Parser.getTok().getLoc();
5048 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5049 parseMemOperand(Operands);
5050 return MatchOperand_Success;
5053 OperandMatchResultTy
5054 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
5055 MCAsmParser &Parser = getParser();
5057 SMLoc S = Parser.getTok().getLoc();
5058 if (parseAnyRegister(Operands) != MatchOperand_Success)
5059 return MatchOperand_ParseFail;
5061 SMLoc E = Parser.getTok().getLoc();
5062 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
5064 Operands.pop_back();
5065 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
5066 return MatchOperand_Success;
5069 OperandMatchResultTy
5070 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
5071 MCAsmParser &Parser = getParser();
5072 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5073 SmallVector<unsigned, 10> Regs;
5075 if (Parser.getTok().isNot(AsmToken::Dollar))
5076 return MatchOperand_ParseFail;
5078 SMLoc S = Parser.getTok().getLoc();
5080 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5081 return MatchOperand_ParseFail;
5083 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5084 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5085 Regs.push_back(RegNo);
5087 SMLoc E = Parser.getTok().getLoc();
5088 if (Parser.getTok().isNot(AsmToken::Comma)) {
5089 Error(E, "',' expected");
5090 return MatchOperand_ParseFail;
5096 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5097 return MatchOperand_ParseFail;
5099 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5100 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5101 Regs.push_back(RegNo);
5103 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5105 return MatchOperand_Success;
5108 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
5110 /// ::= '(', register, ')'
5111 /// handle it before we iterate so we don't get tripped up by the lack of
5113 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
5114 MCAsmParser &Parser = getParser();
5115 if (getLexer().is(AsmToken::LParen)) {
5117 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
5119 if (parseOperand(Operands, Name)) {
5120 SMLoc Loc = getLexer().getLoc();
5121 return Error(Loc, "unexpected token in argument list");
5123 if (Parser.getTok().isNot(AsmToken::RParen)) {
5124 SMLoc Loc = getLexer().getLoc();
5125 return Error(Loc, "unexpected token, expected ')'");
5128 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
5134 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
5135 /// either one of these.
5136 /// ::= '[', register, ']'
5137 /// ::= '[', integer, ']'
5138 /// handle it before we iterate so we don't get tripped up by the lack of
5140 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
5141 OperandVector &Operands) {
5142 MCAsmParser &Parser = getParser();
5143 if (getLexer().is(AsmToken::LBrac)) {
5145 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
5147 if (parseOperand(Operands, Name)) {
5148 SMLoc Loc = getLexer().getLoc();
5149 return Error(Loc, "unexpected token in argument list");
5151 if (Parser.getTok().isNot(AsmToken::RBrac)) {
5152 SMLoc Loc = getLexer().getLoc();
5153 return Error(Loc, "unexpected token, expected ']'");
5156 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
5162 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
5163 SMLoc NameLoc, OperandVector &Operands) {
5164 MCAsmParser &Parser = getParser();
5165 DEBUG(dbgs() << "ParseInstruction\n");
5167 // We have reached first instruction, module directive are now forbidden.
5168 getTargetStreamer().forbidModuleDirective();
5170 // Check if we have valid mnemonic
5171 if (!mnemonicIsValid(Name, 0)) {
5172 return Error(NameLoc, "unknown instruction");
5174 // First operand in MCInst is instruction mnemonic.
5175 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
5177 // Read the remaining operands.
5178 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5179 // Read the first operand.
5180 if (parseOperand(Operands, Name)) {
5181 SMLoc Loc = getLexer().getLoc();
5182 return Error(Loc, "unexpected token in argument list");
5184 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
5186 // AFAIK, parenthesis suffixes are never on the first operand
5188 while (getLexer().is(AsmToken::Comma)) {
5189 Parser.Lex(); // Eat the comma.
5190 // Parse and remember the operand.
5191 if (parseOperand(Operands, Name)) {
5192 SMLoc Loc = getLexer().getLoc();
5193 return Error(Loc, "unexpected token in argument list");
5195 // Parse bracket and parenthesis suffixes before we iterate
5196 if (getLexer().is(AsmToken::LBrac)) {
5197 if (parseBracketSuffix(Name, Operands))
5199 } else if (getLexer().is(AsmToken::LParen) &&
5200 parseParenSuffix(Name, Operands))
5204 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5205 SMLoc Loc = getLexer().getLoc();
5206 return Error(Loc, "unexpected token in argument list");
5208 Parser.Lex(); // Consume the EndOfStatement.
5212 // FIXME: Given that these have the same name, these should both be
5213 // consistent on affecting the Parser.
5214 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
5215 SMLoc Loc = getLexer().getLoc();
5216 return Error(Loc, ErrorMsg);
5219 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
5220 return Error(Loc, ErrorMsg);
5223 bool MipsAsmParser::parseSetNoAtDirective() {
5224 MCAsmParser &Parser = getParser();
5225 // Line should look like: ".set noat".
5227 // Set the $at register to $0.
5228 AssemblerOptions.back()->setATRegIndex(0);
5230 Parser.Lex(); // Eat "noat".
5232 // If this is not the end of the statement, report an error.
5233 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5234 reportParseError("unexpected token, expected end of statement");
5238 getTargetStreamer().emitDirectiveSetNoAt();
5239 Parser.Lex(); // Consume the EndOfStatement.
5243 bool MipsAsmParser::parseSetAtDirective() {
5244 // Line can be: ".set at", which sets $at to $1
5245 // or ".set at=$reg", which sets $at to $reg.
5246 MCAsmParser &Parser = getParser();
5247 Parser.Lex(); // Eat "at".
5249 if (getLexer().is(AsmToken::EndOfStatement)) {
5250 // No register was specified, so we set $at to $1.
5251 AssemblerOptions.back()->setATRegIndex(1);
5253 getTargetStreamer().emitDirectiveSetAt();
5254 Parser.Lex(); // Consume the EndOfStatement.
5258 if (getLexer().isNot(AsmToken::Equal)) {
5259 reportParseError("unexpected token, expected equals sign");
5262 Parser.Lex(); // Eat "=".
5264 if (getLexer().isNot(AsmToken::Dollar)) {
5265 if (getLexer().is(AsmToken::EndOfStatement)) {
5266 reportParseError("no register specified");
5269 reportParseError("unexpected token, expected dollar sign '$'");
5273 Parser.Lex(); // Eat "$".
5275 // Find out what "reg" is.
5277 const AsmToken &Reg = Parser.getTok();
5278 if (Reg.is(AsmToken::Identifier)) {
5279 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
5280 } else if (Reg.is(AsmToken::Integer)) {
5281 AtRegNo = Reg.getIntVal();
5283 reportParseError("unexpected token, expected identifier or integer");
5287 // Check if $reg is a valid register. If it is, set $at to $reg.
5288 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
5289 reportParseError("invalid register");
5292 Parser.Lex(); // Eat "reg".
5294 // If this is not the end of the statement, report an error.
5295 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5296 reportParseError("unexpected token, expected end of statement");
5300 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
5302 Parser.Lex(); // Consume the EndOfStatement.
5306 bool MipsAsmParser::parseSetReorderDirective() {
5307 MCAsmParser &Parser = getParser();
5309 // If this is not the end of the statement, report an error.
5310 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5311 reportParseError("unexpected token, expected end of statement");
5314 AssemblerOptions.back()->setReorder();
5315 getTargetStreamer().emitDirectiveSetReorder();
5316 Parser.Lex(); // Consume the EndOfStatement.
5320 bool MipsAsmParser::parseSetNoReorderDirective() {
5321 MCAsmParser &Parser = getParser();
5323 // If this is not the end of the statement, report an error.
5324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5325 reportParseError("unexpected token, expected end of statement");
5328 AssemblerOptions.back()->setNoReorder();
5329 getTargetStreamer().emitDirectiveSetNoReorder();
5330 Parser.Lex(); // Consume the EndOfStatement.
5334 bool MipsAsmParser::parseSetMacroDirective() {
5335 MCAsmParser &Parser = getParser();
5337 // If this is not the end of the statement, report an error.
5338 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5339 reportParseError("unexpected token, expected end of statement");
5342 AssemblerOptions.back()->setMacro();
5343 getTargetStreamer().emitDirectiveSetMacro();
5344 Parser.Lex(); // Consume the EndOfStatement.
5348 bool MipsAsmParser::parseSetNoMacroDirective() {
5349 MCAsmParser &Parser = getParser();
5351 // If this is not the end of the statement, report an error.
5352 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5353 reportParseError("unexpected token, expected end of statement");
5356 if (AssemblerOptions.back()->isReorder()) {
5357 reportParseError("`noreorder' must be set before `nomacro'");
5360 AssemblerOptions.back()->setNoMacro();
5361 getTargetStreamer().emitDirectiveSetNoMacro();
5362 Parser.Lex(); // Consume the EndOfStatement.
5366 bool MipsAsmParser::parseSetMsaDirective() {
5367 MCAsmParser &Parser = getParser();
5370 // If this is not the end of the statement, report an error.
5371 if (getLexer().isNot(AsmToken::EndOfStatement))
5372 return reportParseError("unexpected token, expected end of statement");
5374 setFeatureBits(Mips::FeatureMSA, "msa");
5375 getTargetStreamer().emitDirectiveSetMsa();
5379 bool MipsAsmParser::parseSetNoMsaDirective() {
5380 MCAsmParser &Parser = getParser();
5383 // If this is not the end of the statement, report an error.
5384 if (getLexer().isNot(AsmToken::EndOfStatement))
5385 return reportParseError("unexpected token, expected end of statement");
5387 clearFeatureBits(Mips::FeatureMSA, "msa");
5388 getTargetStreamer().emitDirectiveSetNoMsa();
5392 bool MipsAsmParser::parseSetNoDspDirective() {
5393 MCAsmParser &Parser = getParser();
5394 Parser.Lex(); // Eat "nodsp".
5396 // If this is not the end of the statement, report an error.
5397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5398 reportParseError("unexpected token, expected end of statement");
5402 clearFeatureBits(Mips::FeatureDSP, "dsp");
5403 getTargetStreamer().emitDirectiveSetNoDsp();
5407 bool MipsAsmParser::parseSetMips16Directive() {
5408 MCAsmParser &Parser = getParser();
5409 Parser.Lex(); // Eat "mips16".
5411 // If this is not the end of the statement, report an error.
5412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5413 reportParseError("unexpected token, expected end of statement");
5417 setFeatureBits(Mips::FeatureMips16, "mips16");
5418 getTargetStreamer().emitDirectiveSetMips16();
5419 Parser.Lex(); // Consume the EndOfStatement.
5423 bool MipsAsmParser::parseSetNoMips16Directive() {
5424 MCAsmParser &Parser = getParser();
5425 Parser.Lex(); // Eat "nomips16".
5427 // If this is not the end of the statement, report an error.
5428 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5429 reportParseError("unexpected token, expected end of statement");
5433 clearFeatureBits(Mips::FeatureMips16, "mips16");
5434 getTargetStreamer().emitDirectiveSetNoMips16();
5435 Parser.Lex(); // Consume the EndOfStatement.
5439 bool MipsAsmParser::parseSetFpDirective() {
5440 MCAsmParser &Parser = getParser();
5441 MipsABIFlagsSection::FpABIKind FpAbiVal;
5442 // Line can be: .set fp=32
5445 Parser.Lex(); // Eat fp token
5446 AsmToken Tok = Parser.getTok();
5447 if (Tok.isNot(AsmToken::Equal)) {
5448 reportParseError("unexpected token, expected equals sign '='");
5451 Parser.Lex(); // Eat '=' token.
5452 Tok = Parser.getTok();
5454 if (!parseFpABIValue(FpAbiVal, ".set"))
5457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5458 reportParseError("unexpected token, expected end of statement");
5461 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5462 Parser.Lex(); // Consume the EndOfStatement.
5466 bool MipsAsmParser::parseSetOddSPRegDirective() {
5467 MCAsmParser &Parser = getParser();
5469 Parser.Lex(); // Eat "oddspreg".
5470 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5471 reportParseError("unexpected token, expected end of statement");
5475 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5476 getTargetStreamer().emitDirectiveSetOddSPReg();
5480 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5481 MCAsmParser &Parser = getParser();
5483 Parser.Lex(); // Eat "nooddspreg".
5484 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5485 reportParseError("unexpected token, expected end of statement");
5489 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5490 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5494 bool MipsAsmParser::parseSetPopDirective() {
5495 MCAsmParser &Parser = getParser();
5496 SMLoc Loc = getLexer().getLoc();
5499 if (getLexer().isNot(AsmToken::EndOfStatement))
5500 return reportParseError("unexpected token, expected end of statement");
5502 // Always keep an element on the options "stack" to prevent the user
5503 // from changing the initial options. This is how we remember them.
5504 if (AssemblerOptions.size() == 2)
5505 return reportParseError(Loc, ".set pop with no .set push");
5507 MCSubtargetInfo &STI = copySTI();
5508 AssemblerOptions.pop_back();
5509 setAvailableFeatures(
5510 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5511 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5513 getTargetStreamer().emitDirectiveSetPop();
5517 bool MipsAsmParser::parseSetPushDirective() {
5518 MCAsmParser &Parser = getParser();
5520 if (getLexer().isNot(AsmToken::EndOfStatement))
5521 return reportParseError("unexpected token, expected end of statement");
5523 // Create a copy of the current assembler options environment and push it.
5524 AssemblerOptions.push_back(
5525 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5527 getTargetStreamer().emitDirectiveSetPush();
5531 bool MipsAsmParser::parseSetSoftFloatDirective() {
5532 MCAsmParser &Parser = getParser();
5534 if (getLexer().isNot(AsmToken::EndOfStatement))
5535 return reportParseError("unexpected token, expected end of statement");
5537 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5538 getTargetStreamer().emitDirectiveSetSoftFloat();
5542 bool MipsAsmParser::parseSetHardFloatDirective() {
5543 MCAsmParser &Parser = getParser();
5545 if (getLexer().isNot(AsmToken::EndOfStatement))
5546 return reportParseError("unexpected token, expected end of statement");
5548 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5549 getTargetStreamer().emitDirectiveSetHardFloat();
5553 bool MipsAsmParser::parseSetAssignment() {
5555 const MCExpr *Value;
5556 MCAsmParser &Parser = getParser();
5558 if (Parser.parseIdentifier(Name))
5559 reportParseError("expected identifier after .set");
5561 if (getLexer().isNot(AsmToken::Comma))
5562 return reportParseError("unexpected token, expected comma");
5565 if (Parser.parseExpression(Value))
5566 return reportParseError("expected valid expression after comma");
5568 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5569 Sym->setVariableValue(Value);
5574 bool MipsAsmParser::parseSetMips0Directive() {
5575 MCAsmParser &Parser = getParser();
5577 if (getLexer().isNot(AsmToken::EndOfStatement))
5578 return reportParseError("unexpected token, expected end of statement");
5580 // Reset assembler options to their initial values.
5581 MCSubtargetInfo &STI = copySTI();
5582 setAvailableFeatures(
5583 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5584 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5585 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5587 getTargetStreamer().emitDirectiveSetMips0();
5591 bool MipsAsmParser::parseSetArchDirective() {
5592 MCAsmParser &Parser = getParser();
5594 if (getLexer().isNot(AsmToken::Equal))
5595 return reportParseError("unexpected token, expected equals sign");
5599 if (Parser.parseIdentifier(Arch))
5600 return reportParseError("expected arch identifier");
5602 StringRef ArchFeatureName =
5603 StringSwitch<StringRef>(Arch)
5604 .Case("mips1", "mips1")
5605 .Case("mips2", "mips2")
5606 .Case("mips3", "mips3")
5607 .Case("mips4", "mips4")
5608 .Case("mips5", "mips5")
5609 .Case("mips32", "mips32")
5610 .Case("mips32r2", "mips32r2")
5611 .Case("mips32r3", "mips32r3")
5612 .Case("mips32r5", "mips32r5")
5613 .Case("mips32r6", "mips32r6")
5614 .Case("mips64", "mips64")
5615 .Case("mips64r2", "mips64r2")
5616 .Case("mips64r3", "mips64r3")
5617 .Case("mips64r5", "mips64r5")
5618 .Case("mips64r6", "mips64r6")
5619 .Case("octeon", "cnmips")
5620 .Case("r4000", "mips3") // This is an implementation of Mips3.
5623 if (ArchFeatureName.empty())
5624 return reportParseError("unsupported architecture");
5626 selectArch(ArchFeatureName);
5627 getTargetStreamer().emitDirectiveSetArch(Arch);
5631 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5632 MCAsmParser &Parser = getParser();
5634 if (getLexer().isNot(AsmToken::EndOfStatement))
5635 return reportParseError("unexpected token, expected end of statement");
5639 llvm_unreachable("Unimplemented feature");
5640 case Mips::FeatureDSP:
5641 setFeatureBits(Mips::FeatureDSP, "dsp");
5642 getTargetStreamer().emitDirectiveSetDsp();
5644 case Mips::FeatureMicroMips:
5645 setFeatureBits(Mips::FeatureMicroMips, "micromips");
5646 getTargetStreamer().emitDirectiveSetMicroMips();
5648 case Mips::FeatureMips1:
5649 selectArch("mips1");
5650 getTargetStreamer().emitDirectiveSetMips1();
5652 case Mips::FeatureMips2:
5653 selectArch("mips2");
5654 getTargetStreamer().emitDirectiveSetMips2();
5656 case Mips::FeatureMips3:
5657 selectArch("mips3");
5658 getTargetStreamer().emitDirectiveSetMips3();
5660 case Mips::FeatureMips4:
5661 selectArch("mips4");
5662 getTargetStreamer().emitDirectiveSetMips4();
5664 case Mips::FeatureMips5:
5665 selectArch("mips5");
5666 getTargetStreamer().emitDirectiveSetMips5();
5668 case Mips::FeatureMips32:
5669 selectArch("mips32");
5670 getTargetStreamer().emitDirectiveSetMips32();
5672 case Mips::FeatureMips32r2:
5673 selectArch("mips32r2");
5674 getTargetStreamer().emitDirectiveSetMips32R2();
5676 case Mips::FeatureMips32r3:
5677 selectArch("mips32r3");
5678 getTargetStreamer().emitDirectiveSetMips32R3();
5680 case Mips::FeatureMips32r5:
5681 selectArch("mips32r5");
5682 getTargetStreamer().emitDirectiveSetMips32R5();
5684 case Mips::FeatureMips32r6:
5685 selectArch("mips32r6");
5686 getTargetStreamer().emitDirectiveSetMips32R6();
5688 case Mips::FeatureMips64:
5689 selectArch("mips64");
5690 getTargetStreamer().emitDirectiveSetMips64();
5692 case Mips::FeatureMips64r2:
5693 selectArch("mips64r2");
5694 getTargetStreamer().emitDirectiveSetMips64R2();
5696 case Mips::FeatureMips64r3:
5697 selectArch("mips64r3");
5698 getTargetStreamer().emitDirectiveSetMips64R3();
5700 case Mips::FeatureMips64r5:
5701 selectArch("mips64r5");
5702 getTargetStreamer().emitDirectiveSetMips64R5();
5704 case Mips::FeatureMips64r6:
5705 selectArch("mips64r6");
5706 getTargetStreamer().emitDirectiveSetMips64R6();
5712 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5713 MCAsmParser &Parser = getParser();
5714 if (getLexer().isNot(AsmToken::Comma)) {
5715 SMLoc Loc = getLexer().getLoc();
5716 return Error(Loc, ErrorStr);
5719 Parser.Lex(); // Eat the comma.
5723 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5724 // In this class, it is only used for .cprestore.
5725 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5726 // MipsTargetELFStreamer and MipsAsmParser.
5727 bool MipsAsmParser::isPicAndNotNxxAbi() {
5728 return inPicMode() && !(isABI_N32() || isABI_N64());
5731 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5732 if (AssemblerOptions.back()->isReorder())
5733 Warning(Loc, ".cpload should be inside a noreorder section");
5735 if (inMips16Mode()) {
5736 reportParseError(".cpload is not supported in Mips16 mode");
5740 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5741 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5742 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5743 reportParseError("expected register containing function address");
5747 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5748 if (!RegOpnd.isGPRAsmReg()) {
5749 reportParseError(RegOpnd.getStartLoc(), "invalid register");
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");
5759 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5763 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5764 MCAsmParser &Parser = getParser();
5766 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5767 // is used in non-PIC mode.
5769 if (inMips16Mode()) {
5770 reportParseError(".cprestore is not supported in Mips16 mode");
5774 // Get the stack offset value.
5775 const MCExpr *StackOffset;
5776 int64_t StackOffsetVal;
5777 if (Parser.parseExpression(StackOffset)) {
5778 reportParseError("expected stack offset value");
5782 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5783 reportParseError("stack offset is not an absolute expression");
5787 if (StackOffsetVal < 0) {
5788 Warning(Loc, ".cprestore with negative stack offset has no effect");
5789 IsCpRestoreSet = false;
5791 IsCpRestoreSet = true;
5792 CpRestoreOffset = StackOffsetVal;
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");
5801 if (!getTargetStreamer().emitDirectiveCpRestore(
5802 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
5804 Parser.Lex(); // Consume the EndOfStatement.
5808 bool MipsAsmParser::parseDirectiveCPSetup() {
5809 MCAsmParser &Parser = getParser();
5812 bool SaveIsReg = true;
5814 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5815 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5816 if (ResTy == MatchOperand_NoMatch) {
5817 reportParseError("expected register containing function address");
5821 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5822 if (!FuncRegOpnd.isGPRAsmReg()) {
5823 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5827 FuncReg = FuncRegOpnd.getGPR32Reg();
5830 if (!eatComma("unexpected token, expected comma"))
5833 ResTy = parseAnyRegister(TmpReg);
5834 if (ResTy == MatchOperand_NoMatch) {
5835 const MCExpr *OffsetExpr;
5837 SMLoc ExprLoc = getLexer().getLoc();
5839 if (Parser.parseExpression(OffsetExpr) ||
5840 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5841 reportParseError(ExprLoc, "expected save register or stack offset");
5848 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5849 if (!SaveOpnd.isGPRAsmReg()) {
5850 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5853 Save = SaveOpnd.getGPR32Reg();
5856 if (!eatComma("unexpected token, expected comma"))
5860 if (Parser.parseExpression(Expr)) {
5861 reportParseError("expected expression");
5865 if (Expr->getKind() != MCExpr::SymbolRef) {
5866 reportParseError("expected symbol");
5869 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5871 CpSaveLocation = Save;
5872 CpSaveLocationIsRegister = SaveIsReg;
5874 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5879 bool MipsAsmParser::parseDirectiveCPReturn() {
5880 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5881 CpSaveLocationIsRegister);
5885 bool MipsAsmParser::parseDirectiveNaN() {
5886 MCAsmParser &Parser = getParser();
5887 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5888 const AsmToken &Tok = Parser.getTok();
5890 if (Tok.getString() == "2008") {
5892 getTargetStreamer().emitDirectiveNaN2008();
5894 } else if (Tok.getString() == "legacy") {
5896 getTargetStreamer().emitDirectiveNaNLegacy();
5900 // If we don't recognize the option passed to the .nan
5901 // directive (e.g. no option or unknown option), emit an error.
5902 reportParseError("invalid option in .nan directive");
5906 bool MipsAsmParser::parseDirectiveSet() {
5907 MCAsmParser &Parser = getParser();
5908 // Get the next token.
5909 const AsmToken &Tok = Parser.getTok();
5911 if (Tok.getString() == "noat") {
5912 return parseSetNoAtDirective();
5913 } else if (Tok.getString() == "at") {
5914 return parseSetAtDirective();
5915 } else if (Tok.getString() == "arch") {
5916 return parseSetArchDirective();
5917 } else if (Tok.getString() == "fp") {
5918 return parseSetFpDirective();
5919 } else if (Tok.getString() == "oddspreg") {
5920 return parseSetOddSPRegDirective();
5921 } else if (Tok.getString() == "nooddspreg") {
5922 return parseSetNoOddSPRegDirective();
5923 } else if (Tok.getString() == "pop") {
5924 return parseSetPopDirective();
5925 } else if (Tok.getString() == "push") {
5926 return parseSetPushDirective();
5927 } else if (Tok.getString() == "reorder") {
5928 return parseSetReorderDirective();
5929 } else if (Tok.getString() == "noreorder") {
5930 return parseSetNoReorderDirective();
5931 } else if (Tok.getString() == "macro") {
5932 return parseSetMacroDirective();
5933 } else if (Tok.getString() == "nomacro") {
5934 return parseSetNoMacroDirective();
5935 } else if (Tok.getString() == "mips16") {
5936 return parseSetMips16Directive();
5937 } else if (Tok.getString() == "nomips16") {
5938 return parseSetNoMips16Directive();
5939 } else if (Tok.getString() == "nomicromips") {
5940 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
5941 getTargetStreamer().emitDirectiveSetNoMicroMips();
5942 Parser.eatToEndOfStatement();
5944 } else if (Tok.getString() == "micromips") {
5945 return parseSetFeature(Mips::FeatureMicroMips);
5946 } else if (Tok.getString() == "mips0") {
5947 return parseSetMips0Directive();
5948 } else if (Tok.getString() == "mips1") {
5949 return parseSetFeature(Mips::FeatureMips1);
5950 } else if (Tok.getString() == "mips2") {
5951 return parseSetFeature(Mips::FeatureMips2);
5952 } else if (Tok.getString() == "mips3") {
5953 return parseSetFeature(Mips::FeatureMips3);
5954 } else if (Tok.getString() == "mips4") {
5955 return parseSetFeature(Mips::FeatureMips4);
5956 } else if (Tok.getString() == "mips5") {
5957 return parseSetFeature(Mips::FeatureMips5);
5958 } else if (Tok.getString() == "mips32") {
5959 return parseSetFeature(Mips::FeatureMips32);
5960 } else if (Tok.getString() == "mips32r2") {
5961 return parseSetFeature(Mips::FeatureMips32r2);
5962 } else if (Tok.getString() == "mips32r3") {
5963 return parseSetFeature(Mips::FeatureMips32r3);
5964 } else if (Tok.getString() == "mips32r5") {
5965 return parseSetFeature(Mips::FeatureMips32r5);
5966 } else if (Tok.getString() == "mips32r6") {
5967 return parseSetFeature(Mips::FeatureMips32r6);
5968 } else if (Tok.getString() == "mips64") {
5969 return parseSetFeature(Mips::FeatureMips64);
5970 } else if (Tok.getString() == "mips64r2") {
5971 return parseSetFeature(Mips::FeatureMips64r2);
5972 } else if (Tok.getString() == "mips64r3") {
5973 return parseSetFeature(Mips::FeatureMips64r3);
5974 } else if (Tok.getString() == "mips64r5") {
5975 return parseSetFeature(Mips::FeatureMips64r5);
5976 } else if (Tok.getString() == "mips64r6") {
5977 return parseSetFeature(Mips::FeatureMips64r6);
5978 } else if (Tok.getString() == "dsp") {
5979 return parseSetFeature(Mips::FeatureDSP);
5980 } else if (Tok.getString() == "nodsp") {
5981 return parseSetNoDspDirective();
5982 } else if (Tok.getString() == "msa") {
5983 return parseSetMsaDirective();
5984 } else if (Tok.getString() == "nomsa") {
5985 return parseSetNoMsaDirective();
5986 } else if (Tok.getString() == "softfloat") {
5987 return parseSetSoftFloatDirective();
5988 } else if (Tok.getString() == "hardfloat") {
5989 return parseSetHardFloatDirective();
5991 // It is just an identifier, look for an assignment.
5992 parseSetAssignment();
5999 /// parseDataDirective
6000 /// ::= .word [ expression (, expression)* ]
6001 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
6002 MCAsmParser &Parser = getParser();
6003 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6005 const MCExpr *Value;
6006 if (getParser().parseExpression(Value))
6009 getParser().getStreamer().EmitValue(Value, Size);
6011 if (getLexer().is(AsmToken::EndOfStatement))
6014 if (getLexer().isNot(AsmToken::Comma))
6015 return Error(L, "unexpected token, expected comma");
6024 /// parseDirectiveGpWord
6025 /// ::= .gpword local_sym
6026 bool MipsAsmParser::parseDirectiveGpWord() {
6027 MCAsmParser &Parser = getParser();
6028 const MCExpr *Value;
6029 // EmitGPRel32Value requires an expression, so we are using base class
6030 // method to evaluate the expression.
6031 if (getParser().parseExpression(Value))
6033 getParser().getStreamer().EmitGPRel32Value(Value);
6035 if (getLexer().isNot(AsmToken::EndOfStatement))
6036 return Error(getLexer().getLoc(),
6037 "unexpected token, expected end of statement");
6038 Parser.Lex(); // Eat EndOfStatement token.
6042 /// parseDirectiveGpDWord
6043 /// ::= .gpdword local_sym
6044 bool MipsAsmParser::parseDirectiveGpDWord() {
6045 MCAsmParser &Parser = getParser();
6046 const MCExpr *Value;
6047 // EmitGPRel64Value requires an expression, so we are using base class
6048 // method to evaluate the expression.
6049 if (getParser().parseExpression(Value))
6051 getParser().getStreamer().EmitGPRel64Value(Value);
6053 if (getLexer().isNot(AsmToken::EndOfStatement))
6054 return Error(getLexer().getLoc(),
6055 "unexpected token, expected end of statement");
6056 Parser.Lex(); // Eat EndOfStatement token.
6060 /// parseDirectiveDtpRelWord
6061 /// ::= .dtprelword tls_sym
6062 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6063 MCAsmParser &Parser = getParser();
6064 const MCExpr *Value;
6065 // EmitDTPRel32Value requires an expression, so we are using base class
6066 // method to evaluate the expression.
6067 if (getParser().parseExpression(Value))
6069 getParser().getStreamer().EmitDTPRel32Value(Value);
6071 if (getLexer().isNot(AsmToken::EndOfStatement))
6072 return Error(getLexer().getLoc(),
6073 "unexpected token, expected end of statement");
6074 Parser.Lex(); // Eat EndOfStatement token.
6078 /// parseDirectiveDtpRelDWord
6079 /// ::= .dtpreldword tls_sym
6080 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6081 MCAsmParser &Parser = getParser();
6082 const MCExpr *Value;
6083 // EmitDTPRel64Value requires an expression, so we are using base class
6084 // method to evaluate the expression.
6085 if (getParser().parseExpression(Value))
6087 getParser().getStreamer().EmitDTPRel64Value(Value);
6089 if (getLexer().isNot(AsmToken::EndOfStatement))
6090 return Error(getLexer().getLoc(),
6091 "unexpected token, expected end of statement");
6092 Parser.Lex(); // Eat EndOfStatement token.
6096 /// parseDirectiveTpRelWord
6097 /// ::= .tprelword tls_sym
6098 bool MipsAsmParser::parseDirectiveTpRelWord() {
6099 MCAsmParser &Parser = getParser();
6100 const MCExpr *Value;
6101 // EmitTPRel32Value requires an expression, so we are using base class
6102 // method to evaluate the expression.
6103 if (getParser().parseExpression(Value))
6105 getParser().getStreamer().EmitTPRel32Value(Value);
6107 if (getLexer().isNot(AsmToken::EndOfStatement))
6108 return Error(getLexer().getLoc(),
6109 "unexpected token, expected end of statement");
6110 Parser.Lex(); // Eat EndOfStatement token.
6114 /// parseDirectiveTpRelDWord
6115 /// ::= .tpreldword tls_sym
6116 bool MipsAsmParser::parseDirectiveTpRelDWord() {
6117 MCAsmParser &Parser = getParser();
6118 const MCExpr *Value;
6119 // EmitTPRel64Value requires an expression, so we are using base class
6120 // method to evaluate the expression.
6121 if (getParser().parseExpression(Value))
6123 getParser().getStreamer().EmitTPRel64Value(Value);
6125 if (getLexer().isNot(AsmToken::EndOfStatement))
6126 return Error(getLexer().getLoc(),
6127 "unexpected token, expected end of statement");
6128 Parser.Lex(); // Eat EndOfStatement token.
6132 bool MipsAsmParser::parseDirectiveOption() {
6133 MCAsmParser &Parser = getParser();
6134 // Get the option token.
6135 AsmToken Tok = Parser.getTok();
6136 // At the moment only identifiers are supported.
6137 if (Tok.isNot(AsmToken::Identifier)) {
6138 return Error(Parser.getTok().getLoc(),
6139 "unexpected token, expected identifier");
6142 StringRef Option = Tok.getIdentifier();
6144 if (Option == "pic0") {
6145 // MipsAsmParser needs to know if the current PIC mode changes.
6146 IsPicEnabled = false;
6148 getTargetStreamer().emitDirectiveOptionPic0();
6150 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6151 return Error(Parser.getTok().getLoc(),
6152 "unexpected token, expected end of statement");
6157 if (Option == "pic2") {
6158 // MipsAsmParser needs to know if the current PIC mode changes.
6159 IsPicEnabled = true;
6161 getTargetStreamer().emitDirectiveOptionPic2();
6163 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6164 return Error(Parser.getTok().getLoc(),
6165 "unexpected token, expected end of statement");
6171 Warning(Parser.getTok().getLoc(),
6172 "unknown option, expected 'pic0' or 'pic2'");
6173 Parser.eatToEndOfStatement();
6177 /// parseInsnDirective
6179 bool MipsAsmParser::parseInsnDirective() {
6180 // If this is not the end of the statement, report an error.
6181 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6182 reportParseError("unexpected token, expected end of statement");
6186 // The actual label marking happens in
6187 // MipsELFStreamer::createPendingLabelRelocs().
6188 getTargetStreamer().emitDirectiveInsn();
6190 getParser().Lex(); // Eat EndOfStatement token.
6194 /// parseSSectionDirective
6197 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
6198 // If this is not the end of the statement, report an error.
6199 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6200 reportParseError("unexpected token, expected end of statement");
6204 MCSection *ELFSection = getContext().getELFSection(
6205 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
6206 getParser().getStreamer().SwitchSection(ELFSection);
6208 getParser().Lex(); // Eat EndOfStatement token.
6212 /// parseDirectiveModule
6213 /// ::= .module oddspreg
6214 /// ::= .module nooddspreg
6215 /// ::= .module fp=value
6216 /// ::= .module softfloat
6217 /// ::= .module hardfloat
6218 bool MipsAsmParser::parseDirectiveModule() {
6219 MCAsmParser &Parser = getParser();
6220 MCAsmLexer &Lexer = getLexer();
6221 SMLoc L = Lexer.getLoc();
6223 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
6224 // TODO : get a better message.
6225 reportParseError(".module directive must appear before any code");
6230 if (Parser.parseIdentifier(Option)) {
6231 reportParseError("expected .module option identifier");
6235 if (Option == "oddspreg") {
6236 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6238 // Synchronize the abiflags information with the FeatureBits information we
6240 getTargetStreamer().updateABIInfo(*this);
6242 // If printing assembly, use the recently updated abiflags information.
6243 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6244 // emitted at the end).
6245 getTargetStreamer().emitDirectiveModuleOddSPReg();
6247 // If this is not the end of the statement, report an error.
6248 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6249 reportParseError("unexpected token, expected end of statement");
6253 return false; // parseDirectiveModule has finished successfully.
6254 } else if (Option == "nooddspreg") {
6256 return Error(L, "'.module nooddspreg' requires the O32 ABI");
6259 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6261 // Synchronize the abiflags information with the FeatureBits information we
6263 getTargetStreamer().updateABIInfo(*this);
6265 // If printing assembly, use the recently updated abiflags information.
6266 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6267 // emitted at the end).
6268 getTargetStreamer().emitDirectiveModuleOddSPReg();
6270 // If this is not the end of the statement, report an error.
6271 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6272 reportParseError("unexpected token, expected end of statement");
6276 return false; // parseDirectiveModule has finished successfully.
6277 } else if (Option == "fp") {
6278 return parseDirectiveModuleFP();
6279 } else if (Option == "softfloat") {
6280 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6282 // Synchronize the ABI Flags information with the FeatureBits information we
6284 getTargetStreamer().updateABIInfo(*this);
6286 // If printing assembly, use the recently updated ABI Flags information.
6287 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6289 getTargetStreamer().emitDirectiveModuleSoftFloat();
6291 // If this is not the end of the statement, report an error.
6292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6293 reportParseError("unexpected token, expected end of statement");
6297 return false; // parseDirectiveModule has finished successfully.
6298 } else if (Option == "hardfloat") {
6299 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6301 // Synchronize the ABI Flags information with the FeatureBits information we
6303 getTargetStreamer().updateABIInfo(*this);
6305 // If printing assembly, use the recently updated ABI Flags information.
6306 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6308 getTargetStreamer().emitDirectiveModuleHardFloat();
6310 // If this is not the end of the statement, report an error.
6311 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6312 reportParseError("unexpected token, expected end of statement");
6316 return false; // parseDirectiveModule has finished successfully.
6318 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
6322 /// parseDirectiveModuleFP
6326 bool MipsAsmParser::parseDirectiveModuleFP() {
6327 MCAsmParser &Parser = getParser();
6328 MCAsmLexer &Lexer = getLexer();
6330 if (Lexer.isNot(AsmToken::Equal)) {
6331 reportParseError("unexpected token, expected equals sign '='");
6334 Parser.Lex(); // Eat '=' token.
6336 MipsABIFlagsSection::FpABIKind FpABI;
6337 if (!parseFpABIValue(FpABI, ".module"))
6340 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6341 reportParseError("unexpected token, expected end of statement");
6345 // Synchronize the abiflags information with the FeatureBits information we
6347 getTargetStreamer().updateABIInfo(*this);
6349 // If printing assembly, use the recently updated abiflags information.
6350 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6351 // emitted at the end).
6352 getTargetStreamer().emitDirectiveModuleFP();
6354 Parser.Lex(); // Consume the EndOfStatement.
6358 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
6359 StringRef Directive) {
6360 MCAsmParser &Parser = getParser();
6361 MCAsmLexer &Lexer = getLexer();
6362 bool ModuleLevelOptions = Directive == ".module";
6364 if (Lexer.is(AsmToken::Identifier)) {
6365 StringRef Value = Parser.getTok().getString();
6368 if (Value != "xx") {
6369 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6374 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
6378 FpABI = MipsABIFlagsSection::FpABIKind::XX;
6379 if (ModuleLevelOptions) {
6380 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6381 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6383 setFeatureBits(Mips::FeatureFPXX, "fpxx");
6384 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6389 if (Lexer.is(AsmToken::Integer)) {
6390 unsigned Value = Parser.getTok().getIntVal();
6393 if (Value != 32 && Value != 64) {
6394 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6400 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6404 FpABI = MipsABIFlagsSection::FpABIKind::S32;
6405 if (ModuleLevelOptions) {
6406 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6407 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6409 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6410 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6413 FpABI = MipsABIFlagsSection::FpABIKind::S64;
6414 if (ModuleLevelOptions) {
6415 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6416 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6418 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6419 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6429 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6430 // This returns false if this function recognizes the directive
6431 // regardless of whether it is successfully handles or reports an
6432 // error. Otherwise it returns true to give the generic parser a
6433 // chance at recognizing it.
6435 MCAsmParser &Parser = getParser();
6436 StringRef IDVal = DirectiveID.getString();
6438 if (IDVal == ".cpload") {
6439 parseDirectiveCpLoad(DirectiveID.getLoc());
6442 if (IDVal == ".cprestore") {
6443 parseDirectiveCpRestore(DirectiveID.getLoc());
6446 if (IDVal == ".dword") {
6447 parseDataDirective(8, DirectiveID.getLoc());
6450 if (IDVal == ".ent") {
6451 StringRef SymbolName;
6453 if (Parser.parseIdentifier(SymbolName)) {
6454 reportParseError("expected identifier after .ent");
6458 // There's an undocumented extension that allows an integer to
6459 // follow the name of the procedure which AFAICS is ignored by GAS.
6460 // Example: .ent foo,2
6461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6462 if (getLexer().isNot(AsmToken::Comma)) {
6463 // Even though we accept this undocumented extension for compatibility
6464 // reasons, the additional integer argument does not actually change
6465 // the behaviour of the '.ent' directive, so we would like to discourage
6466 // its use. We do this by not referring to the extended version in
6467 // error messages which are not directly related to its use.
6468 reportParseError("unexpected token, expected end of statement");
6471 Parser.Lex(); // Eat the comma.
6472 const MCExpr *DummyNumber;
6473 int64_t DummyNumberVal;
6474 // If the user was explicitly trying to use the extended version,
6475 // we still give helpful extension-related error messages.
6476 if (Parser.parseExpression(DummyNumber)) {
6477 reportParseError("expected number after comma");
6480 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6481 reportParseError("expected an absolute expression after comma");
6486 // If this is not the end of the statement, report an error.
6487 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6488 reportParseError("unexpected token, expected end of statement");
6492 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6494 getTargetStreamer().emitDirectiveEnt(*Sym);
6496 IsCpRestoreSet = false;
6500 if (IDVal == ".end") {
6501 StringRef SymbolName;
6503 if (Parser.parseIdentifier(SymbolName)) {
6504 reportParseError("expected identifier after .end");
6508 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6509 reportParseError("unexpected token, expected end of statement");
6513 if (CurrentFn == nullptr) {
6514 reportParseError(".end used without .ent");
6518 if ((SymbolName != CurrentFn->getName())) {
6519 reportParseError(".end symbol does not match .ent symbol");
6523 getTargetStreamer().emitDirectiveEnd(SymbolName);
6524 CurrentFn = nullptr;
6525 IsCpRestoreSet = false;
6529 if (IDVal == ".frame") {
6530 // .frame $stack_reg, frame_size_in_bytes, $return_reg
6531 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6532 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6533 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6534 reportParseError("expected stack register");
6538 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6539 if (!StackRegOpnd.isGPRAsmReg()) {
6540 reportParseError(StackRegOpnd.getStartLoc(),
6541 "expected general purpose register");
6544 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6546 if (Parser.getTok().is(AsmToken::Comma))
6549 reportParseError("unexpected token, expected comma");
6553 // Parse the frame size.
6554 const MCExpr *FrameSize;
6555 int64_t FrameSizeVal;
6557 if (Parser.parseExpression(FrameSize)) {
6558 reportParseError("expected frame size value");
6562 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6563 reportParseError("frame size not an absolute expression");
6567 if (Parser.getTok().is(AsmToken::Comma))
6570 reportParseError("unexpected token, expected comma");
6574 // Parse the return register.
6576 ResTy = parseAnyRegister(TmpReg);
6577 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6578 reportParseError("expected return register");
6582 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6583 if (!ReturnRegOpnd.isGPRAsmReg()) {
6584 reportParseError(ReturnRegOpnd.getStartLoc(),
6585 "expected general purpose register");
6589 // If this is not the end of the statement, report an error.
6590 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6591 reportParseError("unexpected token, expected end of statement");
6595 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6596 ReturnRegOpnd.getGPR32Reg());
6597 IsCpRestoreSet = false;
6601 if (IDVal == ".set") {
6602 parseDirectiveSet();
6606 if (IDVal == ".mask" || IDVal == ".fmask") {
6607 // .mask bitmask, frame_offset
6608 // bitmask: One bit for each register used.
6609 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6610 // first register is expected to be saved.
6612 // .mask 0x80000000, -4
6613 // .fmask 0x80000000, -4
6616 // Parse the bitmask
6617 const MCExpr *BitMask;
6620 if (Parser.parseExpression(BitMask)) {
6621 reportParseError("expected bitmask value");
6625 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6626 reportParseError("bitmask not an absolute expression");
6630 if (Parser.getTok().is(AsmToken::Comma))
6633 reportParseError("unexpected token, expected comma");
6637 // Parse the frame_offset
6638 const MCExpr *FrameOffset;
6639 int64_t FrameOffsetVal;
6641 if (Parser.parseExpression(FrameOffset)) {
6642 reportParseError("expected frame offset value");
6646 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6647 reportParseError("frame offset not an absolute expression");
6651 // If this is not the end of the statement, report an error.
6652 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6653 reportParseError("unexpected token, expected end of statement");
6657 if (IDVal == ".mask")
6658 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6660 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6664 if (IDVal == ".nan")
6665 return parseDirectiveNaN();
6667 if (IDVal == ".gpword") {
6668 parseDirectiveGpWord();
6672 if (IDVal == ".gpdword") {
6673 parseDirectiveGpDWord();
6677 if (IDVal == ".dtprelword") {
6678 parseDirectiveDtpRelWord();
6682 if (IDVal == ".dtpreldword") {
6683 parseDirectiveDtpRelDWord();
6687 if (IDVal == ".tprelword") {
6688 parseDirectiveTpRelWord();
6692 if (IDVal == ".tpreldword") {
6693 parseDirectiveTpRelDWord();
6697 if (IDVal == ".word") {
6698 parseDataDirective(4, DirectiveID.getLoc());
6702 if (IDVal == ".hword") {
6703 parseDataDirective(2, DirectiveID.getLoc());
6707 if (IDVal == ".option") {
6708 parseDirectiveOption();
6712 if (IDVal == ".abicalls") {
6713 getTargetStreamer().emitDirectiveAbiCalls();
6714 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6715 Error(Parser.getTok().getLoc(),
6716 "unexpected token, expected end of statement");
6721 if (IDVal == ".cpsetup") {
6722 parseDirectiveCPSetup();
6725 if (IDVal == ".cpreturn") {
6726 parseDirectiveCPReturn();
6729 if (IDVal == ".module") {
6730 parseDirectiveModule();
6733 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
6734 parseInternalDirectiveReallowModule();
6737 if (IDVal == ".insn") {
6738 parseInsnDirective();
6741 if (IDVal == ".sbss") {
6742 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
6745 if (IDVal == ".sdata") {
6746 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
6753 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6754 // If this is not the end of the statement, report an error.
6755 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6756 reportParseError("unexpected token, expected end of statement");
6760 getTargetStreamer().reallowModuleDirective();
6762 getParser().Lex(); // Eat EndOfStatement token.
6766 extern "C" void LLVMInitializeMipsAsmParser() {
6767 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
6768 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
6769 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
6770 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
6773 #define GET_REGISTER_MATCHER
6774 #define GET_MATCHER_IMPLEMENTATION
6775 #include "MipsGenAsmMatcher.inc"