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_NonZeroOperandForSync,
417 #define GET_OPERAND_DIAGNOSTIC_TYPES
418 #include "MipsGenAsmMatcher.inc"
419 #undef GET_OPERAND_DIAGNOSTIC_TYPES
422 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
423 const MCInstrInfo &MII, const MCTargetOptions &Options)
424 : MCTargetAsmParser(Options, sti),
425 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
426 sti.getCPU(), Options)) {
427 MCAsmParserExtension::Initialize(parser);
429 parser.addAliasForDirective(".asciiz", ".asciz");
431 // Initialize the set of available features.
432 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
434 // Remember the initial assembler options. The user can not modify these.
435 AssemblerOptions.push_back(
436 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
438 // Create an assembler options environment for the user to modify.
439 AssemblerOptions.push_back(
440 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
442 getTargetStreamer().updateABIInfo(*this);
444 if (!isABI_O32() && !useOddSPReg() != 0)
445 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
449 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
451 IsCpRestoreSet = false;
452 CpRestoreOffset = -1;
454 const Triple &TheTriple = sti.getTargetTriple();
455 if ((TheTriple.getArch() == Triple::mips) ||
456 (TheTriple.getArch() == Triple::mips64))
457 IsLittleEndian = false;
459 IsLittleEndian = true;
462 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
463 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
465 bool isGP64bit() const {
466 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
468 bool isFP64bit() const {
469 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
471 const MipsABIInfo &getABI() const { return ABI; }
472 bool isABI_N32() const { return ABI.IsN32(); }
473 bool isABI_N64() const { return ABI.IsN64(); }
474 bool isABI_O32() const { return ABI.IsO32(); }
475 bool isABI_FPXX() const {
476 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
479 bool useOddSPReg() const {
480 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
483 bool inMicroMipsMode() const {
484 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
486 bool hasMips1() const {
487 return getSTI().getFeatureBits()[Mips::FeatureMips1];
489 bool hasMips2() const {
490 return getSTI().getFeatureBits()[Mips::FeatureMips2];
492 bool hasMips3() const {
493 return getSTI().getFeatureBits()[Mips::FeatureMips3];
495 bool hasMips4() const {
496 return getSTI().getFeatureBits()[Mips::FeatureMips4];
498 bool hasMips5() const {
499 return getSTI().getFeatureBits()[Mips::FeatureMips5];
501 bool hasMips32() const {
502 return getSTI().getFeatureBits()[Mips::FeatureMips32];
504 bool hasMips64() const {
505 return getSTI().getFeatureBits()[Mips::FeatureMips64];
507 bool hasMips32r2() const {
508 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
510 bool hasMips64r2() const {
511 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
513 bool hasMips32r3() const {
514 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
516 bool hasMips64r3() const {
517 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
519 bool hasMips32r5() const {
520 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
522 bool hasMips64r5() const {
523 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
525 bool hasMips32r6() const {
526 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
528 bool hasMips64r6() const {
529 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
532 bool hasDSP() const {
533 return getSTI().getFeatureBits()[Mips::FeatureDSP];
535 bool hasDSPR2() const {
536 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
538 bool hasDSPR3() const {
539 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
541 bool hasMSA() const {
542 return getSTI().getFeatureBits()[Mips::FeatureMSA];
544 bool hasCnMips() const {
545 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
552 bool inMips16Mode() const {
553 return getSTI().getFeatureBits()[Mips::FeatureMips16];
556 bool useTraps() const {
557 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
560 bool useSoftFloat() const {
561 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
564 /// Warn if RegIndex is the same as the current AT.
565 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
567 void warnIfNoMacro(SMLoc Loc);
569 bool isLittle() const { return IsLittleEndian; }
571 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
572 AsmToken::TokenKind OperatorToken,
573 MCContext &Ctx) override {
574 switch(OperatorToken) {
576 llvm_unreachable("Unknown token");
578 case AsmToken::PercentCall16:
579 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
580 case AsmToken::PercentCall_Hi:
581 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
582 case AsmToken::PercentCall_Lo:
583 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
584 case AsmToken::PercentDtprel_Hi:
585 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
586 case AsmToken::PercentDtprel_Lo:
587 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
588 case AsmToken::PercentGot:
589 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
590 case AsmToken::PercentGot_Disp:
591 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
592 case AsmToken::PercentGot_Hi:
593 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
594 case AsmToken::PercentGot_Lo:
595 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
596 case AsmToken::PercentGot_Ofst:
597 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
598 case AsmToken::PercentGot_Page:
599 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
600 case AsmToken::PercentGottprel:
601 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
602 case AsmToken::PercentGp_Rel:
603 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
604 case AsmToken::PercentHi:
605 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
606 case AsmToken::PercentHigher:
607 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
608 case AsmToken::PercentHighest:
609 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
610 case AsmToken::PercentLo:
611 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
612 case AsmToken::PercentNeg:
613 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
614 case AsmToken::PercentPcrel_Hi:
615 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
616 case AsmToken::PercentPcrel_Lo:
617 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
618 case AsmToken::PercentTlsgd:
619 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
620 case AsmToken::PercentTlsldm:
621 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
622 case AsmToken::PercentTprel_Hi:
623 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
624 case AsmToken::PercentTprel_Lo:
625 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
633 /// MipsOperand - Instances of this class represent a parsed Mips machine
635 class MipsOperand : public MCParsedAsmOperand {
637 /// Broad categories of register classes
638 /// The exact class is finalized by the render method.
640 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
641 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
643 RegKind_FCC = 4, /// FCC
644 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
645 RegKind_MSACtrl = 16, /// MSA control registers
646 RegKind_COP2 = 32, /// COP2
647 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
649 RegKind_CCR = 128, /// CCR
650 RegKind_HWRegs = 256, /// HWRegs
651 RegKind_COP3 = 512, /// COP3
652 RegKind_COP0 = 1024, /// COP0
653 /// Potentially any (e.g. $1)
654 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
655 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
656 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
661 k_Immediate, /// An immediate (possibly involving symbol references)
662 k_Memory, /// Base + Offset Memory Address
663 k_RegisterIndex, /// A register index in one or more RegKind.
664 k_Token, /// A simple token
665 k_RegList, /// A physical register list
666 k_RegPair /// A pair of physical register
670 MipsOperand(KindTy K, MipsAsmParser &Parser)
671 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
674 /// For diagnostics, and checking the assembler temporary
675 MipsAsmParser &AsmParser;
683 unsigned Index; /// Index into the register class
684 RegKind Kind; /// Bitfield of the kinds it could possibly be
685 struct Token Tok; /// The input token this operand originated from.
686 const MCRegisterInfo *RegInfo;
699 SmallVector<unsigned, 10> *List;
704 struct RegIdxOp RegIdx;
707 struct RegListOp RegList;
710 SMLoc StartLoc, EndLoc;
712 /// Internal constructor for register kinds
713 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
715 const MCRegisterInfo *RegInfo,
717 MipsAsmParser &Parser) {
718 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
719 Op->RegIdx.Index = Index;
720 Op->RegIdx.RegInfo = RegInfo;
721 Op->RegIdx.Kind = RegKind;
722 Op->RegIdx.Tok.Data = Str.data();
723 Op->RegIdx.Tok.Length = Str.size();
730 /// Coerce the register to GPR32 and return the real register for the current
732 unsigned getGPR32Reg() const {
733 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
734 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
735 unsigned ClassID = Mips::GPR32RegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 /// Coerce the register to GPR32 and return the real register for the current
741 unsigned getGPRMM16Reg() const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
743 unsigned ClassID = Mips::GPR32RegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
747 /// Coerce the register to GPR64 and return the real register for the current
749 unsigned getGPR64Reg() const {
750 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
751 unsigned ClassID = Mips::GPR64RegClassID;
752 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
756 /// Coerce the register to AFGR64 and return the real register for the current
758 unsigned getAFGR64Reg() const {
759 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
760 if (RegIdx.Index % 2 != 0)
761 AsmParser.Warning(StartLoc, "Float register should be even.");
762 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
763 .getRegister(RegIdx.Index / 2);
766 /// Coerce the register to FGR64 and return the real register for the current
768 unsigned getFGR64Reg() const {
769 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
770 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
771 .getRegister(RegIdx.Index);
774 /// Coerce the register to FGR32 and return the real register for the current
776 unsigned getFGR32Reg() const {
777 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
778 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
779 .getRegister(RegIdx.Index);
782 /// Coerce the register to FGRH32 and return the real register for the current
784 unsigned getFGRH32Reg() const {
785 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
786 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
787 .getRegister(RegIdx.Index);
790 /// Coerce the register to FCC and return the real register for the current
792 unsigned getFCCReg() const {
793 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
794 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
795 .getRegister(RegIdx.Index);
798 /// Coerce the register to MSA128 and return the real register for the current
800 unsigned getMSA128Reg() const {
801 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
802 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
804 unsigned ClassID = Mips::MSA128BRegClassID;
805 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
808 /// Coerce the register to MSACtrl and return the real register for the
810 unsigned getMSACtrlReg() const {
811 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
812 unsigned ClassID = Mips::MSACtrlRegClassID;
813 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
816 /// Coerce the register to COP0 and return the real register for the
818 unsigned getCOP0Reg() const {
819 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
820 unsigned ClassID = Mips::COP0RegClassID;
821 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
824 /// Coerce the register to COP2 and return the real register for the
826 unsigned getCOP2Reg() const {
827 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
828 unsigned ClassID = Mips::COP2RegClassID;
829 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
832 /// Coerce the register to COP3 and return the real register for the
834 unsigned getCOP3Reg() const {
835 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
836 unsigned ClassID = Mips::COP3RegClassID;
837 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
840 /// Coerce the register to ACC64DSP and return the real register for the
842 unsigned getACC64DSPReg() const {
843 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
844 unsigned ClassID = Mips::ACC64DSPRegClassID;
845 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
848 /// Coerce the register to HI32DSP and return the real register for the
850 unsigned getHI32DSPReg() const {
851 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
852 unsigned ClassID = Mips::HI32DSPRegClassID;
853 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
856 /// Coerce the register to LO32DSP and return the real register for the
858 unsigned getLO32DSPReg() const {
859 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
860 unsigned ClassID = Mips::LO32DSPRegClassID;
861 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
864 /// Coerce the register to CCR and return the real register for the
866 unsigned getCCRReg() const {
867 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
868 unsigned ClassID = Mips::CCRRegClassID;
869 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
872 /// Coerce the register to HWRegs and return the real register for the
874 unsigned getHWRegsReg() const {
875 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
876 unsigned ClassID = Mips::HWRegsRegClassID;
877 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
881 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
882 // Add as immediate when possible. Null MCExpr = 0.
884 Inst.addOperand(MCOperand::createImm(0));
885 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
886 Inst.addOperand(MCOperand::createImm(CE->getValue()));
888 Inst.addOperand(MCOperand::createExpr(Expr));
891 void addRegOperands(MCInst &Inst, unsigned N) const {
892 llvm_unreachable("Use a custom parser instead");
895 /// Render the operand to an MCInst as a GPR32
896 /// Asserts if the wrong number of operands are requested, or the operand
897 /// is not a k_RegisterIndex compatible with RegKind_GPR
898 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
899 assert(N == 1 && "Invalid number of operands!");
900 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
903 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
904 assert(N == 1 && "Invalid number of operands!");
905 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
908 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
909 assert(N == 1 && "Invalid number of operands!");
910 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
913 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
914 assert(N == 1 && "Invalid number of operands!");
915 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
918 /// Render the operand to an MCInst as a GPR64
919 /// Asserts if the wrong number of operands are requested, or the operand
920 /// is not a k_RegisterIndex compatible with RegKind_GPR
921 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
922 assert(N == 1 && "Invalid number of operands!");
923 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
926 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
927 assert(N == 1 && "Invalid number of operands!");
928 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
931 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
932 assert(N == 1 && "Invalid number of operands!");
933 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
936 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
937 assert(N == 1 && "Invalid number of operands!");
938 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
939 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
940 // FIXME: This should propagate failure up to parseStatement.
941 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
942 AsmParser.getParser().printError(
943 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
947 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
948 assert(N == 1 && "Invalid number of operands!");
949 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
952 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
953 assert(N == 1 && "Invalid number of operands!");
954 Inst.addOperand(MCOperand::createReg(getFCCReg()));
957 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
958 assert(N == 1 && "Invalid number of operands!");
959 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
962 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
963 assert(N == 1 && "Invalid number of operands!");
964 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
967 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
968 assert(N == 1 && "Invalid number of operands!");
969 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
972 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
973 assert(N == 1 && "Invalid number of operands!");
974 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
977 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
978 assert(N == 1 && "Invalid number of operands!");
979 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
982 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
983 assert(N == 1 && "Invalid number of operands!");
984 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
987 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
988 assert(N == 1 && "Invalid number of operands!");
989 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
992 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
993 assert(N == 1 && "Invalid number of operands!");
994 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
997 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
998 assert(N == 1 && "Invalid number of operands!");
999 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1002 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1003 assert(N == 1 && "Invalid number of operands!");
1004 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1007 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1008 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1009 assert(N == 1 && "Invalid number of operands!");
1010 uint64_t Imm = getConstantImm() - Offset;
1011 Imm &= (1ULL << Bits) - 1;
1013 Imm += AdjustOffset;
1014 Inst.addOperand(MCOperand::createImm(Imm));
1017 template <unsigned Bits>
1018 void addSImmOperands(MCInst &Inst, unsigned N) const {
1019 if (isImm() && !isConstantImm()) {
1020 addExpr(Inst, getImm());
1023 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1026 template <unsigned Bits>
1027 void addUImmOperands(MCInst &Inst, unsigned N) const {
1028 if (isImm() && !isConstantImm()) {
1029 addExpr(Inst, getImm());
1032 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1035 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1036 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1037 assert(N == 1 && "Invalid number of operands!");
1038 int64_t Imm = getConstantImm() - Offset;
1039 Imm = SignExtend64<Bits>(Imm);
1041 Imm += AdjustOffset;
1042 Inst.addOperand(MCOperand::createImm(Imm));
1045 void addImmOperands(MCInst &Inst, unsigned N) const {
1046 assert(N == 1 && "Invalid number of operands!");
1047 const MCExpr *Expr = getImm();
1048 addExpr(Inst, Expr);
1051 void addMemOperands(MCInst &Inst, unsigned N) const {
1052 assert(N == 2 && "Invalid number of operands!");
1054 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1055 ? getMemBase()->getGPR64Reg()
1056 : getMemBase()->getGPR32Reg()));
1058 const MCExpr *Expr = getMemOff();
1059 addExpr(Inst, Expr);
1062 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1063 assert(N == 2 && "Invalid number of operands!");
1065 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1067 const MCExpr *Expr = getMemOff();
1068 addExpr(Inst, Expr);
1071 void addRegListOperands(MCInst &Inst, unsigned N) const {
1072 assert(N == 1 && "Invalid number of operands!");
1074 for (auto RegNo : getRegList())
1075 Inst.addOperand(MCOperand::createReg(RegNo));
1078 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1079 assert(N == 2 && "Invalid number of operands!");
1080 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1081 unsigned RegNo = getRegPair();
1082 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1083 Inst.addOperand(MCOperand::createReg(
1084 RegIdx.RegInfo->getRegClass(
1085 AsmParser.getABI().AreGprs64bit()
1086 ? Mips::GPR64RegClassID
1087 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1088 Inst.addOperand(MCOperand::createReg(
1089 RegIdx.RegInfo->getRegClass(
1090 AsmParser.getABI().AreGprs64bit()
1091 ? Mips::GPR64RegClassID
1092 : Mips::GPR32RegClassID).getRegister(RegNo)));
1095 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1096 assert(N == 2 && "Invalid number of operands!");
1097 for (auto RegNo : getRegList())
1098 Inst.addOperand(MCOperand::createReg(RegNo));
1101 bool isReg() const override {
1102 // As a special case until we sort out the definition of div/divu, accept
1103 // $0/$zero here so that MCK_ZERO works correctly.
1104 return isGPRAsmReg() && RegIdx.Index == 0;
1106 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1107 bool isImm() const override { return Kind == k_Immediate; }
1108 bool isConstantImm() const {
1110 return isImm() && getImm()->evaluateAsAbsolute(Res);
1112 bool isConstantImmz() const {
1113 return isConstantImm() && getConstantImm() == 0;
1115 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1116 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1118 template <unsigned Bits> bool isSImm() const {
1119 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1121 template <unsigned Bits> bool isUImm() const {
1122 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1124 template <unsigned Bits> bool isAnyImm() const {
1125 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1126 isUInt<Bits>(getConstantImm()))
1129 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1130 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1132 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1133 return isConstantImm() && getConstantImm() >= Bottom &&
1134 getConstantImm() <= Top;
1136 bool isToken() const override {
1137 // Note: It's not possible to pretend that other operand kinds are tokens.
1138 // The matcher emitter checks tokens first.
1139 return Kind == k_Token;
1141 bool isMem() const override { return Kind == k_Memory; }
1142 bool isConstantMemOff() const {
1143 return isMem() && isa<MCConstantExpr>(getMemOff());
1145 // Allow relocation operators.
1146 // FIXME: This predicate and others need to look through binary expressions
1147 // and determine whether a Value is a constant or not.
1148 template <unsigned Bits, unsigned ShiftAmount = 0>
1149 bool isMemWithSimmOffset() const {
1152 if (!getMemBase()->isGPRAsmReg())
1154 if (isa<MCTargetExpr>(getMemOff()) ||
1155 (isConstantMemOff() &&
1156 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1159 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1160 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1162 bool isMemWithGRPMM16Base() const {
1163 return isMem() && getMemBase()->isMM16AsmReg();
1165 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1166 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1167 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1169 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1170 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1171 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1172 && (getMemBase()->getGPR32Reg() == Mips::SP);
1174 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1175 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1176 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1177 && (getMemBase()->getGPR32Reg() == Mips::GP);
1179 template <unsigned Bits, unsigned ShiftLeftAmount>
1180 bool isScaledUImm() const {
1181 return isConstantImm() &&
1182 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1184 template <unsigned Bits, unsigned ShiftLeftAmount>
1185 bool isScaledSImm() const {
1186 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1188 // Operand can also be a symbol or symbol plus offset in case of relocations.
1189 if (Kind != k_Immediate)
1192 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1193 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1195 bool isRegList16() const {
1199 int Size = RegList.List->size();
1200 if (Size < 2 || Size > 5)
1203 unsigned R0 = RegList.List->front();
1204 unsigned R1 = RegList.List->back();
1205 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1206 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1209 int PrevReg = *RegList.List->begin();
1210 for (int i = 1; i < Size - 1; i++) {
1211 int Reg = (*(RegList.List))[i];
1212 if ( Reg != PrevReg + 1)
1219 bool isInvNum() const { return Kind == k_Immediate; }
1220 bool isLSAImm() const {
1221 if (!isConstantImm())
1223 int64_t Val = getConstantImm();
1224 return 1 <= Val && Val <= 4;
1226 bool isRegList() const { return Kind == k_RegList; }
1227 bool isMovePRegPair() const {
1228 if (Kind != k_RegList || RegList.List->size() != 2)
1231 unsigned R0 = RegList.List->front();
1232 unsigned R1 = RegList.List->back();
1234 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1235 (R0 == Mips::A1 && R1 == Mips::A3) ||
1236 (R0 == Mips::A2 && R1 == Mips::A3) ||
1237 (R0 == Mips::A0 && R1 == Mips::S5) ||
1238 (R0 == Mips::A0 && R1 == Mips::S6) ||
1239 (R0 == Mips::A0 && R1 == Mips::A1) ||
1240 (R0 == Mips::A0 && R1 == Mips::A2) ||
1241 (R0 == Mips::A0 && R1 == Mips::A3) ||
1242 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1243 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1244 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1245 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1246 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1247 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1248 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1249 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1255 StringRef getToken() const {
1256 assert(Kind == k_Token && "Invalid access!");
1257 return StringRef(Tok.Data, Tok.Length);
1259 bool isRegPair() const {
1260 return Kind == k_RegPair && RegIdx.Index <= 30;
1263 unsigned getReg() const override {
1264 // As a special case until we sort out the definition of div/divu, accept
1265 // $0/$zero here so that MCK_ZERO works correctly.
1266 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1267 RegIdx.Kind & RegKind_GPR)
1268 return getGPR32Reg(); // FIXME: GPR64 too
1270 llvm_unreachable("Invalid access!");
1274 const MCExpr *getImm() const {
1275 assert((Kind == k_Immediate) && "Invalid access!");
1279 int64_t getConstantImm() const {
1280 const MCExpr *Val = getImm();
1282 (void)Val->evaluateAsAbsolute(Value);
1286 MipsOperand *getMemBase() const {
1287 assert((Kind == k_Memory) && "Invalid access!");
1291 const MCExpr *getMemOff() const {
1292 assert((Kind == k_Memory) && "Invalid access!");
1296 int64_t getConstantMemOff() const {
1297 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1300 const SmallVectorImpl<unsigned> &getRegList() const {
1301 assert((Kind == k_RegList) && "Invalid access!");
1302 return *(RegList.List);
1305 unsigned getRegPair() const {
1306 assert((Kind == k_RegPair) && "Invalid access!");
1307 return RegIdx.Index;
1310 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1311 MipsAsmParser &Parser) {
1312 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1313 Op->Tok.Data = Str.data();
1314 Op->Tok.Length = Str.size();
1320 /// Create a numeric register (e.g. $1). The exact register remains
1321 /// unresolved until an instruction successfully matches
1322 static std::unique_ptr<MipsOperand>
1323 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1324 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1325 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1326 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1329 /// Create a register that is definitely a GPR.
1330 /// This is typically only used for named registers such as $gp.
1331 static std::unique_ptr<MipsOperand>
1332 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1333 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1334 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1337 /// Create a register that is definitely a FGR.
1338 /// This is typically only used for named registers such as $f0.
1339 static std::unique_ptr<MipsOperand>
1340 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1341 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1342 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1345 /// Create a register that is definitely a HWReg.
1346 /// This is typically only used for named registers such as $hwr_cpunum.
1347 static std::unique_ptr<MipsOperand>
1348 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1349 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1350 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1353 /// Create a register that is definitely an FCC.
1354 /// This is typically only used for named registers such as $fcc0.
1355 static std::unique_ptr<MipsOperand>
1356 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1357 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1358 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1361 /// Create a register that is definitely an ACC.
1362 /// This is typically only used for named registers such as $ac0.
1363 static std::unique_ptr<MipsOperand>
1364 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1365 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1366 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1369 /// Create a register that is definitely an MSA128.
1370 /// This is typically only used for named registers such as $w0.
1371 static std::unique_ptr<MipsOperand>
1372 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1373 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1374 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1377 /// Create a register that is definitely an MSACtrl.
1378 /// This is typically only used for named registers such as $msaaccess.
1379 static std::unique_ptr<MipsOperand>
1380 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1381 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1382 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1385 static std::unique_ptr<MipsOperand>
1386 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1387 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1394 static std::unique_ptr<MipsOperand>
1395 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1396 SMLoc E, MipsAsmParser &Parser) {
1397 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1398 Op->Mem.Base = Base.release();
1405 static std::unique_ptr<MipsOperand>
1406 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1407 MipsAsmParser &Parser) {
1408 assert (Regs.size() > 0 && "Empty list not allowed");
1410 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1411 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1412 Op->StartLoc = StartLoc;
1413 Op->EndLoc = EndLoc;
1417 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1419 MipsAsmParser &Parser) {
1420 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1421 Op->RegIdx.Index = MOP.RegIdx.Index;
1422 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1423 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1429 bool isGPRAsmReg() const {
1430 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1432 bool isMM16AsmReg() const {
1433 if (!(isRegIdx() && RegIdx.Kind))
1435 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1436 || RegIdx.Index == 16 || RegIdx.Index == 17);
1438 bool isMM16AsmRegZero() const {
1439 if (!(isRegIdx() && RegIdx.Kind))
1441 return (RegIdx.Index == 0 ||
1442 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1443 RegIdx.Index == 17);
1445 bool isMM16AsmRegMoveP() const {
1446 if (!(isRegIdx() && RegIdx.Kind))
1448 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1449 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1451 bool isFGRAsmReg() const {
1452 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1453 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1455 bool isHWRegsAsmReg() const {
1456 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1458 bool isCCRAsmReg() const {
1459 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1461 bool isFCCAsmReg() const {
1462 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1464 if (!AsmParser.hasEightFccRegisters())
1465 return RegIdx.Index == 0;
1466 return RegIdx.Index <= 7;
1468 bool isACCAsmReg() const {
1469 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1471 bool isCOP0AsmReg() const {
1472 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1474 bool isCOP2AsmReg() const {
1475 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1477 bool isCOP3AsmReg() const {
1478 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1480 bool isMSA128AsmReg() const {
1481 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1483 bool isMSACtrlAsmReg() const {
1484 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1487 /// getStartLoc - Get the location of the first token of this operand.
1488 SMLoc getStartLoc() const override { return StartLoc; }
1489 /// getEndLoc - Get the location of the last token of this operand.
1490 SMLoc getEndLoc() const override { return EndLoc; }
1492 virtual ~MipsOperand() {
1500 delete RegList.List;
1501 case k_RegisterIndex:
1508 void print(raw_ostream &OS) const override {
1517 Mem.Base->print(OS);
1522 case k_RegisterIndex:
1523 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1524 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1531 for (auto Reg : (*RegList.List))
1536 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1541 bool isValidForTie(const MipsOperand &Other) const {
1542 if (Kind != Other.Kind)
1547 llvm_unreachable("Unexpected kind");
1549 case k_RegisterIndex: {
1550 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1551 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1552 return Token == OtherToken;
1556 }; // class MipsOperand
1560 extern const MCInstrDesc MipsInsts[];
1562 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1563 return MipsInsts[Opcode];
1566 static bool hasShortDelaySlot(unsigned Opcode) {
1569 case Mips::JALRS_MM:
1570 case Mips::JALRS16_MM:
1571 case Mips::BGEZALS_MM:
1572 case Mips::BLTZALS_MM:
1579 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1580 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1581 return &SRExpr->getSymbol();
1584 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1585 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1586 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1597 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1598 return getSingleMCSymbol(UExpr->getSubExpr());
1603 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1604 if (isa<MCSymbolRefExpr>(Expr))
1607 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1608 return countMCSymbolRefExpr(BExpr->getLHS()) +
1609 countMCSymbolRefExpr(BExpr->getRHS());
1611 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1612 return countMCSymbolRefExpr(UExpr->getSubExpr());
1617 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1619 const MCSubtargetInfo *STI) {
1620 MipsTargetStreamer &TOut = getTargetStreamer();
1621 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1622 bool ExpandedJalSym = false;
1626 if (MCID.isBranch() || MCID.isCall()) {
1627 const unsigned Opcode = Inst.getOpcode();
1637 assert(hasCnMips() && "instruction only valid for octeon cpus");
1644 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1645 Offset = Inst.getOperand(2);
1646 if (!Offset.isImm())
1647 break; // We'll deal with this situation later on when applying fixups.
1648 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1649 return Error(IDLoc, "branch target out of range");
1650 if (OffsetToAlignment(Offset.getImm(),
1651 1LL << (inMicroMipsMode() ? 1 : 2)))
1652 return Error(IDLoc, "branch to misaligned address");
1666 case Mips::BGEZAL_MM:
1667 case Mips::BLTZAL_MM:
1670 case Mips::BC1EQZC_MMR6:
1671 case Mips::BC1NEZC_MMR6:
1672 case Mips::BC2EQZC_MMR6:
1673 case Mips::BC2NEZC_MMR6:
1674 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1675 Offset = Inst.getOperand(1);
1676 if (!Offset.isImm())
1677 break; // We'll deal with this situation later on when applying fixups.
1678 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1679 return Error(IDLoc, "branch target out of range");
1680 if (OffsetToAlignment(Offset.getImm(),
1681 1LL << (inMicroMipsMode() ? 1 : 2)))
1682 return Error(IDLoc, "branch to misaligned address");
1684 case Mips::BGEC: case Mips::BGEC_MMR6:
1685 case Mips::BLTC: case Mips::BLTC_MMR6:
1686 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1687 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1688 case Mips::BEQC: case Mips::BEQC_MMR6:
1689 case Mips::BNEC: case Mips::BNEC_MMR6:
1690 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1691 Offset = Inst.getOperand(2);
1692 if (!Offset.isImm())
1693 break; // We'll deal with this situation later on when applying fixups.
1694 if (!isIntN(18, Offset.getImm()))
1695 return Error(IDLoc, "branch target out of range");
1696 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1697 return Error(IDLoc, "branch to misaligned address");
1699 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1700 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1701 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1702 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1703 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1704 Offset = Inst.getOperand(1);
1705 if (!Offset.isImm())
1706 break; // We'll deal with this situation later on when applying fixups.
1707 if (!isIntN(18, Offset.getImm()))
1708 return Error(IDLoc, "branch target out of range");
1709 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1710 return Error(IDLoc, "branch to misaligned address");
1712 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1713 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1714 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1715 Offset = Inst.getOperand(1);
1716 if (!Offset.isImm())
1717 break; // We'll deal with this situation later on when applying fixups.
1718 if (!isIntN(23, Offset.getImm()))
1719 return Error(IDLoc, "branch target out of range");
1720 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1721 return Error(IDLoc, "branch to misaligned address");
1723 case Mips::BEQZ16_MM:
1724 case Mips::BEQZC16_MMR6:
1725 case Mips::BNEZ16_MM:
1726 case Mips::BNEZC16_MMR6:
1727 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1728 Offset = Inst.getOperand(1);
1729 if (!Offset.isImm())
1730 break; // We'll deal with this situation later on when applying fixups.
1731 if (!isInt<8>(Offset.getImm()))
1732 return Error(IDLoc, "branch target out of range");
1733 if (OffsetToAlignment(Offset.getImm(), 2LL))
1734 return Error(IDLoc, "branch to misaligned address");
1739 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1740 // We still accept it but it is a normal nop.
1741 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1742 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1743 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1748 const unsigned Opcode = Inst.getOpcode();
1760 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1761 // The offset is handled above
1762 Opnd = Inst.getOperand(1);
1764 return Error(IDLoc, "expected immediate operand kind");
1765 Imm = Opnd.getImm();
1766 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1767 Opcode == Mips::BBIT1 ? 63 : 31))
1768 return Error(IDLoc, "immediate operand value out of range");
1770 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1772 Inst.getOperand(1).setImm(Imm - 32);
1778 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1779 Opnd = Inst.getOperand(2);
1781 return Error(IDLoc, "expected immediate operand kind");
1782 Imm = Opnd.getImm();
1783 if (!isInt<10>(Imm))
1784 return Error(IDLoc, "immediate operand value out of range");
1789 // For PIC code convert unconditional jump to unconditional branch.
1790 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1793 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1794 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1795 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1796 BInst.addOperand(Inst.getOperand(0));
1800 // This expansion is not in a function called by tryExpandInstruction()
1801 // because the pseudo-instruction doesn't have a distinct opcode.
1802 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1804 warnIfNoMacro(IDLoc);
1806 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1808 // We can do this expansion if there's only 1 symbol in the argument
1810 if (countMCSymbolRefExpr(JalExpr) > 1)
1811 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1813 // FIXME: This is checking the expression can be handled by the later stages
1814 // of the assembler. We ought to leave it to those later stages.
1815 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1817 // FIXME: Add support for label+offset operands (currently causes an error).
1818 // FIXME: Add support for forward-declared local symbols.
1819 // FIXME: Add expansion for when the LargeGOT option is enabled.
1820 if (JalSym->isInSection() || JalSym->isTemporary() ||
1821 (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
1823 // If it's a local symbol and the O32 ABI is being used, we expand to:
1825 // R_(MICRO)MIPS_GOT16 label
1826 // addiu $25, $25, 0
1827 // R_(MICRO)MIPS_LO16 label
1829 const MCExpr *Got16RelocExpr =
1830 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
1831 const MCExpr *Lo16RelocExpr =
1832 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
1834 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
1835 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
1836 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1837 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
1838 } else if (isABI_N32() || isABI_N64()) {
1839 // If it's a local symbol and the N32/N64 ABIs are being used,
1841 // lw/ld $25, 0($gp)
1842 // R_(MICRO)MIPS_GOT_DISP label
1844 const MCExpr *GotDispRelocExpr =
1845 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
1847 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
1848 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
1852 // If it's an external/weak symbol, we expand to:
1853 // lw/ld $25, 0($gp)
1854 // R_(MICRO)MIPS_CALL16 label
1856 const MCExpr *Call16RelocExpr =
1857 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
1859 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1860 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
1864 if (IsCpRestoreSet && inMicroMipsMode())
1865 JalrInst.setOpcode(Mips::JALRS_MM);
1867 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1868 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1869 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1871 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1872 // This relocation is supposed to be an optimization hint for the linker
1873 // and is not necessary for correctness.
1876 ExpandedJalSym = true;
1879 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
1880 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
1881 // Check the offset of memory operand, if it is a symbol
1882 // reference or immediate we may have to expand instructions.
1883 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1884 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1885 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1886 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1887 MCOperand &Op = Inst.getOperand(i);
1889 int MemOffset = Op.getImm();
1890 if (MemOffset < -32768 || MemOffset > 32767) {
1891 // Offset can't exceed 16bit value.
1892 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
1893 return getParser().hasPendingError();
1895 } else if (Op.isExpr()) {
1896 const MCExpr *Expr = Op.getExpr();
1897 if (Expr->getKind() == MCExpr::SymbolRef) {
1898 const MCSymbolRefExpr *SR =
1899 static_cast<const MCSymbolRefExpr *>(Expr);
1900 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1902 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1903 return getParser().hasPendingError();
1905 } else if (!isEvaluated(Expr)) {
1906 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1907 return getParser().hasPendingError();
1914 if (inMicroMipsMode()) {
1915 if (MCID.mayLoad()) {
1916 // Try to create 16-bit GP relative load instruction.
1917 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1918 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1919 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1920 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1921 MCOperand &Op = Inst.getOperand(i);
1923 int MemOffset = Op.getImm();
1924 MCOperand &DstReg = Inst.getOperand(0);
1925 MCOperand &BaseReg = Inst.getOperand(1);
1926 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1927 getContext().getRegisterInfo()->getRegClass(
1928 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1929 (BaseReg.getReg() == Mips::GP ||
1930 BaseReg.getReg() == Mips::GP_64)) {
1932 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1941 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1946 switch (Inst.getOpcode()) {
1949 case Mips::ADDIUSP_MM:
1950 Opnd = Inst.getOperand(0);
1952 return Error(IDLoc, "expected immediate operand kind");
1953 Imm = Opnd.getImm();
1954 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1956 return Error(IDLoc, "immediate operand value out of range");
1958 case Mips::SLL16_MM:
1959 case Mips::SRL16_MM:
1960 Opnd = Inst.getOperand(2);
1962 return Error(IDLoc, "expected immediate operand kind");
1963 Imm = Opnd.getImm();
1964 if (Imm < 1 || Imm > 8)
1965 return Error(IDLoc, "immediate operand value out of range");
1968 Opnd = Inst.getOperand(1);
1970 return Error(IDLoc, "expected immediate operand kind");
1971 Imm = Opnd.getImm();
1972 if (Imm < -1 || Imm > 126)
1973 return Error(IDLoc, "immediate operand value out of range");
1975 case Mips::ADDIUR2_MM:
1976 Opnd = Inst.getOperand(2);
1978 return Error(IDLoc, "expected immediate operand kind");
1979 Imm = Opnd.getImm();
1980 if (!(Imm == 1 || Imm == -1 ||
1981 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1982 return Error(IDLoc, "immediate operand value out of range");
1984 case Mips::ANDI16_MM:
1985 Opnd = Inst.getOperand(2);
1987 return Error(IDLoc, "expected immediate operand kind");
1988 Imm = Opnd.getImm();
1989 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1990 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1991 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1992 return Error(IDLoc, "immediate operand value out of range");
1994 case Mips::LBU16_MM:
1995 Opnd = Inst.getOperand(2);
1997 return Error(IDLoc, "expected immediate operand kind");
1998 Imm = Opnd.getImm();
1999 if (Imm < -1 || Imm > 14)
2000 return Error(IDLoc, "immediate operand value out of range");
2003 case Mips::SB16_MMR6:
2004 Opnd = Inst.getOperand(2);
2006 return Error(IDLoc, "expected immediate operand kind");
2007 Imm = Opnd.getImm();
2008 if (Imm < 0 || Imm > 15)
2009 return Error(IDLoc, "immediate operand value out of range");
2011 case Mips::LHU16_MM:
2013 case Mips::SH16_MMR6:
2014 Opnd = Inst.getOperand(2);
2016 return Error(IDLoc, "expected immediate operand kind");
2017 Imm = Opnd.getImm();
2018 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2019 return Error(IDLoc, "immediate operand value out of range");
2023 case Mips::SW16_MMR6:
2024 Opnd = Inst.getOperand(2);
2026 return Error(IDLoc, "expected immediate operand kind");
2027 Imm = Opnd.getImm();
2028 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2029 return Error(IDLoc, "immediate operand value out of range");
2031 case Mips::ADDIUPC_MM:
2032 MCOperand Opnd = Inst.getOperand(1);
2034 return Error(IDLoc, "expected immediate operand kind");
2035 int Imm = Opnd.getImm();
2036 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2037 return Error(IDLoc, "immediate operand value out of range");
2042 bool FillDelaySlot =
2043 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2045 TOut.emitDirectiveSetNoReorder();
2047 MacroExpanderResultTy ExpandResult =
2048 tryExpandInstruction(Inst, IDLoc, Out, STI);
2049 switch (ExpandResult) {
2051 Out.EmitInstruction(Inst, *STI);
2059 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2060 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2061 if (inMicroMipsMode())
2062 TOut.setUsesMicroMips();
2064 // If this instruction has a delay slot and .set reorder is active,
2065 // emit a NOP after it.
2066 if (FillDelaySlot) {
2067 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2068 TOut.emitDirectiveSetReorder();
2071 if ((Inst.getOpcode() == Mips::JalOneReg ||
2072 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2073 isPicAndNotNxxAbi()) {
2074 if (IsCpRestoreSet) {
2075 // We need a NOP between the JALR and the LW:
2076 // If .set reorder has been used, we've already emitted a NOP.
2077 // If .set noreorder has been used, we need to emit a NOP at this point.
2078 if (!AssemblerOptions.back()->isReorder())
2079 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2082 // Load the $gp from the stack.
2083 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2085 Warning(IDLoc, "no .cprestore used in PIC mode");
2091 MipsAsmParser::MacroExpanderResultTy
2092 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2093 const MCSubtargetInfo *STI) {
2094 switch (Inst.getOpcode()) {
2096 return MER_NotAMacro;
2097 case Mips::LoadImm32:
2098 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2099 case Mips::LoadImm64:
2100 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2101 case Mips::LoadAddrImm32:
2102 case Mips::LoadAddrImm64:
2103 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2104 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2105 "expected immediate operand kind");
2107 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2109 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2113 case Mips::LoadAddrReg32:
2114 case Mips::LoadAddrReg64:
2115 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2116 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2117 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2118 "expected immediate operand kind");
2120 return expandLoadAddress(Inst.getOperand(0).getReg(),
2121 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2122 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2126 case Mips::B_MM_Pseudo:
2127 case Mips::B_MMR6_Pseudo:
2128 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2132 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2134 case Mips::JalOneReg:
2135 case Mips::JalTwoReg:
2136 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2139 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2156 case Mips::BLTImmMacro:
2157 case Mips::BLEImmMacro:
2158 case Mips::BGEImmMacro:
2159 case Mips::BGTImmMacro:
2160 case Mips::BLTUImmMacro:
2161 case Mips::BLEUImmMacro:
2162 case Mips::BGEUImmMacro:
2163 case Mips::BGTUImmMacro:
2164 case Mips::BLTLImmMacro:
2165 case Mips::BLELImmMacro:
2166 case Mips::BGELImmMacro:
2167 case Mips::BGTLImmMacro:
2168 case Mips::BLTULImmMacro:
2169 case Mips::BLEULImmMacro:
2170 case Mips::BGEULImmMacro:
2171 case Mips::BGTULImmMacro:
2172 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2173 case Mips::SDivMacro:
2174 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2176 case Mips::DSDivMacro:
2177 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2179 case Mips::UDivMacro:
2180 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2182 case Mips::DUDivMacro:
2183 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2185 case Mips::PseudoTRUNC_W_S:
2186 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2188 case Mips::PseudoTRUNC_W_D32:
2189 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2191 case Mips::PseudoTRUNC_W_D:
2192 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2195 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2197 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2199 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2202 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2204 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2209 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2210 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2211 int64_t ImmValue = Inst.getOperand(2).getImm();
2212 if (isInt<16>(ImmValue))
2213 return MER_NotAMacro;
2214 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2217 return MER_NotAMacro;
2221 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2222 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2223 int64_t ImmValue = Inst.getOperand(2).getImm();
2224 if (isUInt<16>(ImmValue))
2225 return MER_NotAMacro;
2226 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2229 return MER_NotAMacro;
2232 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2235 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2238 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2241 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2242 case Mips::ABSMacro:
2243 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2246 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2247 Inst.getOpcode() == Mips::LDMacro)
2250 case Mips::SEQMacro:
2251 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2252 case Mips::SEQIMacro:
2253 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2257 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2259 const MCSubtargetInfo *STI) {
2260 MipsTargetStreamer &TOut = getTargetStreamer();
2262 // Create a JALR instruction which is going to replace the pseudo-JAL.
2264 JalrInst.setLoc(IDLoc);
2265 const MCOperand FirstRegOp = Inst.getOperand(0);
2266 const unsigned Opcode = Inst.getOpcode();
2268 if (Opcode == Mips::JalOneReg) {
2269 // jal $rs => jalr $rs
2270 if (IsCpRestoreSet && inMicroMipsMode()) {
2271 JalrInst.setOpcode(Mips::JALRS16_MM);
2272 JalrInst.addOperand(FirstRegOp);
2273 } else if (inMicroMipsMode()) {
2274 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2275 JalrInst.addOperand(FirstRegOp);
2277 JalrInst.setOpcode(Mips::JALR);
2278 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2279 JalrInst.addOperand(FirstRegOp);
2281 } else if (Opcode == Mips::JalTwoReg) {
2282 // jal $rd, $rs => jalr $rd, $rs
2283 if (IsCpRestoreSet && inMicroMipsMode())
2284 JalrInst.setOpcode(Mips::JALRS_MM);
2286 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2287 JalrInst.addOperand(FirstRegOp);
2288 const MCOperand SecondRegOp = Inst.getOperand(1);
2289 JalrInst.addOperand(SecondRegOp);
2291 Out.EmitInstruction(JalrInst, *STI);
2293 // If .set reorder is active and branch instruction has a delay slot,
2294 // emit a NOP after it.
2295 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2296 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2297 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2303 /// Can the value be represented by a unsigned N-bit value and a shift left?
2304 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2305 unsigned BitNum = findFirstSet(x);
2307 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2310 /// Load (or add) an immediate into a register.
2312 /// @param ImmValue The immediate to load.
2313 /// @param DstReg The register that will hold the immediate.
2314 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2315 /// for a simple initialization.
2316 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2317 /// @param IsAddress True if the immediate represents an address. False if it
2319 /// @param IDLoc Location of the immediate in the source file.
2320 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2321 unsigned SrcReg, bool Is32BitImm,
2322 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2323 const MCSubtargetInfo *STI) {
2324 MipsTargetStreamer &TOut = getTargetStreamer();
2326 if (!Is32BitImm && !isGP64bit()) {
2327 Error(IDLoc, "instruction requires a 64-bit architecture");
2332 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2333 // Sign extend up to 64-bit so that the predicates match the hardware
2334 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2336 ImmValue = SignExtend64<32>(ImmValue);
2338 Error(IDLoc, "instruction requires a 32-bit immediate");
2343 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2344 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2346 bool UseSrcReg = false;
2347 if (SrcReg != Mips::NoRegister)
2350 unsigned TmpReg = DstReg;
2352 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2353 // At this point we need AT to perform the expansions and we exit if it is
2355 unsigned ATReg = getATReg(IDLoc);
2361 if (isInt<16>(ImmValue)) {
2365 // This doesn't quite follow the usual ABI expectations for N32 but matches
2366 // traditional assembler behaviour. N32 would normally use addiu for both
2367 // integers and addresses.
2368 if (IsAddress && !Is32BitImm) {
2369 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2373 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2377 if (isUInt<16>(ImmValue)) {
2378 unsigned TmpReg = DstReg;
2379 if (SrcReg == DstReg) {
2380 TmpReg = getATReg(IDLoc);
2385 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2387 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2391 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2392 warnIfNoMacro(IDLoc);
2394 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2395 uint16_t Bits15To0 = ImmValue & 0xffff;
2397 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2398 // Traditional behaviour seems to special case this particular value. It's
2399 // not clear why other masks are handled differently.
2400 if (ImmValue == 0xffffffff) {
2401 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2402 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2404 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2408 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2410 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2411 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2413 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2415 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2419 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2421 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2423 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2427 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2429 Error(IDLoc, "instruction requires a 32-bit immediate");
2433 // Traditionally, these immediates are shifted as little as possible and as
2434 // such we align the most significant bit to bit 15 of our temporary.
2435 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2436 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2437 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2438 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2439 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2440 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2443 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2448 warnIfNoMacro(IDLoc);
2450 // The remaining case is packed with a sequence of dsll and ori with zeros
2451 // being omitted and any neighbouring dsll's being coalesced.
2452 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2454 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2455 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2459 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2460 // skip it and defer the shift to the next chunk.
2461 unsigned ShiftCarriedForwards = 16;
2462 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2463 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2465 if (ImmChunk != 0) {
2466 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2467 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2468 ShiftCarriedForwards = 0;
2471 ShiftCarriedForwards += 16;
2473 ShiftCarriedForwards -= 16;
2475 // Finish any remaining shifts left by trailing zeros.
2476 if (ShiftCarriedForwards)
2477 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2480 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2485 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2486 MCStreamer &Out, const MCSubtargetInfo *STI) {
2487 const MCOperand &ImmOp = Inst.getOperand(1);
2488 assert(ImmOp.isImm() && "expected immediate operand kind");
2489 const MCOperand &DstRegOp = Inst.getOperand(0);
2490 assert(DstRegOp.isReg() && "expected register operand kind");
2492 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2493 Is32BitImm, false, IDLoc, Out, STI))
2499 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2500 const MCOperand &Offset,
2501 bool Is32BitAddress, SMLoc IDLoc,
2503 const MCSubtargetInfo *STI) {
2504 // la can't produce a usable address when addresses are 64-bit.
2505 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2506 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2507 // We currently can't do this because we depend on the equality
2508 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2509 Error(IDLoc, "la used to load 64-bit address");
2510 // Continue as if we had 'dla' instead.
2511 Is32BitAddress = false;
2515 // dla requires 64-bit addresses.
2516 if (!Is32BitAddress && !hasMips3()) {
2517 Error(IDLoc, "instruction requires a 64-bit architecture");
2521 if (!Offset.isImm())
2522 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2523 Is32BitAddress, IDLoc, Out, STI);
2525 if (!ABI.ArePtrs64bit()) {
2526 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2527 Is32BitAddress = true;
2530 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2534 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2535 unsigned DstReg, unsigned SrcReg,
2536 bool Is32BitSym, SMLoc IDLoc,
2538 const MCSubtargetInfo *STI) {
2539 MipsTargetStreamer &TOut = getTargetStreamer();
2540 bool UseSrcReg = SrcReg != Mips::NoRegister;
2541 warnIfNoMacro(IDLoc);
2543 if (inPicMode() && ABI.IsO32()) {
2545 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2546 Error(IDLoc, "expected relocatable expression");
2549 if (Res.getSymB() != nullptr) {
2550 Error(IDLoc, "expected relocatable expression with only one symbol");
2554 // The case where the result register is $25 is somewhat special. If the
2555 // symbol in the final relocation is external and not modified with a
2556 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2557 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2558 Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
2559 !Res.getSymA()->getSymbol().isTemporary()) {
2560 const MCExpr *CallExpr =
2561 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2562 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2563 MCOperand::createExpr(CallExpr), IDLoc, STI);
2567 // The remaining cases are:
2568 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2569 // >addiu $tmp, $tmp, %lo(offset)
2570 // >addiu $rd, $tmp, $rs
2571 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2572 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2573 // >addiu $rd, $tmp, $rs
2574 // The addiu's marked with a '>' may be omitted if they are redundant. If
2575 // this happens then the last instruction must use $rd as the result
2577 const MipsMCExpr *GotExpr =
2578 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2579 const MCExpr *LoExpr = nullptr;
2580 if (Res.getSymA()->getSymbol().isInSection() ||
2581 Res.getSymA()->getSymbol().isTemporary())
2582 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2583 else if (Res.getConstant() != 0) {
2584 // External symbols fully resolve the symbol with just the %got(symbol)
2585 // but we must still account for any offset to the symbol for expressions
2587 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2590 unsigned TmpReg = DstReg;
2592 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2594 // If $rs is the same as $rd, we need to use AT.
2595 // If it is not available we exit.
2596 unsigned ATReg = getATReg(IDLoc);
2602 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2603 MCOperand::createExpr(GotExpr), IDLoc, STI);
2606 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2610 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2615 const MipsMCExpr *HiExpr =
2616 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2617 const MipsMCExpr *LoExpr =
2618 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2620 // This is the 64-bit symbol address expansion.
2621 if (ABI.ArePtrs64bit() && isGP64bit()) {
2622 // We always need AT for the 64-bit expansion.
2623 // If it is not available we exit.
2624 unsigned ATReg = getATReg(IDLoc);
2628 const MipsMCExpr *HighestExpr =
2629 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2630 const MipsMCExpr *HigherExpr =
2631 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2634 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2636 // If $rs is the same as $rd:
2637 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2638 // daddiu $at, $at, %higher(sym)
2639 // dsll $at, $at, 16
2640 // daddiu $at, $at, %hi(sym)
2641 // dsll $at, $at, 16
2642 // daddiu $at, $at, %lo(sym)
2643 // daddu $rd, $at, $rd
2644 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2646 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2647 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2648 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2649 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2651 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2652 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2654 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2659 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2660 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2661 // lui $at, %hi(sym)
2662 // daddiu $rd, $rd, %higher(sym)
2663 // daddiu $at, $at, %lo(sym)
2664 // dsll32 $rd, $rd, 0
2665 // daddu $rd, $rd, $at
2666 // (daddu $rd, $rd, $rs)
2667 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2669 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2670 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2671 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2672 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2674 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2675 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2677 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2682 // And now, the 32-bit symbol address expansion:
2683 // If $rs is the same as $rd:
2684 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2685 // ori $at, $at, %lo(sym)
2686 // addu $rd, $at, $rd
2687 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2688 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2689 // ori $rd, $rd, %lo(sym)
2690 // (addu $rd, $rd, $rs)
2691 unsigned TmpReg = DstReg;
2693 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2694 // If $rs is the same as $rd, we need to use AT.
2695 // If it is not available we exit.
2696 unsigned ATReg = getATReg(IDLoc);
2702 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2703 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2707 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2710 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2715 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
2717 const MCSubtargetInfo *STI) {
2718 MipsTargetStreamer &TOut = getTargetStreamer();
2720 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2721 "unexpected number of operands");
2723 MCOperand Offset = Inst.getOperand(0);
2724 if (Offset.isExpr()) {
2726 Inst.setOpcode(Mips::BEQ_MM);
2727 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2728 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2729 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2731 assert(Offset.isImm() && "expected immediate operand kind");
2732 if (isInt<11>(Offset.getImm())) {
2733 // If offset fits into 11 bits then this instruction becomes microMIPS
2734 // 16-bit unconditional branch instruction.
2735 if (inMicroMipsMode())
2736 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2738 if (!isInt<17>(Offset.getImm()))
2739 return Error(IDLoc, "branch target out of range");
2740 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2741 return Error(IDLoc, "branch to misaligned address");
2743 Inst.setOpcode(Mips::BEQ_MM);
2744 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2745 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2746 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2749 Out.EmitInstruction(Inst, *STI);
2751 // If .set reorder is active and branch instruction has a delay slot,
2752 // emit a NOP after it.
2753 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2754 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2755 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
2760 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2761 const MCSubtargetInfo *STI) {
2762 MipsTargetStreamer &TOut = getTargetStreamer();
2763 const MCOperand &DstRegOp = Inst.getOperand(0);
2764 assert(DstRegOp.isReg() && "expected register operand kind");
2766 const MCOperand &ImmOp = Inst.getOperand(1);
2767 assert(ImmOp.isImm() && "expected immediate operand kind");
2769 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2770 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
2771 "expected immediate or expression operand");
2773 unsigned OpCode = 0;
2774 switch(Inst.getOpcode()) {
2782 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2786 int64_t ImmValue = ImmOp.getImm();
2788 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2791 warnIfNoMacro(IDLoc);
2793 unsigned ATReg = getATReg(IDLoc);
2797 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2801 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
2806 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2807 const MCSubtargetInfo *STI, bool IsLoad,
2810 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2813 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2816 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2817 const MCSubtargetInfo *STI, bool IsImmOpnd) {
2818 MipsTargetStreamer &TOut = getTargetStreamer();
2820 unsigned DstReg = Inst.getOperand(0).getReg();
2821 unsigned BaseReg = Inst.getOperand(1).getReg();
2823 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2824 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
2825 unsigned DstRegClassID =
2826 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
2827 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
2828 (DstRegClassID == Mips::GPR64RegClassID);
2831 // Try to use DstReg as the temporary.
2832 if (IsGPR && (BaseReg != DstReg)) {
2833 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2834 Inst.getOperand(2).getImm(), DstReg, IDLoc,
2839 // At this point we need AT to perform the expansions and we exit if it is
2841 unsigned ATReg = getATReg(IDLoc);
2845 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2846 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
2850 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2851 MCOperand LoOperand = MCOperand::createExpr(
2852 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2853 MCOperand HiOperand = MCOperand::createExpr(
2854 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2856 // Try to use DstReg as the temporary.
2857 if (IsGPR && (BaseReg != DstReg)) {
2858 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2859 LoOperand, DstReg, IDLoc, STI);
2863 // At this point we need AT to perform the expansions and we exit if it is
2865 unsigned ATReg = getATReg(IDLoc);
2869 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2870 LoOperand, ATReg, IDLoc, STI);
2873 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2874 const MCSubtargetInfo *STI,
2876 MipsTargetStreamer &TOut = getTargetStreamer();
2878 unsigned SrcReg = Inst.getOperand(0).getReg();
2879 unsigned BaseReg = Inst.getOperand(1).getReg();
2882 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
2883 Inst.getOperand(2).getImm(),
2884 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
2888 unsigned ATReg = getATReg(IDLoc);
2892 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2893 MCOperand LoOperand = MCOperand::createExpr(
2894 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2895 MCOperand HiOperand = MCOperand::createExpr(
2896 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2897 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
2898 LoOperand, ATReg, IDLoc, STI);
2901 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2903 const MCSubtargetInfo *STI) {
2904 unsigned OpNum = Inst.getNumOperands();
2905 unsigned Opcode = Inst.getOpcode();
2906 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2908 assert (Inst.getOperand(OpNum - 1).isImm() &&
2909 Inst.getOperand(OpNum - 2).isReg() &&
2910 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2912 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2913 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2914 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2915 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2916 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2917 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2918 // It can be implemented as SWM16 or LWM16 instruction.
2919 if (inMicroMipsMode() && hasMips32r6())
2920 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2922 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2925 Inst.setOpcode(NewOpcode);
2926 Out.EmitInstruction(Inst, *STI);
2930 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2932 const MCSubtargetInfo *STI) {
2933 MipsTargetStreamer &TOut = getTargetStreamer();
2934 bool EmittedNoMacroWarning = false;
2935 unsigned PseudoOpcode = Inst.getOpcode();
2936 unsigned SrcReg = Inst.getOperand(0).getReg();
2937 const MCOperand &TrgOp = Inst.getOperand(1);
2938 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2940 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2941 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2945 TrgReg = TrgOp.getReg();
2946 else if (TrgOp.isImm()) {
2947 warnIfNoMacro(IDLoc);
2948 EmittedNoMacroWarning = true;
2950 TrgReg = getATReg(IDLoc);
2954 switch(PseudoOpcode) {
2956 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2957 case Mips::BLTImmMacro:
2958 PseudoOpcode = Mips::BLT;
2960 case Mips::BLEImmMacro:
2961 PseudoOpcode = Mips::BLE;
2963 case Mips::BGEImmMacro:
2964 PseudoOpcode = Mips::BGE;
2966 case Mips::BGTImmMacro:
2967 PseudoOpcode = Mips::BGT;
2969 case Mips::BLTUImmMacro:
2970 PseudoOpcode = Mips::BLTU;
2972 case Mips::BLEUImmMacro:
2973 PseudoOpcode = Mips::BLEU;
2975 case Mips::BGEUImmMacro:
2976 PseudoOpcode = Mips::BGEU;
2978 case Mips::BGTUImmMacro:
2979 PseudoOpcode = Mips::BGTU;
2981 case Mips::BLTLImmMacro:
2982 PseudoOpcode = Mips::BLTL;
2984 case Mips::BLELImmMacro:
2985 PseudoOpcode = Mips::BLEL;
2987 case Mips::BGELImmMacro:
2988 PseudoOpcode = Mips::BGEL;
2990 case Mips::BGTLImmMacro:
2991 PseudoOpcode = Mips::BGTL;
2993 case Mips::BLTULImmMacro:
2994 PseudoOpcode = Mips::BLTUL;
2996 case Mips::BLEULImmMacro:
2997 PseudoOpcode = Mips::BLEUL;
2999 case Mips::BGEULImmMacro:
3000 PseudoOpcode = Mips::BGEUL;
3002 case Mips::BGTULImmMacro:
3003 PseudoOpcode = Mips::BGTUL;
3007 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3008 false, IDLoc, Out, STI))
3012 switch (PseudoOpcode) {
3017 AcceptsEquality = false;
3018 ReverseOrderSLT = false;
3019 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3020 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3021 ZeroSrcOpcode = Mips::BGTZ;
3022 ZeroTrgOpcode = Mips::BLTZ;
3028 AcceptsEquality = true;
3029 ReverseOrderSLT = true;
3030 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3031 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3032 ZeroSrcOpcode = Mips::BGEZ;
3033 ZeroTrgOpcode = Mips::BLEZ;
3039 AcceptsEquality = true;
3040 ReverseOrderSLT = false;
3041 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3042 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3043 ZeroSrcOpcode = Mips::BLEZ;
3044 ZeroTrgOpcode = Mips::BGEZ;
3050 AcceptsEquality = false;
3051 ReverseOrderSLT = true;
3052 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3053 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3054 ZeroSrcOpcode = Mips::BLTZ;
3055 ZeroTrgOpcode = Mips::BGTZ;
3058 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3061 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3062 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3063 if (IsSrcRegZero && IsTrgRegZero) {
3064 // FIXME: All of these Opcode-specific if's are needed for compatibility
3065 // with GAS' behaviour. However, they may not generate the most efficient
3066 // code in some circumstances.
3067 if (PseudoOpcode == Mips::BLT) {
3068 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3072 if (PseudoOpcode == Mips::BLE) {
3073 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3075 Warning(IDLoc, "branch is always taken");
3078 if (PseudoOpcode == Mips::BGE) {
3079 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3081 Warning(IDLoc, "branch is always taken");
3084 if (PseudoOpcode == Mips::BGT) {
3085 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3089 if (PseudoOpcode == Mips::BGTU) {
3090 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3091 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3094 if (AcceptsEquality) {
3095 // If both registers are $0 and the pseudo-branch accepts equality, it
3096 // will always be taken, so we emit an unconditional branch.
3097 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3098 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3099 Warning(IDLoc, "branch is always taken");
3102 // If both registers are $0 and the pseudo-branch does not accept
3103 // equality, it will never be taken, so we don't have to emit anything.
3106 if (IsSrcRegZero || IsTrgRegZero) {
3107 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3108 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3109 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3110 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3111 // the pseudo-branch will never be taken, so we don't emit anything.
3112 // This only applies to unsigned pseudo-branches.
3115 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3116 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3117 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3118 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3119 // the pseudo-branch will always be taken, so we emit an unconditional
3121 // This only applies to unsigned pseudo-branches.
3122 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3123 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3124 Warning(IDLoc, "branch is always taken");
3128 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3129 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3130 // the pseudo-branch will be taken only when the non-zero register is
3131 // different from 0, so we emit a BNEZ.
3133 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3134 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3135 // the pseudo-branch will be taken only when the non-zero register is
3136 // equal to 0, so we emit a BEQZ.
3138 // Because only BLEU and BGEU branch on equality, we can use the
3139 // AcceptsEquality variable to decide when to emit the BEQZ.
3140 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3141 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3142 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3145 // If we have a signed pseudo-branch and one of the registers is $0,
3146 // we can use an appropriate compare-to-zero branch. We select which one
3147 // to use in the switch statement above.
3148 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3149 IsSrcRegZero ? TrgReg : SrcReg,
3150 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3154 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3155 // expansions. If it is not available, we return.
3156 unsigned ATRegNum = getATReg(IDLoc);
3160 if (!EmittedNoMacroWarning)
3161 warnIfNoMacro(IDLoc);
3163 // SLT fits well with 2 of our 4 pseudo-branches:
3164 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3165 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3166 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3167 // This is accomplished by using a BNEZ with the result of the SLT.
3169 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3170 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3171 // Because only BGE and BLE branch on equality, we can use the
3172 // AcceptsEquality variable to decide when to emit the BEQZ.
3173 // Note that the order of the SLT arguments doesn't change between
3176 // The same applies to the unsigned variants, except that SLTu is used
3178 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3179 ReverseOrderSLT ? TrgReg : SrcReg,
3180 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3182 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3183 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3184 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3189 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3190 const MCSubtargetInfo *STI, const bool IsMips64,
3191 const bool Signed) {
3192 MipsTargetStreamer &TOut = getTargetStreamer();
3194 warnIfNoMacro(IDLoc);
3196 const MCOperand &RdRegOp = Inst.getOperand(0);
3197 assert(RdRegOp.isReg() && "expected register operand kind");
3198 unsigned RdReg = RdRegOp.getReg();
3200 const MCOperand &RsRegOp = Inst.getOperand(1);
3201 assert(RsRegOp.isReg() && "expected register operand kind");
3202 unsigned RsReg = RsRegOp.getReg();
3204 const MCOperand &RtRegOp = Inst.getOperand(2);
3205 assert(RtRegOp.isReg() && "expected register operand kind");
3206 unsigned RtReg = RtRegOp.getReg();
3211 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3212 ZeroReg = Mips::ZERO_64;
3214 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3215 ZeroReg = Mips::ZERO;
3218 bool UseTraps = useTraps();
3220 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3221 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
3222 Warning(IDLoc, "dividing zero by zero");
3224 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3226 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3230 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3234 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3239 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3240 Warning(IDLoc, "division by zero");
3243 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3247 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3252 // FIXME: The values for these two BranchTarget variables may be different in
3253 // micromips. These magic numbers need to be removed.
3254 unsigned BranchTargetNoTraps;
3255 unsigned BranchTarget;
3258 BranchTarget = IsMips64 ? 12 : 8;
3259 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3261 BranchTarget = IsMips64 ? 20 : 16;
3262 BranchTargetNoTraps = 8;
3263 // Branch to the li instruction.
3264 TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI);
3267 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3270 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3273 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3277 unsigned ATReg = getATReg(IDLoc);
3281 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3283 // Branch to the mflo instruction.
3284 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3285 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3286 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3288 // Branch to the mflo instruction.
3289 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3290 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3294 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3296 // Branch to the mflo instruction.
3297 TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI);
3298 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3299 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3301 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3305 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3306 SMLoc IDLoc, MCStreamer &Out,
3307 const MCSubtargetInfo *STI) {
3308 MipsTargetStreamer &TOut = getTargetStreamer();
3310 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3311 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
3312 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
3314 unsigned FirstReg = Inst.getOperand(0).getReg();
3315 unsigned SecondReg = Inst.getOperand(1).getReg();
3316 unsigned ThirdReg = Inst.getOperand(2).getReg();
3318 if (hasMips1() && !hasMips2()) {
3319 unsigned ATReg = getATReg(IDLoc);
3322 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3323 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3324 TOut.emitNop(IDLoc, STI);
3325 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3326 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3327 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3328 TOut.emitNop(IDLoc, STI);
3329 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3331 FirstReg, SecondReg, IDLoc, STI);
3332 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3333 TOut.emitNop(IDLoc, STI);
3337 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3339 FirstReg, SecondReg, IDLoc, STI);
3344 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3345 MCStreamer &Out, const MCSubtargetInfo *STI) {
3346 if (hasMips32r6() || hasMips64r6()) {
3347 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3350 const MCOperand &DstRegOp = Inst.getOperand(0);
3351 assert(DstRegOp.isReg() && "expected register operand kind");
3352 const MCOperand &SrcRegOp = Inst.getOperand(1);
3353 assert(SrcRegOp.isReg() && "expected register operand kind");
3354 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3355 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3357 MipsTargetStreamer &TOut = getTargetStreamer();
3358 unsigned DstReg = DstRegOp.getReg();
3359 unsigned SrcReg = SrcRegOp.getReg();
3360 int64_t OffsetValue = OffsetImmOp.getImm();
3362 // NOTE: We always need AT for ULHU, as it is always used as the source
3363 // register for one of the LBu's.
3364 warnIfNoMacro(IDLoc);
3365 unsigned ATReg = getATReg(IDLoc);
3369 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3370 if (IsLargeOffset) {
3371 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3376 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
3377 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3379 std::swap(FirstOffset, SecondOffset);
3381 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
3382 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
3384 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
3385 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
3387 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3388 FirstOffset, IDLoc, STI);
3389 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
3390 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
3391 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3396 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3397 const MCSubtargetInfo *STI) {
3398 if (hasMips32r6() || hasMips64r6()) {
3399 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3402 const MCOperand &DstRegOp = Inst.getOperand(0);
3403 assert(DstRegOp.isReg() && "expected register operand kind");
3404 const MCOperand &SrcRegOp = Inst.getOperand(1);
3405 assert(SrcRegOp.isReg() && "expected register operand kind");
3406 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3407 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3409 MipsTargetStreamer &TOut = getTargetStreamer();
3410 unsigned DstReg = DstRegOp.getReg();
3411 unsigned SrcReg = SrcRegOp.getReg();
3412 int64_t OffsetValue = OffsetImmOp.getImm();
3414 warnIfNoMacro(IDLoc);
3415 unsigned ATReg = getATReg(IDLoc);
3419 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3420 if (IsLargeOffset) {
3421 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3426 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3427 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
3429 std::swap(FirstOffset, SecondOffset);
3431 if (IsLargeOffset) {
3432 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
3433 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
3434 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
3435 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
3436 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
3437 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3439 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
3440 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
3441 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
3447 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3448 const MCSubtargetInfo *STI) {
3449 if (hasMips32r6() || hasMips64r6()) {
3450 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3453 const MCOperand &DstRegOp = Inst.getOperand(0);
3454 assert(DstRegOp.isReg() && "expected register operand kind");
3455 const MCOperand &SrcRegOp = Inst.getOperand(1);
3456 assert(SrcRegOp.isReg() && "expected register operand kind");
3457 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3458 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3460 MipsTargetStreamer &TOut = getTargetStreamer();
3461 unsigned DstReg = DstRegOp.getReg();
3462 unsigned SrcReg = SrcRegOp.getReg();
3463 int64_t OffsetValue = OffsetImmOp.getImm();
3465 // Compute left/right load/store offsets.
3466 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
3467 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
3468 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
3470 std::swap(LxlOffset, LxrOffset);
3472 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
3473 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
3474 unsigned TmpReg = SrcReg;
3475 if (IsLargeOffset || DoMove) {
3476 warnIfNoMacro(IDLoc);
3477 TmpReg = getATReg(IDLoc);
3482 if (IsLargeOffset) {
3483 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
3489 std::swap(DstReg, TmpReg);
3491 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
3492 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
3493 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
3494 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
3497 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
3502 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3504 const MCSubtargetInfo *STI) {
3505 MipsTargetStreamer &TOut = getTargetStreamer();
3507 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3508 assert (Inst.getOperand(0).isReg() &&
3509 Inst.getOperand(1).isReg() &&
3510 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3512 unsigned ATReg = Mips::NoRegister;
3513 unsigned FinalDstReg = Mips::NoRegister;
3514 unsigned DstReg = Inst.getOperand(0).getReg();
3515 unsigned SrcReg = Inst.getOperand(1).getReg();
3516 int64_t ImmValue = Inst.getOperand(2).getImm();
3518 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3520 unsigned FinalOpcode = Inst.getOpcode();
3522 if (DstReg == SrcReg) {
3523 ATReg = getATReg(Inst.getLoc());
3526 FinalDstReg = DstReg;
3530 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
3531 switch (FinalOpcode) {
3533 llvm_unreachable("unimplemented expansion");
3535 FinalOpcode = Mips::ADD;
3538 FinalOpcode = Mips::ADDu;
3541 FinalOpcode = Mips::AND;
3543 case (Mips::NORImm):
3544 FinalOpcode = Mips::NOR;
3547 FinalOpcode = Mips::OR;
3550 FinalOpcode = Mips::SLT;
3553 FinalOpcode = Mips::SLTu;
3556 FinalOpcode = Mips::XOR;
3560 if (FinalDstReg == Mips::NoRegister)
3561 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
3563 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
3569 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3570 const MCSubtargetInfo *STI) {
3571 MipsTargetStreamer &TOut = getTargetStreamer();
3572 unsigned ATReg = Mips::NoRegister;
3573 unsigned DReg = Inst.getOperand(0).getReg();
3574 unsigned SReg = Inst.getOperand(1).getReg();
3575 unsigned TReg = Inst.getOperand(2).getReg();
3576 unsigned TmpReg = DReg;
3578 unsigned FirstShift = Mips::NOP;
3579 unsigned SecondShift = Mips::NOP;
3581 if (hasMips32r2()) {
3584 TmpReg = getATReg(Inst.getLoc());
3589 if (Inst.getOpcode() == Mips::ROL) {
3590 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3591 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3595 if (Inst.getOpcode() == Mips::ROR) {
3596 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3605 switch (Inst.getOpcode()) {
3607 llvm_unreachable("unexpected instruction opcode");
3609 FirstShift = Mips::SRLV;
3610 SecondShift = Mips::SLLV;
3613 FirstShift = Mips::SLLV;
3614 SecondShift = Mips::SRLV;
3618 ATReg = getATReg(Inst.getLoc());
3622 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3623 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3624 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3625 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3633 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3635 const MCSubtargetInfo *STI) {
3636 MipsTargetStreamer &TOut = getTargetStreamer();
3637 unsigned ATReg = Mips::NoRegister;
3638 unsigned DReg = Inst.getOperand(0).getReg();
3639 unsigned SReg = Inst.getOperand(1).getReg();
3640 int64_t ImmValue = Inst.getOperand(2).getImm();
3642 unsigned FirstShift = Mips::NOP;
3643 unsigned SecondShift = Mips::NOP;
3645 if (hasMips32r2()) {
3647 if (Inst.getOpcode() == Mips::ROLImm) {
3648 uint64_t MaxShift = 32;
3649 uint64_t ShiftValue = ImmValue;
3651 ShiftValue = MaxShift - ImmValue;
3652 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3656 if (Inst.getOpcode() == Mips::RORImm) {
3657 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
3666 if (ImmValue == 0) {
3667 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
3671 switch (Inst.getOpcode()) {
3673 llvm_unreachable("unexpected instruction opcode");
3675 FirstShift = Mips::SLL;
3676 SecondShift = Mips::SRL;
3679 FirstShift = Mips::SRL;
3680 SecondShift = Mips::SLL;
3684 ATReg = getATReg(Inst.getLoc());
3688 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
3689 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
3690 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3698 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3699 const MCSubtargetInfo *STI) {
3700 MipsTargetStreamer &TOut = getTargetStreamer();
3701 unsigned ATReg = Mips::NoRegister;
3702 unsigned DReg = Inst.getOperand(0).getReg();
3703 unsigned SReg = Inst.getOperand(1).getReg();
3704 unsigned TReg = Inst.getOperand(2).getReg();
3705 unsigned TmpReg = DReg;
3707 unsigned FirstShift = Mips::NOP;
3708 unsigned SecondShift = Mips::NOP;
3710 if (hasMips64r2()) {
3712 if (TmpReg == SReg) {
3713 TmpReg = getATReg(Inst.getLoc());
3718 if (Inst.getOpcode() == Mips::DROL) {
3719 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3720 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3724 if (Inst.getOpcode() == Mips::DROR) {
3725 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3734 switch (Inst.getOpcode()) {
3736 llvm_unreachable("unexpected instruction opcode");
3738 FirstShift = Mips::DSRLV;
3739 SecondShift = Mips::DSLLV;
3742 FirstShift = Mips::DSLLV;
3743 SecondShift = Mips::DSRLV;
3747 ATReg = getATReg(Inst.getLoc());
3751 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3752 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3753 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3754 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3762 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3764 const MCSubtargetInfo *STI) {
3765 MipsTargetStreamer &TOut = getTargetStreamer();
3766 unsigned ATReg = Mips::NoRegister;
3767 unsigned DReg = Inst.getOperand(0).getReg();
3768 unsigned SReg = Inst.getOperand(1).getReg();
3769 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3771 unsigned FirstShift = Mips::NOP;
3772 unsigned SecondShift = Mips::NOP;
3776 if (hasMips64r2()) {
3778 unsigned FinalOpcode = Mips::NOP;
3780 FinalOpcode = Mips::DROTR;
3781 else if (ImmValue % 32 == 0)
3782 FinalOpcode = Mips::DROTR32;
3783 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3784 if (Inst.getOpcode() == Mips::DROLImm)
3785 FinalOpcode = Mips::DROTR32;
3787 FinalOpcode = Mips::DROTR;
3788 } else if (ImmValue >= 33) {
3789 if (Inst.getOpcode() == Mips::DROLImm)
3790 FinalOpcode = Mips::DROTR;
3792 FinalOpcode = Mips::DROTR32;
3795 uint64_t ShiftValue = ImmValue % 32;
3796 if (Inst.getOpcode() == Mips::DROLImm)
3797 ShiftValue = (32 - ImmValue % 32) % 32;
3799 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3806 if (ImmValue == 0) {
3807 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
3811 switch (Inst.getOpcode()) {
3813 llvm_unreachable("unexpected instruction opcode");
3815 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3816 FirstShift = Mips::DSLL;
3817 SecondShift = Mips::DSRL32;
3819 if (ImmValue == 32) {
3820 FirstShift = Mips::DSLL32;
3821 SecondShift = Mips::DSRL32;
3823 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3824 FirstShift = Mips::DSLL32;
3825 SecondShift = Mips::DSRL;
3829 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3830 FirstShift = Mips::DSRL;
3831 SecondShift = Mips::DSLL32;
3833 if (ImmValue == 32) {
3834 FirstShift = Mips::DSRL32;
3835 SecondShift = Mips::DSLL32;
3837 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3838 FirstShift = Mips::DSRL32;
3839 SecondShift = Mips::DSLL;
3844 ATReg = getATReg(Inst.getLoc());
3848 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
3849 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
3850 Inst.getLoc(), STI);
3851 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3859 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3860 const MCSubtargetInfo *STI) {
3861 MipsTargetStreamer &TOut = getTargetStreamer();
3862 unsigned FirstRegOp = Inst.getOperand(0).getReg();
3863 unsigned SecondRegOp = Inst.getOperand(1).getReg();
3865 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
3866 if (FirstRegOp != SecondRegOp)
3867 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
3869 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
3870 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
3875 static unsigned nextReg(unsigned Reg) {
3877 case Mips::ZERO: return Mips::AT;
3878 case Mips::AT: return Mips::V0;
3879 case Mips::V0: return Mips::V1;
3880 case Mips::V1: return Mips::A0;
3881 case Mips::A0: return Mips::A1;
3882 case Mips::A1: return Mips::A2;
3883 case Mips::A2: return Mips::A3;
3884 case Mips::A3: return Mips::T0;
3885 case Mips::T0: return Mips::T1;
3886 case Mips::T1: return Mips::T2;
3887 case Mips::T2: return Mips::T3;
3888 case Mips::T3: return Mips::T4;
3889 case Mips::T4: return Mips::T5;
3890 case Mips::T5: return Mips::T6;
3891 case Mips::T6: return Mips::T7;
3892 case Mips::T7: return Mips::S0;
3893 case Mips::S0: return Mips::S1;
3894 case Mips::S1: return Mips::S2;
3895 case Mips::S2: return Mips::S3;
3896 case Mips::S3: return Mips::S4;
3897 case Mips::S4: return Mips::S5;
3898 case Mips::S5: return Mips::S6;
3899 case Mips::S6: return Mips::S7;
3900 case Mips::S7: return Mips::T8;
3901 case Mips::T8: return Mips::T9;
3902 case Mips::T9: return Mips::K0;
3903 case Mips::K0: return Mips::K1;
3904 case Mips::K1: return Mips::GP;
3905 case Mips::GP: return Mips::SP;
3906 case Mips::SP: return Mips::FP;
3907 case Mips::FP: return Mips::RA;
3908 case Mips::RA: return Mips::ZERO;
3914 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
3915 // lw $<reg+1>>, offset+4($reg2)'
3916 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
3917 // sw $<reg+1>>, offset+4($reg2)'
3919 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
3921 const MCSubtargetInfo *STI,
3926 warnIfNoMacro(IDLoc);
3928 MipsTargetStreamer &TOut = getTargetStreamer();
3929 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
3930 unsigned FirstReg = Inst.getOperand(0).getReg();
3931 unsigned SecondReg = nextReg(FirstReg);
3932 unsigned BaseReg = Inst.getOperand(1).getReg();
3936 warnIfRegIndexIsAT(FirstReg, IDLoc);
3938 assert(Inst.getOperand(2).isImm() &&
3939 "Offset for load macro is not immediate!");
3941 MCOperand &FirstOffset = Inst.getOperand(2);
3942 signed NextOffset = FirstOffset.getImm() + 4;
3943 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
3945 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
3948 // For loads, clobber the base register with the second load instead of the
3949 // first if the BaseReg == FirstReg.
3950 if (FirstReg != BaseReg || !IsLoad) {
3951 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3952 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3954 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3955 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3961 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3962 const MCSubtargetInfo *STI) {
3964 warnIfNoMacro(IDLoc);
3965 MipsTargetStreamer &TOut = getTargetStreamer();
3967 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
3968 Inst.getOperand(2).getReg() != Mips::ZERO) {
3969 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
3970 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
3972 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
3973 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
3978 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
3979 Reg = Inst.getOperand(2).getReg();
3981 Reg = Inst.getOperand(1).getReg();
3983 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
3987 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3988 const MCSubtargetInfo *STI) {
3990 warnIfNoMacro(IDLoc);
3991 MipsTargetStreamer &TOut = getTargetStreamer();
3994 int64_t Imm = Inst.getOperand(2).getImm();
3995 unsigned Reg = Inst.getOperand(1).getReg();
3998 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
3999 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4003 if (Reg == Mips::ZERO) {
4004 Warning(IDLoc, "comparison is always false");
4005 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4006 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4010 if (Imm > -0x8000 && Imm < 0) {
4012 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4017 if (!isUInt<16>(Imm)) {
4018 unsigned ATReg = getATReg(IDLoc);
4022 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4026 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4027 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4028 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4029 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4033 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4035 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4036 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4041 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
4042 const OperandVector &Operands) {
4043 switch (Inst.getOpcode()) {
4045 return Match_Success;
4048 case Mips::DATI_MM64R6:
4049 case Mips::DAHI_MM64R6:
4050 if (static_cast<MipsOperand &>(*Operands[1])
4051 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4052 return Match_Success;
4053 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;
4135 return Match_Success;
4139 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
4140 uint64_t ErrorInfo) {
4141 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
4142 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4143 if (ErrorLoc == SMLoc())
4150 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4151 OperandVector &Operands,
4153 uint64_t &ErrorInfo,
4154 bool MatchingInlineAsm) {
4157 unsigned MatchResult =
4158 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
4160 switch (MatchResult) {
4161 case Match_Success: {
4162 if (processInstruction(Inst, IDLoc, Out, STI))
4166 case Match_MissingFeature:
4167 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4169 case Match_InvalidOperand: {
4170 SMLoc ErrorLoc = IDLoc;
4171 if (ErrorInfo != ~0ULL) {
4172 if (ErrorInfo >= Operands.size())
4173 return Error(IDLoc, "too few operands for instruction");
4175 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4176 if (ErrorLoc == SMLoc())
4180 return Error(ErrorLoc, "invalid operand for instruction");
4182 case Match_NonZeroOperandForSync:
4183 return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
4184 case Match_MnemonicFail:
4185 return Error(IDLoc, "invalid instruction");
4186 case Match_RequiresDifferentSrcAndDst:
4187 return Error(IDLoc, "source and destination must be different");
4188 case Match_RequiresDifferentOperands:
4189 return Error(IDLoc, "registers must be different");
4190 case Match_RequiresNoZeroRegister:
4191 return Error(IDLoc, "invalid operand ($zero) for instruction");
4192 case Match_RequiresSameSrcAndDst:
4193 return Error(IDLoc, "source and destination must match");
4195 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
4197 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4198 "expected 1-bit unsigned immediate");
4200 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4201 "expected 2-bit unsigned immediate");
4203 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4204 "expected immediate in range 1 .. 4");
4206 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4207 "expected 3-bit unsigned immediate");
4209 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4210 "expected 4-bit unsigned immediate");
4212 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4213 "expected 4-bit signed immediate");
4215 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4216 "expected 5-bit unsigned immediate");
4218 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4219 "expected 5-bit signed immediate");
4221 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4222 "expected immediate in range 1 .. 32");
4223 case Match_UImm5_32:
4224 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4225 "expected immediate in range 32 .. 63");
4226 case Match_UImm5_33:
4227 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4228 "expected immediate in range 33 .. 64");
4229 case Match_UImm5_0_Report_UImm6:
4230 // This is used on UImm5 operands that have a corresponding UImm5_32
4231 // operand to avoid confusing the user.
4232 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4233 "expected 6-bit unsigned immediate");
4234 case Match_UImm5_Lsl2:
4235 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4236 "expected both 7-bit unsigned immediate and multiple of 4");
4237 case Match_UImmRange2_64:
4238 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4239 "expected immediate in range 2 .. 64");
4241 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4242 "expected 6-bit unsigned immediate");
4243 case Match_UImm6_Lsl2:
4244 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4245 "expected both 8-bit unsigned immediate and multiple of 4");
4247 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4248 "expected 6-bit signed immediate");
4250 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4251 "expected 7-bit unsigned immediate");
4252 case Match_UImm7_N1:
4253 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4254 "expected immediate in range -1 .. 126");
4255 case Match_SImm7_Lsl2:
4256 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4257 "expected both 9-bit signed immediate and multiple of 4");
4259 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4260 "expected 8-bit unsigned immediate");
4261 case Match_UImm10_0:
4262 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4263 "expected 10-bit unsigned immediate");
4264 case Match_SImm10_0:
4265 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4266 "expected 10-bit signed immediate");
4267 case Match_SImm11_0:
4268 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4269 "expected 11-bit signed immediate");
4271 case Match_UImm16_Relaxed:
4272 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4273 "expected 16-bit unsigned immediate");
4275 case Match_SImm16_Relaxed:
4276 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4277 "expected 16-bit signed immediate");
4278 case Match_SImm19_Lsl2:
4279 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4280 "expected both 19-bit signed immediate and multiple of 4");
4281 case Match_UImm20_0:
4282 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4283 "expected 20-bit unsigned immediate");
4284 case Match_UImm26_0:
4285 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4286 "expected 26-bit unsigned immediate");
4288 case Match_SImm32_Relaxed:
4289 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4290 "expected 32-bit signed immediate");
4291 case Match_UImm32_Coerced:
4292 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4293 "expected 32-bit immediate");
4294 case Match_MemSImm9:
4295 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4296 "expected memory with 9-bit signed offset");
4297 case Match_MemSImm10:
4298 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4299 "expected memory with 10-bit signed offset");
4300 case Match_MemSImm10Lsl1:
4301 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4302 "expected memory with 11-bit signed offset and multiple of 2");
4303 case Match_MemSImm10Lsl2:
4304 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4305 "expected memory with 12-bit signed offset and multiple of 4");
4306 case Match_MemSImm10Lsl3:
4307 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4308 "expected memory with 13-bit signed offset and multiple of 8");
4309 case Match_MemSImm11:
4310 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4311 "expected memory with 11-bit signed offset");
4312 case Match_MemSImm12:
4313 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4314 "expected memory with 12-bit signed offset");
4315 case Match_MemSImm16:
4316 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4317 "expected memory with 16-bit signed offset");
4320 llvm_unreachable("Implement any new match types added!");
4323 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
4324 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
4325 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
4326 ") without \".set noat\"");
4329 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
4330 if (!AssemblerOptions.back()->isMacro())
4331 Warning(Loc, "macro instruction expanded into multiple instructions");
4335 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
4336 SMRange Range, bool ShowColors) {
4337 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
4338 Range, SMFixIt(Range, FixMsg),
4342 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
4345 CC = StringSwitch<unsigned>(Name)
4381 if (!(isABI_N32() || isABI_N64()))
4384 if (12 <= CC && CC <= 15) {
4385 // Name is one of t4-t7
4386 AsmToken RegTok = getLexer().peekTok();
4387 SMRange RegRange = RegTok.getLocRange();
4389 StringRef FixedName = StringSwitch<StringRef>(Name)
4395 assert(FixedName != "" && "Register name is not one of t4-t7.");
4397 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
4398 "Did you mean $" + FixedName + "?", RegRange);
4401 // Although SGI documentation just cuts out t0-t3 for n32/n64,
4402 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
4403 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
4404 if (8 <= CC && CC <= 11)
4408 CC = StringSwitch<unsigned>(Name)
4420 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
4423 CC = StringSwitch<unsigned>(Name)
4424 .Case("hwr_cpunum", 0)
4425 .Case("hwr_synci_step", 1)
4427 .Case("hwr_ccres", 3)
4428 .Case("hwr_ulr", 29)
4434 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
4436 if (Name[0] == 'f') {
4437 StringRef NumString = Name.substr(1);
4439 if (NumString.getAsInteger(10, IntVal))
4440 return -1; // This is not an integer.
4441 if (IntVal > 31) // Maximum index for fpu register.
4448 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
4450 if (Name.startswith("fcc")) {
4451 StringRef NumString = Name.substr(3);
4453 if (NumString.getAsInteger(10, IntVal))
4454 return -1; // This is not an integer.
4455 if (IntVal > 7) // There are only 8 fcc registers.
4462 int MipsAsmParser::matchACRegisterName(StringRef Name) {
4464 if (Name.startswith("ac")) {
4465 StringRef NumString = Name.substr(2);
4467 if (NumString.getAsInteger(10, IntVal))
4468 return -1; // This is not an integer.
4469 if (IntVal > 3) // There are only 3 acc registers.
4476 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
4479 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
4488 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4491 CC = StringSwitch<unsigned>(Name)
4494 .Case("msaaccess", 2)
4496 .Case("msamodify", 4)
4497 .Case("msarequest", 5)
4499 .Case("msaunmap", 7)
4505 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
4506 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4508 reportParseError(Loc,
4509 "pseudo-instruction requires $at, which is not available");
4512 unsigned AT = getReg(
4513 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4517 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
4518 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4521 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
4522 MCAsmParser &Parser = getParser();
4523 DEBUG(dbgs() << "parseOperand\n");
4525 // Check if the current operand has a custom associated parser, if so, try to
4526 // custom parse the operand, or fallback to the general approach.
4527 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4528 if (ResTy == MatchOperand_Success)
4530 // If there wasn't a custom match, try the generic matcher below. Otherwise,
4531 // there was a match, but an error occurred, in which case, just return that
4532 // the operand parsing failed.
4533 if (ResTy == MatchOperand_ParseFail)
4536 DEBUG(dbgs() << ".. Generic Parser\n");
4538 switch (getLexer().getKind()) {
4539 case AsmToken::Dollar: {
4540 // Parse the register.
4541 SMLoc S = Parser.getTok().getLoc();
4543 // Almost all registers have been parsed by custom parsers. There is only
4544 // one exception to this. $zero (and it's alias $0) will reach this point
4545 // for div, divu, and similar instructions because it is not an operand
4546 // to the instruction definition but an explicit register. Special case
4547 // this situation for now.
4548 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
4551 // Maybe it is a symbol reference.
4552 StringRef Identifier;
4553 if (Parser.parseIdentifier(Identifier))
4556 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4557 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
4558 // Otherwise create a symbol reference.
4560 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
4562 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
4566 DEBUG(dbgs() << ".. generic integer expression\n");
4569 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
4570 if (getParser().parseExpression(Expr))
4573 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4575 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
4578 } // switch(getLexer().getKind())
4582 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4584 switch (Expr->getKind()) {
4585 case MCExpr::Constant:
4587 case MCExpr::SymbolRef:
4588 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4589 case MCExpr::Binary:
4590 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4591 if (!isEvaluated(BE->getLHS()))
4593 return isEvaluated(BE->getRHS());
4596 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4597 case MCExpr::Target:
4603 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4605 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4606 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4607 if (ResTy == MatchOperand_Success) {
4608 assert(Operands.size() == 1);
4609 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4610 StartLoc = Operand.getStartLoc();
4611 EndLoc = Operand.getEndLoc();
4613 // AFAIK, we only support numeric registers and named GPR's in CFI
4615 // Don't worry about eating tokens before failing. Using an unrecognised
4616 // register is a parse error.
4617 if (Operand.isGPRAsmReg()) {
4618 // Resolve to GPR32 or GPR64 appropriately.
4619 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4622 return (RegNo == (unsigned)-1);
4625 assert(Operands.size() == 0);
4626 return (RegNo == (unsigned)-1);
4629 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4633 return getParser().parseParenExprOfDepth(0, Res, S);
4634 return getParser().parseExpression(Res);
4637 OperandMatchResultTy
4638 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4639 MCAsmParser &Parser = getParser();
4640 DEBUG(dbgs() << "parseMemOperand\n");
4641 const MCExpr *IdVal = nullptr;
4643 bool isParenExpr = false;
4644 OperandMatchResultTy Res = MatchOperand_NoMatch;
4645 // First operand is the offset.
4646 S = Parser.getTok().getLoc();
4648 if (getLexer().getKind() == AsmToken::LParen) {
4653 if (getLexer().getKind() != AsmToken::Dollar) {
4654 if (parseMemOffset(IdVal, isParenExpr))
4655 return MatchOperand_ParseFail;
4657 const AsmToken &Tok = Parser.getTok(); // Get the next token.
4658 if (Tok.isNot(AsmToken::LParen)) {
4659 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4660 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4662 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4663 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4664 return MatchOperand_Success;
4666 if (Tok.is(AsmToken::EndOfStatement)) {
4668 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4670 // Zero register assumed, add a memory operand with ZERO as its base.
4671 // "Base" will be managed by k_Memory.
4672 auto Base = MipsOperand::createGPRReg(
4673 0, "0", getContext().getRegisterInfo(), S, E, *this);
4675 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4676 return MatchOperand_Success;
4678 MCBinaryExpr::Opcode Opcode;
4679 // GAS and LLVM treat comparison operators different. GAS will generate -1
4680 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
4681 // highly unlikely to be found in a memory offset expression, we don't
4683 switch (Tok.getKind()) {
4684 case AsmToken::Plus:
4685 Opcode = MCBinaryExpr::Add;
4688 case AsmToken::Minus:
4689 Opcode = MCBinaryExpr::Sub;
4692 case AsmToken::Star:
4693 Opcode = MCBinaryExpr::Mul;
4696 case AsmToken::Pipe:
4697 Opcode = MCBinaryExpr::Or;
4701 Opcode = MCBinaryExpr::And;
4704 case AsmToken::LessLess:
4705 Opcode = MCBinaryExpr::Shl;
4708 case AsmToken::GreaterGreater:
4709 Opcode = MCBinaryExpr::LShr;
4712 case AsmToken::Caret:
4713 Opcode = MCBinaryExpr::Xor;
4716 case AsmToken::Slash:
4717 Opcode = MCBinaryExpr::Div;
4720 case AsmToken::Percent:
4721 Opcode = MCBinaryExpr::Mod;
4725 Error(Parser.getTok().getLoc(), "'(' or expression expected");
4726 return MatchOperand_ParseFail;
4728 const MCExpr * NextExpr;
4729 if (getParser().parseExpression(NextExpr))
4730 return MatchOperand_ParseFail;
4731 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
4734 Parser.Lex(); // Eat the '(' token.
4737 Res = parseAnyRegister(Operands);
4738 if (Res != MatchOperand_Success)
4741 if (Parser.getTok().isNot(AsmToken::RParen)) {
4742 Error(Parser.getTok().getLoc(), "')' expected");
4743 return MatchOperand_ParseFail;
4746 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4748 Parser.Lex(); // Eat the ')' token.
4751 IdVal = MCConstantExpr::create(0, getContext());
4753 // Replace the register operand with the memory operand.
4754 std::unique_ptr<MipsOperand> op(
4755 static_cast<MipsOperand *>(Operands.back().release()));
4756 // Remove the register from the operands.
4757 // "op" will be managed by k_Memory.
4758 Operands.pop_back();
4759 // Add the memory operand.
4760 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4762 if (IdVal->evaluateAsAbsolute(Imm))
4763 IdVal = MCConstantExpr::create(Imm, getContext());
4764 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4765 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4769 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4770 return MatchOperand_Success;
4773 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4774 MCAsmParser &Parser = getParser();
4775 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4777 SMLoc S = Parser.getTok().getLoc();
4779 if (Sym->isVariable())
4780 Expr = Sym->getVariableValue();
4783 if (Expr->getKind() == MCExpr::SymbolRef) {
4784 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4785 StringRef DefSymbol = Ref->getSymbol().getName();
4786 if (DefSymbol.startswith("$")) {
4787 OperandMatchResultTy ResTy =
4788 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4789 if (ResTy == MatchOperand_Success) {
4792 } else if (ResTy == MatchOperand_ParseFail)
4793 llvm_unreachable("Should never ParseFail");
4801 OperandMatchResultTy
4802 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4803 StringRef Identifier,
4805 int Index = matchCPURegisterName(Identifier);
4807 Operands.push_back(MipsOperand::createGPRReg(
4808 Index, Identifier, getContext().getRegisterInfo(), S,
4809 getLexer().getLoc(), *this));
4810 return MatchOperand_Success;
4813 Index = matchHWRegsRegisterName(Identifier);
4815 Operands.push_back(MipsOperand::createHWRegsReg(
4816 Index, Identifier, getContext().getRegisterInfo(), S,
4817 getLexer().getLoc(), *this));
4818 return MatchOperand_Success;
4821 Index = matchFPURegisterName(Identifier);
4823 Operands.push_back(MipsOperand::createFGRReg(
4824 Index, Identifier, getContext().getRegisterInfo(), S,
4825 getLexer().getLoc(), *this));
4826 return MatchOperand_Success;
4829 Index = matchFCCRegisterName(Identifier);
4831 Operands.push_back(MipsOperand::createFCCReg(
4832 Index, Identifier, getContext().getRegisterInfo(), S,
4833 getLexer().getLoc(), *this));
4834 return MatchOperand_Success;
4837 Index = matchACRegisterName(Identifier);
4839 Operands.push_back(MipsOperand::createACCReg(
4840 Index, Identifier, getContext().getRegisterInfo(), S,
4841 getLexer().getLoc(), *this));
4842 return MatchOperand_Success;
4845 Index = matchMSA128RegisterName(Identifier);
4847 Operands.push_back(MipsOperand::createMSA128Reg(
4848 Index, Identifier, getContext().getRegisterInfo(), S,
4849 getLexer().getLoc(), *this));
4850 return MatchOperand_Success;
4853 Index = matchMSA128CtrlRegisterName(Identifier);
4855 Operands.push_back(MipsOperand::createMSACtrlReg(
4856 Index, Identifier, getContext().getRegisterInfo(), S,
4857 getLexer().getLoc(), *this));
4858 return MatchOperand_Success;
4861 return MatchOperand_NoMatch;
4864 OperandMatchResultTy
4865 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4866 MCAsmParser &Parser = getParser();
4867 auto Token = Parser.getLexer().peekTok(false);
4869 if (Token.is(AsmToken::Identifier)) {
4870 DEBUG(dbgs() << ".. identifier\n");
4871 StringRef Identifier = Token.getIdentifier();
4872 OperandMatchResultTy ResTy =
4873 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4875 } else if (Token.is(AsmToken::Integer)) {
4876 DEBUG(dbgs() << ".. integer\n");
4877 Operands.push_back(MipsOperand::createNumericReg(
4878 Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
4879 Token.getLoc(), *this));
4880 return MatchOperand_Success;
4883 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4885 return MatchOperand_NoMatch;
4888 OperandMatchResultTy
4889 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4890 MCAsmParser &Parser = getParser();
4891 DEBUG(dbgs() << "parseAnyRegister\n");
4893 auto Token = Parser.getTok();
4895 SMLoc S = Token.getLoc();
4897 if (Token.isNot(AsmToken::Dollar)) {
4898 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4899 if (Token.is(AsmToken::Identifier)) {
4900 if (searchSymbolAlias(Operands))
4901 return MatchOperand_Success;
4903 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4904 return MatchOperand_NoMatch;
4906 DEBUG(dbgs() << ".. $\n");
4908 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4909 if (ResTy == MatchOperand_Success) {
4911 Parser.Lex(); // identifier
4916 OperandMatchResultTy
4917 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4918 MCAsmParser &Parser = getParser();
4919 DEBUG(dbgs() << "parseJumpTarget\n");
4921 SMLoc S = getLexer().getLoc();
4923 // Registers are a valid target and have priority over symbols.
4924 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4925 if (ResTy != MatchOperand_NoMatch)
4928 // Integers and expressions are acceptable
4929 const MCExpr *Expr = nullptr;
4930 if (Parser.parseExpression(Expr)) {
4931 // We have no way of knowing if a symbol was consumed so we must ParseFail
4932 return MatchOperand_ParseFail;
4935 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4936 return MatchOperand_Success;
4939 OperandMatchResultTy
4940 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4941 MCAsmParser &Parser = getParser();
4942 const MCExpr *IdVal;
4943 // If the first token is '$' we may have register operand.
4944 if (Parser.getTok().is(AsmToken::Dollar))
4945 return MatchOperand_NoMatch;
4946 SMLoc S = Parser.getTok().getLoc();
4947 if (getParser().parseExpression(IdVal))
4948 return MatchOperand_ParseFail;
4949 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4950 assert(MCE && "Unexpected MCExpr type.");
4951 int64_t Val = MCE->getValue();
4952 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4953 Operands.push_back(MipsOperand::CreateImm(
4954 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4955 return MatchOperand_Success;
4958 OperandMatchResultTy
4959 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4960 MCAsmParser &Parser = getParser();
4961 SmallVector<unsigned, 10> Regs;
4963 unsigned PrevReg = Mips::NoRegister;
4964 bool RegRange = false;
4965 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4967 if (Parser.getTok().isNot(AsmToken::Dollar))
4968 return MatchOperand_ParseFail;
4970 SMLoc S = Parser.getTok().getLoc();
4971 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4972 SMLoc E = getLexer().getLoc();
4973 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4974 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4976 // Remove last register operand because registers from register range
4977 // should be inserted first.
4978 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4979 (!isGP64bit() && RegNo == Mips::RA)) {
4980 Regs.push_back(RegNo);
4982 unsigned TmpReg = PrevReg + 1;
4983 while (TmpReg <= RegNo) {
4984 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4985 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4987 Error(E, "invalid register operand");
4988 return MatchOperand_ParseFail;
4992 Regs.push_back(TmpReg++);
4998 if ((PrevReg == Mips::NoRegister) &&
4999 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5000 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5001 Error(E, "$16 or $31 expected");
5002 return MatchOperand_ParseFail;
5003 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5004 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5006 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5007 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5009 Error(E, "invalid register operand");
5010 return MatchOperand_ParseFail;
5011 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5012 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5013 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5015 Error(E, "consecutive register numbers expected");
5016 return MatchOperand_ParseFail;
5019 Regs.push_back(RegNo);
5022 if (Parser.getTok().is(AsmToken::Minus))
5025 if (!Parser.getTok().isNot(AsmToken::Minus) &&
5026 !Parser.getTok().isNot(AsmToken::Comma)) {
5027 Error(E, "',' or '-' expected");
5028 return MatchOperand_ParseFail;
5031 Lex(); // Consume comma or minus
5032 if (Parser.getTok().isNot(AsmToken::Dollar))
5038 SMLoc E = Parser.getTok().getLoc();
5039 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5040 parseMemOperand(Operands);
5041 return MatchOperand_Success;
5044 OperandMatchResultTy
5045 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
5046 MCAsmParser &Parser = getParser();
5048 SMLoc S = Parser.getTok().getLoc();
5049 if (parseAnyRegister(Operands) != MatchOperand_Success)
5050 return MatchOperand_ParseFail;
5052 SMLoc E = Parser.getTok().getLoc();
5053 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
5055 Operands.pop_back();
5056 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
5057 return MatchOperand_Success;
5060 OperandMatchResultTy
5061 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
5062 MCAsmParser &Parser = getParser();
5063 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
5064 SmallVector<unsigned, 10> Regs;
5066 if (Parser.getTok().isNot(AsmToken::Dollar))
5067 return MatchOperand_ParseFail;
5069 SMLoc S = Parser.getTok().getLoc();
5071 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5072 return MatchOperand_ParseFail;
5074 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5075 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5076 Regs.push_back(RegNo);
5078 SMLoc E = Parser.getTok().getLoc();
5079 if (Parser.getTok().isNot(AsmToken::Comma)) {
5080 Error(E, "',' expected");
5081 return MatchOperand_ParseFail;
5087 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5088 return MatchOperand_ParseFail;
5090 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5091 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5092 Regs.push_back(RegNo);
5094 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5096 return MatchOperand_Success;
5099 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
5101 /// ::= '(', register, ')'
5102 /// handle it before we iterate so we don't get tripped up by the lack of
5104 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
5105 MCAsmParser &Parser = getParser();
5106 if (getLexer().is(AsmToken::LParen)) {
5108 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
5110 if (parseOperand(Operands, Name)) {
5111 SMLoc Loc = getLexer().getLoc();
5112 return Error(Loc, "unexpected token in argument list");
5114 if (Parser.getTok().isNot(AsmToken::RParen)) {
5115 SMLoc Loc = getLexer().getLoc();
5116 return Error(Loc, "unexpected token, expected ')'");
5119 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
5125 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
5126 /// either one of these.
5127 /// ::= '[', register, ']'
5128 /// ::= '[', integer, ']'
5129 /// handle it before we iterate so we don't get tripped up by the lack of
5131 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
5132 OperandVector &Operands) {
5133 MCAsmParser &Parser = getParser();
5134 if (getLexer().is(AsmToken::LBrac)) {
5136 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
5138 if (parseOperand(Operands, Name)) {
5139 SMLoc Loc = getLexer().getLoc();
5140 return Error(Loc, "unexpected token in argument list");
5142 if (Parser.getTok().isNot(AsmToken::RBrac)) {
5143 SMLoc Loc = getLexer().getLoc();
5144 return Error(Loc, "unexpected token, expected ']'");
5147 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
5153 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
5154 SMLoc NameLoc, OperandVector &Operands) {
5155 MCAsmParser &Parser = getParser();
5156 DEBUG(dbgs() << "ParseInstruction\n");
5158 // We have reached first instruction, module directive are now forbidden.
5159 getTargetStreamer().forbidModuleDirective();
5161 // Check if we have valid mnemonic
5162 if (!mnemonicIsValid(Name, 0)) {
5163 return Error(NameLoc, "unknown instruction");
5165 // First operand in MCInst is instruction mnemonic.
5166 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
5168 // Read the remaining operands.
5169 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5170 // Read the first operand.
5171 if (parseOperand(Operands, Name)) {
5172 SMLoc Loc = getLexer().getLoc();
5173 return Error(Loc, "unexpected token in argument list");
5175 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
5177 // AFAIK, parenthesis suffixes are never on the first operand
5179 while (getLexer().is(AsmToken::Comma)) {
5180 Parser.Lex(); // Eat the comma.
5181 // Parse and remember the operand.
5182 if (parseOperand(Operands, Name)) {
5183 SMLoc Loc = getLexer().getLoc();
5184 return Error(Loc, "unexpected token in argument list");
5186 // Parse bracket and parenthesis suffixes before we iterate
5187 if (getLexer().is(AsmToken::LBrac)) {
5188 if (parseBracketSuffix(Name, Operands))
5190 } else if (getLexer().is(AsmToken::LParen) &&
5191 parseParenSuffix(Name, Operands))
5195 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5196 SMLoc Loc = getLexer().getLoc();
5197 return Error(Loc, "unexpected token in argument list");
5199 Parser.Lex(); // Consume the EndOfStatement.
5203 // FIXME: Given that these have the same name, these should both be
5204 // consistent on affecting the Parser.
5205 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
5206 SMLoc Loc = getLexer().getLoc();
5207 return Error(Loc, ErrorMsg);
5210 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
5211 return Error(Loc, ErrorMsg);
5214 bool MipsAsmParser::parseSetNoAtDirective() {
5215 MCAsmParser &Parser = getParser();
5216 // Line should look like: ".set noat".
5218 // Set the $at register to $0.
5219 AssemblerOptions.back()->setATRegIndex(0);
5221 Parser.Lex(); // Eat "noat".
5223 // If this is not the end of the statement, report an error.
5224 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5225 reportParseError("unexpected token, expected end of statement");
5229 getTargetStreamer().emitDirectiveSetNoAt();
5230 Parser.Lex(); // Consume the EndOfStatement.
5234 bool MipsAsmParser::parseSetAtDirective() {
5235 // Line can be: ".set at", which sets $at to $1
5236 // or ".set at=$reg", which sets $at to $reg.
5237 MCAsmParser &Parser = getParser();
5238 Parser.Lex(); // Eat "at".
5240 if (getLexer().is(AsmToken::EndOfStatement)) {
5241 // No register was specified, so we set $at to $1.
5242 AssemblerOptions.back()->setATRegIndex(1);
5244 getTargetStreamer().emitDirectiveSetAt();
5245 Parser.Lex(); // Consume the EndOfStatement.
5249 if (getLexer().isNot(AsmToken::Equal)) {
5250 reportParseError("unexpected token, expected equals sign");
5253 Parser.Lex(); // Eat "=".
5255 if (getLexer().isNot(AsmToken::Dollar)) {
5256 if (getLexer().is(AsmToken::EndOfStatement)) {
5257 reportParseError("no register specified");
5260 reportParseError("unexpected token, expected dollar sign '$'");
5264 Parser.Lex(); // Eat "$".
5266 // Find out what "reg" is.
5268 const AsmToken &Reg = Parser.getTok();
5269 if (Reg.is(AsmToken::Identifier)) {
5270 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
5271 } else if (Reg.is(AsmToken::Integer)) {
5272 AtRegNo = Reg.getIntVal();
5274 reportParseError("unexpected token, expected identifier or integer");
5278 // Check if $reg is a valid register. If it is, set $at to $reg.
5279 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
5280 reportParseError("invalid register");
5283 Parser.Lex(); // Eat "reg".
5285 // If this is not the end of the statement, report an error.
5286 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5287 reportParseError("unexpected token, expected end of statement");
5291 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
5293 Parser.Lex(); // Consume the EndOfStatement.
5297 bool MipsAsmParser::parseSetReorderDirective() {
5298 MCAsmParser &Parser = getParser();
5300 // If this is not the end of the statement, report an error.
5301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5302 reportParseError("unexpected token, expected end of statement");
5305 AssemblerOptions.back()->setReorder();
5306 getTargetStreamer().emitDirectiveSetReorder();
5307 Parser.Lex(); // Consume the EndOfStatement.
5311 bool MipsAsmParser::parseSetNoReorderDirective() {
5312 MCAsmParser &Parser = getParser();
5314 // If this is not the end of the statement, report an error.
5315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5316 reportParseError("unexpected token, expected end of statement");
5319 AssemblerOptions.back()->setNoReorder();
5320 getTargetStreamer().emitDirectiveSetNoReorder();
5321 Parser.Lex(); // Consume the EndOfStatement.
5325 bool MipsAsmParser::parseSetMacroDirective() {
5326 MCAsmParser &Parser = getParser();
5328 // If this is not the end of the statement, report an error.
5329 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5330 reportParseError("unexpected token, expected end of statement");
5333 AssemblerOptions.back()->setMacro();
5334 getTargetStreamer().emitDirectiveSetMacro();
5335 Parser.Lex(); // Consume the EndOfStatement.
5339 bool MipsAsmParser::parseSetNoMacroDirective() {
5340 MCAsmParser &Parser = getParser();
5342 // If this is not the end of the statement, report an error.
5343 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5344 reportParseError("unexpected token, expected end of statement");
5347 if (AssemblerOptions.back()->isReorder()) {
5348 reportParseError("`noreorder' must be set before `nomacro'");
5351 AssemblerOptions.back()->setNoMacro();
5352 getTargetStreamer().emitDirectiveSetNoMacro();
5353 Parser.Lex(); // Consume the EndOfStatement.
5357 bool MipsAsmParser::parseSetMsaDirective() {
5358 MCAsmParser &Parser = getParser();
5361 // If this is not the end of the statement, report an error.
5362 if (getLexer().isNot(AsmToken::EndOfStatement))
5363 return reportParseError("unexpected token, expected end of statement");
5365 setFeatureBits(Mips::FeatureMSA, "msa");
5366 getTargetStreamer().emitDirectiveSetMsa();
5370 bool MipsAsmParser::parseSetNoMsaDirective() {
5371 MCAsmParser &Parser = getParser();
5374 // If this is not the end of the statement, report an error.
5375 if (getLexer().isNot(AsmToken::EndOfStatement))
5376 return reportParseError("unexpected token, expected end of statement");
5378 clearFeatureBits(Mips::FeatureMSA, "msa");
5379 getTargetStreamer().emitDirectiveSetNoMsa();
5383 bool MipsAsmParser::parseSetNoDspDirective() {
5384 MCAsmParser &Parser = getParser();
5385 Parser.Lex(); // Eat "nodsp".
5387 // If this is not the end of the statement, report an error.
5388 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5389 reportParseError("unexpected token, expected end of statement");
5393 clearFeatureBits(Mips::FeatureDSP, "dsp");
5394 getTargetStreamer().emitDirectiveSetNoDsp();
5398 bool MipsAsmParser::parseSetMips16Directive() {
5399 MCAsmParser &Parser = getParser();
5400 Parser.Lex(); // Eat "mips16".
5402 // If this is not the end of the statement, report an error.
5403 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5404 reportParseError("unexpected token, expected end of statement");
5408 setFeatureBits(Mips::FeatureMips16, "mips16");
5409 getTargetStreamer().emitDirectiveSetMips16();
5410 Parser.Lex(); // Consume the EndOfStatement.
5414 bool MipsAsmParser::parseSetNoMips16Directive() {
5415 MCAsmParser &Parser = getParser();
5416 Parser.Lex(); // Eat "nomips16".
5418 // If this is not the end of the statement, report an error.
5419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5420 reportParseError("unexpected token, expected end of statement");
5424 clearFeatureBits(Mips::FeatureMips16, "mips16");
5425 getTargetStreamer().emitDirectiveSetNoMips16();
5426 Parser.Lex(); // Consume the EndOfStatement.
5430 bool MipsAsmParser::parseSetFpDirective() {
5431 MCAsmParser &Parser = getParser();
5432 MipsABIFlagsSection::FpABIKind FpAbiVal;
5433 // Line can be: .set fp=32
5436 Parser.Lex(); // Eat fp token
5437 AsmToken Tok = Parser.getTok();
5438 if (Tok.isNot(AsmToken::Equal)) {
5439 reportParseError("unexpected token, expected equals sign '='");
5442 Parser.Lex(); // Eat '=' token.
5443 Tok = Parser.getTok();
5445 if (!parseFpABIValue(FpAbiVal, ".set"))
5448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5449 reportParseError("unexpected token, expected end of statement");
5452 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5453 Parser.Lex(); // Consume the EndOfStatement.
5457 bool MipsAsmParser::parseSetOddSPRegDirective() {
5458 MCAsmParser &Parser = getParser();
5460 Parser.Lex(); // Eat "oddspreg".
5461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5462 reportParseError("unexpected token, expected end of statement");
5466 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5467 getTargetStreamer().emitDirectiveSetOddSPReg();
5471 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5472 MCAsmParser &Parser = getParser();
5474 Parser.Lex(); // Eat "nooddspreg".
5475 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5476 reportParseError("unexpected token, expected end of statement");
5480 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5481 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5485 bool MipsAsmParser::parseSetPopDirective() {
5486 MCAsmParser &Parser = getParser();
5487 SMLoc Loc = getLexer().getLoc();
5490 if (getLexer().isNot(AsmToken::EndOfStatement))
5491 return reportParseError("unexpected token, expected end of statement");
5493 // Always keep an element on the options "stack" to prevent the user
5494 // from changing the initial options. This is how we remember them.
5495 if (AssemblerOptions.size() == 2)
5496 return reportParseError(Loc, ".set pop with no .set push");
5498 MCSubtargetInfo &STI = copySTI();
5499 AssemblerOptions.pop_back();
5500 setAvailableFeatures(
5501 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5502 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5504 getTargetStreamer().emitDirectiveSetPop();
5508 bool MipsAsmParser::parseSetPushDirective() {
5509 MCAsmParser &Parser = getParser();
5511 if (getLexer().isNot(AsmToken::EndOfStatement))
5512 return reportParseError("unexpected token, expected end of statement");
5514 // Create a copy of the current assembler options environment and push it.
5515 AssemblerOptions.push_back(
5516 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5518 getTargetStreamer().emitDirectiveSetPush();
5522 bool MipsAsmParser::parseSetSoftFloatDirective() {
5523 MCAsmParser &Parser = getParser();
5525 if (getLexer().isNot(AsmToken::EndOfStatement))
5526 return reportParseError("unexpected token, expected end of statement");
5528 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5529 getTargetStreamer().emitDirectiveSetSoftFloat();
5533 bool MipsAsmParser::parseSetHardFloatDirective() {
5534 MCAsmParser &Parser = getParser();
5536 if (getLexer().isNot(AsmToken::EndOfStatement))
5537 return reportParseError("unexpected token, expected end of statement");
5539 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5540 getTargetStreamer().emitDirectiveSetHardFloat();
5544 bool MipsAsmParser::parseSetAssignment() {
5546 const MCExpr *Value;
5547 MCAsmParser &Parser = getParser();
5549 if (Parser.parseIdentifier(Name))
5550 reportParseError("expected identifier after .set");
5552 if (getLexer().isNot(AsmToken::Comma))
5553 return reportParseError("unexpected token, expected comma");
5556 if (Parser.parseExpression(Value))
5557 return reportParseError("expected valid expression after comma");
5559 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5560 Sym->setVariableValue(Value);
5565 bool MipsAsmParser::parseSetMips0Directive() {
5566 MCAsmParser &Parser = getParser();
5568 if (getLexer().isNot(AsmToken::EndOfStatement))
5569 return reportParseError("unexpected token, expected end of statement");
5571 // Reset assembler options to their initial values.
5572 MCSubtargetInfo &STI = copySTI();
5573 setAvailableFeatures(
5574 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5575 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5576 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5578 getTargetStreamer().emitDirectiveSetMips0();
5582 bool MipsAsmParser::parseSetArchDirective() {
5583 MCAsmParser &Parser = getParser();
5585 if (getLexer().isNot(AsmToken::Equal))
5586 return reportParseError("unexpected token, expected equals sign");
5590 if (Parser.parseIdentifier(Arch))
5591 return reportParseError("expected arch identifier");
5593 StringRef ArchFeatureName =
5594 StringSwitch<StringRef>(Arch)
5595 .Case("mips1", "mips1")
5596 .Case("mips2", "mips2")
5597 .Case("mips3", "mips3")
5598 .Case("mips4", "mips4")
5599 .Case("mips5", "mips5")
5600 .Case("mips32", "mips32")
5601 .Case("mips32r2", "mips32r2")
5602 .Case("mips32r3", "mips32r3")
5603 .Case("mips32r5", "mips32r5")
5604 .Case("mips32r6", "mips32r6")
5605 .Case("mips64", "mips64")
5606 .Case("mips64r2", "mips64r2")
5607 .Case("mips64r3", "mips64r3")
5608 .Case("mips64r5", "mips64r5")
5609 .Case("mips64r6", "mips64r6")
5610 .Case("octeon", "cnmips")
5611 .Case("r4000", "mips3") // This is an implementation of Mips3.
5614 if (ArchFeatureName.empty())
5615 return reportParseError("unsupported architecture");
5617 selectArch(ArchFeatureName);
5618 getTargetStreamer().emitDirectiveSetArch(Arch);
5622 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5623 MCAsmParser &Parser = getParser();
5625 if (getLexer().isNot(AsmToken::EndOfStatement))
5626 return reportParseError("unexpected token, expected end of statement");
5630 llvm_unreachable("Unimplemented feature");
5631 case Mips::FeatureDSP:
5632 setFeatureBits(Mips::FeatureDSP, "dsp");
5633 getTargetStreamer().emitDirectiveSetDsp();
5635 case Mips::FeatureMicroMips:
5636 setFeatureBits(Mips::FeatureMicroMips, "micromips");
5637 getTargetStreamer().emitDirectiveSetMicroMips();
5639 case Mips::FeatureMips1:
5640 selectArch("mips1");
5641 getTargetStreamer().emitDirectiveSetMips1();
5643 case Mips::FeatureMips2:
5644 selectArch("mips2");
5645 getTargetStreamer().emitDirectiveSetMips2();
5647 case Mips::FeatureMips3:
5648 selectArch("mips3");
5649 getTargetStreamer().emitDirectiveSetMips3();
5651 case Mips::FeatureMips4:
5652 selectArch("mips4");
5653 getTargetStreamer().emitDirectiveSetMips4();
5655 case Mips::FeatureMips5:
5656 selectArch("mips5");
5657 getTargetStreamer().emitDirectiveSetMips5();
5659 case Mips::FeatureMips32:
5660 selectArch("mips32");
5661 getTargetStreamer().emitDirectiveSetMips32();
5663 case Mips::FeatureMips32r2:
5664 selectArch("mips32r2");
5665 getTargetStreamer().emitDirectiveSetMips32R2();
5667 case Mips::FeatureMips32r3:
5668 selectArch("mips32r3");
5669 getTargetStreamer().emitDirectiveSetMips32R3();
5671 case Mips::FeatureMips32r5:
5672 selectArch("mips32r5");
5673 getTargetStreamer().emitDirectiveSetMips32R5();
5675 case Mips::FeatureMips32r6:
5676 selectArch("mips32r6");
5677 getTargetStreamer().emitDirectiveSetMips32R6();
5679 case Mips::FeatureMips64:
5680 selectArch("mips64");
5681 getTargetStreamer().emitDirectiveSetMips64();
5683 case Mips::FeatureMips64r2:
5684 selectArch("mips64r2");
5685 getTargetStreamer().emitDirectiveSetMips64R2();
5687 case Mips::FeatureMips64r3:
5688 selectArch("mips64r3");
5689 getTargetStreamer().emitDirectiveSetMips64R3();
5691 case Mips::FeatureMips64r5:
5692 selectArch("mips64r5");
5693 getTargetStreamer().emitDirectiveSetMips64R5();
5695 case Mips::FeatureMips64r6:
5696 selectArch("mips64r6");
5697 getTargetStreamer().emitDirectiveSetMips64R6();
5703 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5704 MCAsmParser &Parser = getParser();
5705 if (getLexer().isNot(AsmToken::Comma)) {
5706 SMLoc Loc = getLexer().getLoc();
5707 return Error(Loc, ErrorStr);
5710 Parser.Lex(); // Eat the comma.
5714 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5715 // In this class, it is only used for .cprestore.
5716 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5717 // MipsTargetELFStreamer and MipsAsmParser.
5718 bool MipsAsmParser::isPicAndNotNxxAbi() {
5719 return inPicMode() && !(isABI_N32() || isABI_N64());
5722 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5723 if (AssemblerOptions.back()->isReorder())
5724 Warning(Loc, ".cpload should be inside a noreorder section");
5726 if (inMips16Mode()) {
5727 reportParseError(".cpload is not supported in Mips16 mode");
5731 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5732 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5733 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5734 reportParseError("expected register containing function address");
5738 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5739 if (!RegOpnd.isGPRAsmReg()) {
5740 reportParseError(RegOpnd.getStartLoc(), "invalid register");
5744 // If this is not the end of the statement, report an error.
5745 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5746 reportParseError("unexpected token, expected end of statement");
5750 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5754 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5755 MCAsmParser &Parser = getParser();
5757 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5758 // is used in non-PIC mode.
5760 if (inMips16Mode()) {
5761 reportParseError(".cprestore is not supported in Mips16 mode");
5765 // Get the stack offset value.
5766 const MCExpr *StackOffset;
5767 int64_t StackOffsetVal;
5768 if (Parser.parseExpression(StackOffset)) {
5769 reportParseError("expected stack offset value");
5773 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5774 reportParseError("stack offset is not an absolute expression");
5778 if (StackOffsetVal < 0) {
5779 Warning(Loc, ".cprestore with negative stack offset has no effect");
5780 IsCpRestoreSet = false;
5782 IsCpRestoreSet = true;
5783 CpRestoreOffset = StackOffsetVal;
5786 // If this is not the end of the statement, report an error.
5787 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5788 reportParseError("unexpected token, expected end of statement");
5792 if (!getTargetStreamer().emitDirectiveCpRestore(
5793 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
5795 Parser.Lex(); // Consume the EndOfStatement.
5799 bool MipsAsmParser::parseDirectiveCPSetup() {
5800 MCAsmParser &Parser = getParser();
5803 bool SaveIsReg = true;
5805 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5806 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5807 if (ResTy == MatchOperand_NoMatch) {
5808 reportParseError("expected register containing function address");
5812 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5813 if (!FuncRegOpnd.isGPRAsmReg()) {
5814 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5818 FuncReg = FuncRegOpnd.getGPR32Reg();
5821 if (!eatComma("unexpected token, expected comma"))
5824 ResTy = parseAnyRegister(TmpReg);
5825 if (ResTy == MatchOperand_NoMatch) {
5826 const MCExpr *OffsetExpr;
5828 SMLoc ExprLoc = getLexer().getLoc();
5830 if (Parser.parseExpression(OffsetExpr) ||
5831 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5832 reportParseError(ExprLoc, "expected save register or stack offset");
5839 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5840 if (!SaveOpnd.isGPRAsmReg()) {
5841 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5844 Save = SaveOpnd.getGPR32Reg();
5847 if (!eatComma("unexpected token, expected comma"))
5851 if (Parser.parseExpression(Expr)) {
5852 reportParseError("expected expression");
5856 if (Expr->getKind() != MCExpr::SymbolRef) {
5857 reportParseError("expected symbol");
5860 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5862 CpSaveLocation = Save;
5863 CpSaveLocationIsRegister = SaveIsReg;
5865 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5870 bool MipsAsmParser::parseDirectiveCPReturn() {
5871 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5872 CpSaveLocationIsRegister);
5876 bool MipsAsmParser::parseDirectiveNaN() {
5877 MCAsmParser &Parser = getParser();
5878 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5879 const AsmToken &Tok = Parser.getTok();
5881 if (Tok.getString() == "2008") {
5883 getTargetStreamer().emitDirectiveNaN2008();
5885 } else if (Tok.getString() == "legacy") {
5887 getTargetStreamer().emitDirectiveNaNLegacy();
5891 // If we don't recognize the option passed to the .nan
5892 // directive (e.g. no option or unknown option), emit an error.
5893 reportParseError("invalid option in .nan directive");
5897 bool MipsAsmParser::parseDirectiveSet() {
5898 MCAsmParser &Parser = getParser();
5899 // Get the next token.
5900 const AsmToken &Tok = Parser.getTok();
5902 if (Tok.getString() == "noat") {
5903 return parseSetNoAtDirective();
5904 } else if (Tok.getString() == "at") {
5905 return parseSetAtDirective();
5906 } else if (Tok.getString() == "arch") {
5907 return parseSetArchDirective();
5908 } else if (Tok.getString() == "fp") {
5909 return parseSetFpDirective();
5910 } else if (Tok.getString() == "oddspreg") {
5911 return parseSetOddSPRegDirective();
5912 } else if (Tok.getString() == "nooddspreg") {
5913 return parseSetNoOddSPRegDirective();
5914 } else if (Tok.getString() == "pop") {
5915 return parseSetPopDirective();
5916 } else if (Tok.getString() == "push") {
5917 return parseSetPushDirective();
5918 } else if (Tok.getString() == "reorder") {
5919 return parseSetReorderDirective();
5920 } else if (Tok.getString() == "noreorder") {
5921 return parseSetNoReorderDirective();
5922 } else if (Tok.getString() == "macro") {
5923 return parseSetMacroDirective();
5924 } else if (Tok.getString() == "nomacro") {
5925 return parseSetNoMacroDirective();
5926 } else if (Tok.getString() == "mips16") {
5927 return parseSetMips16Directive();
5928 } else if (Tok.getString() == "nomips16") {
5929 return parseSetNoMips16Directive();
5930 } else if (Tok.getString() == "nomicromips") {
5931 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
5932 getTargetStreamer().emitDirectiveSetNoMicroMips();
5933 Parser.eatToEndOfStatement();
5935 } else if (Tok.getString() == "micromips") {
5936 return parseSetFeature(Mips::FeatureMicroMips);
5937 } else if (Tok.getString() == "mips0") {
5938 return parseSetMips0Directive();
5939 } else if (Tok.getString() == "mips1") {
5940 return parseSetFeature(Mips::FeatureMips1);
5941 } else if (Tok.getString() == "mips2") {
5942 return parseSetFeature(Mips::FeatureMips2);
5943 } else if (Tok.getString() == "mips3") {
5944 return parseSetFeature(Mips::FeatureMips3);
5945 } else if (Tok.getString() == "mips4") {
5946 return parseSetFeature(Mips::FeatureMips4);
5947 } else if (Tok.getString() == "mips5") {
5948 return parseSetFeature(Mips::FeatureMips5);
5949 } else if (Tok.getString() == "mips32") {
5950 return parseSetFeature(Mips::FeatureMips32);
5951 } else if (Tok.getString() == "mips32r2") {
5952 return parseSetFeature(Mips::FeatureMips32r2);
5953 } else if (Tok.getString() == "mips32r3") {
5954 return parseSetFeature(Mips::FeatureMips32r3);
5955 } else if (Tok.getString() == "mips32r5") {
5956 return parseSetFeature(Mips::FeatureMips32r5);
5957 } else if (Tok.getString() == "mips32r6") {
5958 return parseSetFeature(Mips::FeatureMips32r6);
5959 } else if (Tok.getString() == "mips64") {
5960 return parseSetFeature(Mips::FeatureMips64);
5961 } else if (Tok.getString() == "mips64r2") {
5962 return parseSetFeature(Mips::FeatureMips64r2);
5963 } else if (Tok.getString() == "mips64r3") {
5964 return parseSetFeature(Mips::FeatureMips64r3);
5965 } else if (Tok.getString() == "mips64r5") {
5966 return parseSetFeature(Mips::FeatureMips64r5);
5967 } else if (Tok.getString() == "mips64r6") {
5968 return parseSetFeature(Mips::FeatureMips64r6);
5969 } else if (Tok.getString() == "dsp") {
5970 return parseSetFeature(Mips::FeatureDSP);
5971 } else if (Tok.getString() == "nodsp") {
5972 return parseSetNoDspDirective();
5973 } else if (Tok.getString() == "msa") {
5974 return parseSetMsaDirective();
5975 } else if (Tok.getString() == "nomsa") {
5976 return parseSetNoMsaDirective();
5977 } else if (Tok.getString() == "softfloat") {
5978 return parseSetSoftFloatDirective();
5979 } else if (Tok.getString() == "hardfloat") {
5980 return parseSetHardFloatDirective();
5982 // It is just an identifier, look for an assignment.
5983 parseSetAssignment();
5990 /// parseDataDirective
5991 /// ::= .word [ expression (, expression)* ]
5992 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5993 MCAsmParser &Parser = getParser();
5994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5996 const MCExpr *Value;
5997 if (getParser().parseExpression(Value))
6000 getParser().getStreamer().EmitValue(Value, Size);
6002 if (getLexer().is(AsmToken::EndOfStatement))
6005 if (getLexer().isNot(AsmToken::Comma))
6006 return Error(L, "unexpected token, expected comma");
6015 /// parseDirectiveGpWord
6016 /// ::= .gpword local_sym
6017 bool MipsAsmParser::parseDirectiveGpWord() {
6018 MCAsmParser &Parser = getParser();
6019 const MCExpr *Value;
6020 // EmitGPRel32Value requires an expression, so we are using base class
6021 // method to evaluate the expression.
6022 if (getParser().parseExpression(Value))
6024 getParser().getStreamer().EmitGPRel32Value(Value);
6026 if (getLexer().isNot(AsmToken::EndOfStatement))
6027 return Error(getLexer().getLoc(),
6028 "unexpected token, expected end of statement");
6029 Parser.Lex(); // Eat EndOfStatement token.
6033 /// parseDirectiveGpDWord
6034 /// ::= .gpdword local_sym
6035 bool MipsAsmParser::parseDirectiveGpDWord() {
6036 MCAsmParser &Parser = getParser();
6037 const MCExpr *Value;
6038 // EmitGPRel64Value requires an expression, so we are using base class
6039 // method to evaluate the expression.
6040 if (getParser().parseExpression(Value))
6042 getParser().getStreamer().EmitGPRel64Value(Value);
6044 if (getLexer().isNot(AsmToken::EndOfStatement))
6045 return Error(getLexer().getLoc(),
6046 "unexpected token, expected end of statement");
6047 Parser.Lex(); // Eat EndOfStatement token.
6051 /// parseDirectiveDtpRelWord
6052 /// ::= .dtprelword tls_sym
6053 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6054 MCAsmParser &Parser = getParser();
6055 const MCExpr *Value;
6056 // EmitDTPRel32Value requires an expression, so we are using base class
6057 // method to evaluate the expression.
6058 if (getParser().parseExpression(Value))
6060 getParser().getStreamer().EmitDTPRel32Value(Value);
6062 if (getLexer().isNot(AsmToken::EndOfStatement))
6063 return Error(getLexer().getLoc(),
6064 "unexpected token, expected end of statement");
6065 Parser.Lex(); // Eat EndOfStatement token.
6069 /// parseDirectiveDtpRelDWord
6070 /// ::= .dtpreldword tls_sym
6071 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6072 MCAsmParser &Parser = getParser();
6073 const MCExpr *Value;
6074 // EmitDTPRel64Value requires an expression, so we are using base class
6075 // method to evaluate the expression.
6076 if (getParser().parseExpression(Value))
6078 getParser().getStreamer().EmitDTPRel64Value(Value);
6080 if (getLexer().isNot(AsmToken::EndOfStatement))
6081 return Error(getLexer().getLoc(),
6082 "unexpected token, expected end of statement");
6083 Parser.Lex(); // Eat EndOfStatement token.
6087 /// parseDirectiveTpRelWord
6088 /// ::= .tprelword tls_sym
6089 bool MipsAsmParser::parseDirectiveTpRelWord() {
6090 MCAsmParser &Parser = getParser();
6091 const MCExpr *Value;
6092 // EmitTPRel32Value requires an expression, so we are using base class
6093 // method to evaluate the expression.
6094 if (getParser().parseExpression(Value))
6096 getParser().getStreamer().EmitTPRel32Value(Value);
6098 if (getLexer().isNot(AsmToken::EndOfStatement))
6099 return Error(getLexer().getLoc(),
6100 "unexpected token, expected end of statement");
6101 Parser.Lex(); // Eat EndOfStatement token.
6105 /// parseDirectiveTpRelDWord
6106 /// ::= .tpreldword tls_sym
6107 bool MipsAsmParser::parseDirectiveTpRelDWord() {
6108 MCAsmParser &Parser = getParser();
6109 const MCExpr *Value;
6110 // EmitTPRel64Value requires an expression, so we are using base class
6111 // method to evaluate the expression.
6112 if (getParser().parseExpression(Value))
6114 getParser().getStreamer().EmitTPRel64Value(Value);
6116 if (getLexer().isNot(AsmToken::EndOfStatement))
6117 return Error(getLexer().getLoc(),
6118 "unexpected token, expected end of statement");
6119 Parser.Lex(); // Eat EndOfStatement token.
6123 bool MipsAsmParser::parseDirectiveOption() {
6124 MCAsmParser &Parser = getParser();
6125 // Get the option token.
6126 AsmToken Tok = Parser.getTok();
6127 // At the moment only identifiers are supported.
6128 if (Tok.isNot(AsmToken::Identifier)) {
6129 return Error(Parser.getTok().getLoc(),
6130 "unexpected token, expected identifier");
6133 StringRef Option = Tok.getIdentifier();
6135 if (Option == "pic0") {
6136 // MipsAsmParser needs to know if the current PIC mode changes.
6137 IsPicEnabled = false;
6139 getTargetStreamer().emitDirectiveOptionPic0();
6141 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6142 return Error(Parser.getTok().getLoc(),
6143 "unexpected token, expected end of statement");
6148 if (Option == "pic2") {
6149 // MipsAsmParser needs to know if the current PIC mode changes.
6150 IsPicEnabled = true;
6152 getTargetStreamer().emitDirectiveOptionPic2();
6154 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6155 return Error(Parser.getTok().getLoc(),
6156 "unexpected token, expected end of statement");
6162 Warning(Parser.getTok().getLoc(),
6163 "unknown option, expected 'pic0' or 'pic2'");
6164 Parser.eatToEndOfStatement();
6168 /// parseInsnDirective
6170 bool MipsAsmParser::parseInsnDirective() {
6171 // If this is not the end of the statement, report an error.
6172 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6173 reportParseError("unexpected token, expected end of statement");
6177 // The actual label marking happens in
6178 // MipsELFStreamer::createPendingLabelRelocs().
6179 getTargetStreamer().emitDirectiveInsn();
6181 getParser().Lex(); // Eat EndOfStatement token.
6185 /// parseSSectionDirective
6188 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
6189 // If this is not the end of the statement, report an error.
6190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6191 reportParseError("unexpected token, expected end of statement");
6195 MCSection *ELFSection = getContext().getELFSection(
6196 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
6197 getParser().getStreamer().SwitchSection(ELFSection);
6199 getParser().Lex(); // Eat EndOfStatement token.
6203 /// parseDirectiveModule
6204 /// ::= .module oddspreg
6205 /// ::= .module nooddspreg
6206 /// ::= .module fp=value
6207 /// ::= .module softfloat
6208 /// ::= .module hardfloat
6209 bool MipsAsmParser::parseDirectiveModule() {
6210 MCAsmParser &Parser = getParser();
6211 MCAsmLexer &Lexer = getLexer();
6212 SMLoc L = Lexer.getLoc();
6214 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
6215 // TODO : get a better message.
6216 reportParseError(".module directive must appear before any code");
6221 if (Parser.parseIdentifier(Option)) {
6222 reportParseError("expected .module option identifier");
6226 if (Option == "oddspreg") {
6227 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6229 // Synchronize the abiflags information with the FeatureBits information we
6231 getTargetStreamer().updateABIInfo(*this);
6233 // If printing assembly, use the recently updated abiflags information.
6234 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6235 // emitted at the end).
6236 getTargetStreamer().emitDirectiveModuleOddSPReg();
6238 // If this is not the end of the statement, report an error.
6239 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6240 reportParseError("unexpected token, expected end of statement");
6244 return false; // parseDirectiveModule has finished successfully.
6245 } else if (Option == "nooddspreg") {
6247 return Error(L, "'.module nooddspreg' requires the O32 ABI");
6250 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6252 // Synchronize the abiflags information with the FeatureBits information we
6254 getTargetStreamer().updateABIInfo(*this);
6256 // If printing assembly, use the recently updated abiflags information.
6257 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6258 // emitted at the end).
6259 getTargetStreamer().emitDirectiveModuleOddSPReg();
6261 // If this is not the end of the statement, report an error.
6262 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6263 reportParseError("unexpected token, expected end of statement");
6267 return false; // parseDirectiveModule has finished successfully.
6268 } else if (Option == "fp") {
6269 return parseDirectiveModuleFP();
6270 } else if (Option == "softfloat") {
6271 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6273 // Synchronize the ABI Flags information with the FeatureBits information we
6275 getTargetStreamer().updateABIInfo(*this);
6277 // If printing assembly, use the recently updated ABI Flags information.
6278 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6280 getTargetStreamer().emitDirectiveModuleSoftFloat();
6282 // If this is not the end of the statement, report an error.
6283 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6284 reportParseError("unexpected token, expected end of statement");
6288 return false; // parseDirectiveModule has finished successfully.
6289 } else if (Option == "hardfloat") {
6290 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6292 // Synchronize the ABI Flags information with the FeatureBits information we
6294 getTargetStreamer().updateABIInfo(*this);
6296 // If printing assembly, use the recently updated ABI Flags information.
6297 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6299 getTargetStreamer().emitDirectiveModuleHardFloat();
6301 // If this is not the end of the statement, report an error.
6302 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6303 reportParseError("unexpected token, expected end of statement");
6307 return false; // parseDirectiveModule has finished successfully.
6309 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
6313 /// parseDirectiveModuleFP
6317 bool MipsAsmParser::parseDirectiveModuleFP() {
6318 MCAsmParser &Parser = getParser();
6319 MCAsmLexer &Lexer = getLexer();
6321 if (Lexer.isNot(AsmToken::Equal)) {
6322 reportParseError("unexpected token, expected equals sign '='");
6325 Parser.Lex(); // Eat '=' token.
6327 MipsABIFlagsSection::FpABIKind FpABI;
6328 if (!parseFpABIValue(FpABI, ".module"))
6331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6332 reportParseError("unexpected token, expected end of statement");
6336 // Synchronize the abiflags information with the FeatureBits information we
6338 getTargetStreamer().updateABIInfo(*this);
6340 // If printing assembly, use the recently updated abiflags information.
6341 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6342 // emitted at the end).
6343 getTargetStreamer().emitDirectiveModuleFP();
6345 Parser.Lex(); // Consume the EndOfStatement.
6349 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
6350 StringRef Directive) {
6351 MCAsmParser &Parser = getParser();
6352 MCAsmLexer &Lexer = getLexer();
6353 bool ModuleLevelOptions = Directive == ".module";
6355 if (Lexer.is(AsmToken::Identifier)) {
6356 StringRef Value = Parser.getTok().getString();
6359 if (Value != "xx") {
6360 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6365 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
6369 FpABI = MipsABIFlagsSection::FpABIKind::XX;
6370 if (ModuleLevelOptions) {
6371 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6372 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6374 setFeatureBits(Mips::FeatureFPXX, "fpxx");
6375 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6380 if (Lexer.is(AsmToken::Integer)) {
6381 unsigned Value = Parser.getTok().getIntVal();
6384 if (Value != 32 && Value != 64) {
6385 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6391 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6395 FpABI = MipsABIFlagsSection::FpABIKind::S32;
6396 if (ModuleLevelOptions) {
6397 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6398 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6400 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6401 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6404 FpABI = MipsABIFlagsSection::FpABIKind::S64;
6405 if (ModuleLevelOptions) {
6406 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6407 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6409 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6410 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6420 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6421 // This returns false if this function recognizes the directive
6422 // regardless of whether it is successfully handles or reports an
6423 // error. Otherwise it returns true to give the generic parser a
6424 // chance at recognizing it.
6426 MCAsmParser &Parser = getParser();
6427 StringRef IDVal = DirectiveID.getString();
6429 if (IDVal == ".cpload") {
6430 parseDirectiveCpLoad(DirectiveID.getLoc());
6433 if (IDVal == ".cprestore") {
6434 parseDirectiveCpRestore(DirectiveID.getLoc());
6437 if (IDVal == ".dword") {
6438 parseDataDirective(8, DirectiveID.getLoc());
6441 if (IDVal == ".ent") {
6442 StringRef SymbolName;
6444 if (Parser.parseIdentifier(SymbolName)) {
6445 reportParseError("expected identifier after .ent");
6449 // There's an undocumented extension that allows an integer to
6450 // follow the name of the procedure which AFAICS is ignored by GAS.
6451 // Example: .ent foo,2
6452 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6453 if (getLexer().isNot(AsmToken::Comma)) {
6454 // Even though we accept this undocumented extension for compatibility
6455 // reasons, the additional integer argument does not actually change
6456 // the behaviour of the '.ent' directive, so we would like to discourage
6457 // its use. We do this by not referring to the extended version in
6458 // error messages which are not directly related to its use.
6459 reportParseError("unexpected token, expected end of statement");
6462 Parser.Lex(); // Eat the comma.
6463 const MCExpr *DummyNumber;
6464 int64_t DummyNumberVal;
6465 // If the user was explicitly trying to use the extended version,
6466 // we still give helpful extension-related error messages.
6467 if (Parser.parseExpression(DummyNumber)) {
6468 reportParseError("expected number after comma");
6471 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6472 reportParseError("expected an absolute expression after comma");
6477 // If this is not the end of the statement, report an error.
6478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6479 reportParseError("unexpected token, expected end of statement");
6483 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6485 getTargetStreamer().emitDirectiveEnt(*Sym);
6487 IsCpRestoreSet = false;
6491 if (IDVal == ".end") {
6492 StringRef SymbolName;
6494 if (Parser.parseIdentifier(SymbolName)) {
6495 reportParseError("expected identifier after .end");
6499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6500 reportParseError("unexpected token, expected end of statement");
6504 if (CurrentFn == nullptr) {
6505 reportParseError(".end used without .ent");
6509 if ((SymbolName != CurrentFn->getName())) {
6510 reportParseError(".end symbol does not match .ent symbol");
6514 getTargetStreamer().emitDirectiveEnd(SymbolName);
6515 CurrentFn = nullptr;
6516 IsCpRestoreSet = false;
6520 if (IDVal == ".frame") {
6521 // .frame $stack_reg, frame_size_in_bytes, $return_reg
6522 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6523 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6524 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6525 reportParseError("expected stack register");
6529 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6530 if (!StackRegOpnd.isGPRAsmReg()) {
6531 reportParseError(StackRegOpnd.getStartLoc(),
6532 "expected general purpose register");
6535 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6537 if (Parser.getTok().is(AsmToken::Comma))
6540 reportParseError("unexpected token, expected comma");
6544 // Parse the frame size.
6545 const MCExpr *FrameSize;
6546 int64_t FrameSizeVal;
6548 if (Parser.parseExpression(FrameSize)) {
6549 reportParseError("expected frame size value");
6553 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6554 reportParseError("frame size not an absolute expression");
6558 if (Parser.getTok().is(AsmToken::Comma))
6561 reportParseError("unexpected token, expected comma");
6565 // Parse the return register.
6567 ResTy = parseAnyRegister(TmpReg);
6568 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6569 reportParseError("expected return register");
6573 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6574 if (!ReturnRegOpnd.isGPRAsmReg()) {
6575 reportParseError(ReturnRegOpnd.getStartLoc(),
6576 "expected general purpose register");
6580 // If this is not the end of the statement, report an error.
6581 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6582 reportParseError("unexpected token, expected end of statement");
6586 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6587 ReturnRegOpnd.getGPR32Reg());
6588 IsCpRestoreSet = false;
6592 if (IDVal == ".set") {
6593 parseDirectiveSet();
6597 if (IDVal == ".mask" || IDVal == ".fmask") {
6598 // .mask bitmask, frame_offset
6599 // bitmask: One bit for each register used.
6600 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6601 // first register is expected to be saved.
6603 // .mask 0x80000000, -4
6604 // .fmask 0x80000000, -4
6607 // Parse the bitmask
6608 const MCExpr *BitMask;
6611 if (Parser.parseExpression(BitMask)) {
6612 reportParseError("expected bitmask value");
6616 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6617 reportParseError("bitmask not an absolute expression");
6621 if (Parser.getTok().is(AsmToken::Comma))
6624 reportParseError("unexpected token, expected comma");
6628 // Parse the frame_offset
6629 const MCExpr *FrameOffset;
6630 int64_t FrameOffsetVal;
6632 if (Parser.parseExpression(FrameOffset)) {
6633 reportParseError("expected frame offset value");
6637 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6638 reportParseError("frame offset not an absolute expression");
6642 // If this is not the end of the statement, report an error.
6643 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6644 reportParseError("unexpected token, expected end of statement");
6648 if (IDVal == ".mask")
6649 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6651 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6655 if (IDVal == ".nan")
6656 return parseDirectiveNaN();
6658 if (IDVal == ".gpword") {
6659 parseDirectiveGpWord();
6663 if (IDVal == ".gpdword") {
6664 parseDirectiveGpDWord();
6668 if (IDVal == ".dtprelword") {
6669 parseDirectiveDtpRelWord();
6673 if (IDVal == ".dtpreldword") {
6674 parseDirectiveDtpRelDWord();
6678 if (IDVal == ".tprelword") {
6679 parseDirectiveTpRelWord();
6683 if (IDVal == ".tpreldword") {
6684 parseDirectiveTpRelDWord();
6688 if (IDVal == ".word") {
6689 parseDataDirective(4, DirectiveID.getLoc());
6693 if (IDVal == ".hword") {
6694 parseDataDirective(2, DirectiveID.getLoc());
6698 if (IDVal == ".option") {
6699 parseDirectiveOption();
6703 if (IDVal == ".abicalls") {
6704 getTargetStreamer().emitDirectiveAbiCalls();
6705 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6706 Error(Parser.getTok().getLoc(),
6707 "unexpected token, expected end of statement");
6712 if (IDVal == ".cpsetup") {
6713 parseDirectiveCPSetup();
6716 if (IDVal == ".cpreturn") {
6717 parseDirectiveCPReturn();
6720 if (IDVal == ".module") {
6721 parseDirectiveModule();
6724 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
6725 parseInternalDirectiveReallowModule();
6728 if (IDVal == ".insn") {
6729 parseInsnDirective();
6732 if (IDVal == ".sbss") {
6733 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
6736 if (IDVal == ".sdata") {
6737 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
6744 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6745 // If this is not the end of the statement, report an error.
6746 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6747 reportParseError("unexpected token, expected end of statement");
6751 getTargetStreamer().reallowModuleDirective();
6753 getParser().Lex(); // Eat EndOfStatement token.
6757 extern "C" void LLVMInitializeMipsAsmParser() {
6758 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
6759 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
6760 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
6761 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
6764 #define GET_REGISTER_MATCHER
6765 #define GET_MATCHER_IMPLEMENTATION
6766 #include "MipsGenAsmMatcher.inc"