1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIFlagsSection.h"
11 #include "MCTargetDesc/MipsABIInfo.h"
12 #include "MCTargetDesc/MipsBaseInfo.h"
13 #include "MCTargetDesc/MipsMCExpr.h"
14 #include "MCTargetDesc/MipsMCTargetDesc.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCAsmParser.h"
31 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/SubtargetFeature.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/Compiler.h"
43 #include "llvm/Support/Debug.h"
44 #include "llvm/Support/ErrorHandling.h"
45 #include "llvm/Support/MathExtras.h"
46 #include "llvm/Support/SMLoc.h"
47 #include "llvm/Support/SourceMgr.h"
48 #include "llvm/Support/TargetRegistry.h"
49 #include "llvm/Support/raw_ostream.h"
59 #define DEBUG_TYPE "mips-asm-parser"
65 } // end namespace llvm
69 class MipsAssemblerOptions {
71 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
73 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
74 ATReg = Opts->getATRegIndex();
75 Reorder = Opts->isReorder();
76 Macro = Opts->isMacro();
77 Features = Opts->getFeatures();
80 unsigned getATRegIndex() const { return ATReg; }
81 bool setATRegIndex(unsigned Reg) {
89 bool isReorder() const { return Reorder; }
90 void setReorder() { Reorder = true; }
91 void setNoReorder() { Reorder = false; }
93 bool isMacro() const { return Macro; }
94 void setMacro() { Macro = true; }
95 void setNoMacro() { Macro = false; }
97 const FeatureBitset &getFeatures() const { return Features; }
98 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
100 // Set of features that are either architecture features or referenced
101 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
102 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
103 // The reason we need this mask is explained in the selectArch function.
104 // FIXME: Ideally we would like TableGen to generate this information.
105 static const FeatureBitset AllArchRelatedMask;
111 FeatureBitset Features;
114 } // end anonymous namespace
116 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
117 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
118 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
119 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
120 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
121 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
122 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
123 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
124 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
129 class MipsAsmParser : public MCTargetAsmParser {
130 MipsTargetStreamer &getTargetStreamer() {
131 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
132 return static_cast<MipsTargetStreamer &>(TS);
136 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
137 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
138 // nullptr, which indicates that no function is currently
139 // selected. This usually happens after an '.end func'
145 unsigned CpSaveLocation;
146 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
147 bool CpSaveLocationIsRegister;
149 // Map of register aliases created via the .set directive.
150 StringMap<AsmToken> RegisterSets;
152 // Print a warning along with its fix-it message at the given range.
153 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
154 SMRange Range, bool ShowColors = true);
156 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
158 #define GET_ASSEMBLER_HEADER
159 #include "MipsGenAsmMatcher.inc"
162 checkEarlyTargetMatchPredicate(MCInst &Inst,
163 const OperandVector &Operands) override;
164 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
166 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
167 OperandVector &Operands, MCStreamer &Out,
169 bool MatchingInlineAsm) override;
171 /// Parse a register as used in CFI directives
172 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
174 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
176 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
178 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
180 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
181 SMLoc NameLoc, OperandVector &Operands) override;
183 bool ParseDirective(AsmToken DirectiveID) override;
185 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
187 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
188 StringRef Identifier, SMLoc S);
189 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
190 const AsmToken &Token,
192 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
194 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
195 OperandMatchResultTy parseImm(OperandVector &Operands);
196 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
197 OperandMatchResultTy parseInvNum(OperandVector &Operands);
198 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
199 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
201 bool searchSymbolAlias(OperandVector &Operands);
203 bool parseOperand(OperandVector &, StringRef Mnemonic);
205 enum MacroExpanderResultTy {
211 // Expands assembly pseudo instructions.
212 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
214 const MCSubtargetInfo *STI);
216 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
217 const MCSubtargetInfo *STI);
219 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
220 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
221 MCStreamer &Out, const MCSubtargetInfo *STI);
223 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
224 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
225 MCStreamer &Out, const MCSubtargetInfo *STI);
227 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
229 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
230 MCStreamer &Out, const MCSubtargetInfo *STI);
232 bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
233 SMLoc IDLoc, MCStreamer &Out,
234 const MCSubtargetInfo *STI);
236 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
237 const MCOperand &Offset, bool Is32BitAddress,
238 SMLoc IDLoc, MCStreamer &Out,
239 const MCSubtargetInfo *STI);
241 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
242 const MCSubtargetInfo *STI);
244 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
245 const MCSubtargetInfo *STI, bool IsLoad);
247 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
248 const MCSubtargetInfo *STI);
250 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
251 const MCSubtargetInfo *STI);
253 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
254 const MCSubtargetInfo *STI);
256 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
257 const MCSubtargetInfo *STI);
259 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
260 const MCSubtargetInfo *STI, const bool IsMips64,
263 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
264 MCStreamer &Out, const MCSubtargetInfo *STI);
266 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
267 const MCSubtargetInfo *STI);
269 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270 const MCSubtargetInfo *STI);
272 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
273 const MCSubtargetInfo *STI);
275 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
276 MCStreamer &Out, const MCSubtargetInfo *STI);
277 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
278 const MCSubtargetInfo *STI);
279 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
281 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
282 const MCSubtargetInfo *STI);
284 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
285 const MCSubtargetInfo *STI);
287 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
288 const MCSubtargetInfo *STI);
290 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291 const MCSubtargetInfo *STI);
293 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
294 const MCSubtargetInfo *STI);
296 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
299 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
300 const MCSubtargetInfo *STI, bool IsLoad);
302 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
303 const MCSubtargetInfo *STI);
305 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
306 const MCSubtargetInfo *STI);
308 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
309 const MCSubtargetInfo *STI);
311 bool reportParseError(Twine ErrorMsg);
312 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
314 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
316 bool isEvaluated(const MCExpr *Expr);
317 bool parseSetMips0Directive();
318 bool parseSetArchDirective();
319 bool parseSetFeature(uint64_t Feature);
320 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
321 bool parseDirectiveCpLoad(SMLoc Loc);
322 bool parseDirectiveCpRestore(SMLoc Loc);
323 bool parseDirectiveCPSetup();
324 bool parseDirectiveCPReturn();
325 bool parseDirectiveNaN();
326 bool parseDirectiveSet();
327 bool parseDirectiveOption();
328 bool parseInsnDirective();
329 bool parseRSectionDirective(StringRef Section);
330 bool parseSSectionDirective(StringRef Section, unsigned Type);
332 bool parseSetAtDirective();
333 bool parseSetNoAtDirective();
334 bool parseSetMacroDirective();
335 bool parseSetNoMacroDirective();
336 bool parseSetMsaDirective();
337 bool parseSetNoMsaDirective();
338 bool parseSetNoDspDirective();
339 bool parseSetReorderDirective();
340 bool parseSetNoReorderDirective();
341 bool parseSetMips16Directive();
342 bool parseSetNoMips16Directive();
343 bool parseSetFpDirective();
344 bool parseSetOddSPRegDirective();
345 bool parseSetNoOddSPRegDirective();
346 bool parseSetPopDirective();
347 bool parseSetPushDirective();
348 bool parseSetSoftFloatDirective();
349 bool parseSetHardFloatDirective();
350 bool parseSetMtDirective();
351 bool parseSetNoMtDirective();
352 bool parseSetNoCRCDirective();
353 bool parseSetNoVirtDirective();
354 bool parseSetNoGINVDirective();
356 bool parseSetAssignment();
358 bool parseDirectiveGpWord();
359 bool parseDirectiveGpDWord();
360 bool parseDirectiveDtpRelWord();
361 bool parseDirectiveDtpRelDWord();
362 bool parseDirectiveTpRelWord();
363 bool parseDirectiveTpRelDWord();
364 bool parseDirectiveModule();
365 bool parseDirectiveModuleFP();
366 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
367 StringRef Directive);
369 bool parseInternalDirectiveReallowModule();
371 bool eatComma(StringRef ErrorStr);
373 int matchCPURegisterName(StringRef Symbol);
375 int matchHWRegsRegisterName(StringRef Symbol);
377 int matchFPURegisterName(StringRef Name);
379 int matchFCCRegisterName(StringRef Name);
381 int matchACRegisterName(StringRef Name);
383 int matchMSA128RegisterName(StringRef Name);
385 int matchMSA128CtrlRegisterName(StringRef Name);
387 unsigned getReg(int RC, int RegNo);
389 /// Returns the internal register number for the current AT. Also checks if
390 /// the current AT is unavailable (set to $0) and gives an error if it is.
391 /// This should be used in pseudo-instruction expansions which need AT.
392 unsigned getATReg(SMLoc Loc);
396 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
397 const MCSubtargetInfo *STI);
399 // Helper function that checks if the value of a vector index is within the
400 // boundaries of accepted values for each RegisterKind
401 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
402 bool validateMSAIndex(int Val, int RegKind);
404 // Selects a new architecture by updating the FeatureBits with the necessary
405 // info including implied dependencies.
406 // Internally, it clears all the feature bits related to *any* architecture
407 // and selects the new one using the ToggleFeature functionality of the
408 // MCSubtargetInfo object that handles implied dependencies. The reason we
409 // clear all the arch related bits manually is because ToggleFeature only
410 // clears the features that imply the feature being cleared and not the
411 // features implied by the feature being cleared. This is easier to see
413 // --------------------------------------------------
414 // | Feature | Implies |
415 // | -------------------------------------------------|
416 // | FeatureMips1 | None |
417 // | FeatureMips2 | FeatureMips1 |
418 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
419 // | FeatureMips4 | FeatureMips3 |
421 // --------------------------------------------------
423 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
424 // FeatureMipsGP64 | FeatureMips1)
425 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
426 void selectArch(StringRef ArchFeature) {
427 MCSubtargetInfo &STI = copySTI();
428 FeatureBitset FeatureBits = STI.getFeatureBits();
429 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
430 STI.setFeatureBits(FeatureBits);
431 setAvailableFeatures(
432 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
433 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
436 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
437 if (!(getSTI().getFeatureBits()[Feature])) {
438 MCSubtargetInfo &STI = copySTI();
439 setAvailableFeatures(
440 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
441 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
445 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
446 if (getSTI().getFeatureBits()[Feature]) {
447 MCSubtargetInfo &STI = copySTI();
448 setAvailableFeatures(
449 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
450 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
454 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
455 setFeatureBits(Feature, FeatureString);
456 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
459 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
460 clearFeatureBits(Feature, FeatureString);
461 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
465 enum MipsMatchResultTy {
466 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
467 Match_RequiresDifferentOperands,
468 Match_RequiresNoZeroRegister,
469 Match_RequiresSameSrcAndDst,
470 Match_NoFCCRegisterForCurrentISA,
471 Match_NonZeroOperandForSync,
472 Match_NonZeroOperandForMTCX,
473 Match_RequiresPosSizeRange0_32,
474 Match_RequiresPosSizeRange33_64,
475 Match_RequiresPosSizeUImm6,
476 #define GET_OPERAND_DIAGNOSTIC_TYPES
477 #include "MipsGenAsmMatcher.inc"
478 #undef GET_OPERAND_DIAGNOSTIC_TYPES
481 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
482 const MCInstrInfo &MII, const MCTargetOptions &Options)
483 : MCTargetAsmParser(Options, sti, MII),
484 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
485 sti.getCPU(), Options)) {
486 MCAsmParserExtension::Initialize(parser);
488 parser.addAliasForDirective(".asciiz", ".asciz");
489 parser.addAliasForDirective(".hword", ".2byte");
490 parser.addAliasForDirective(".word", ".4byte");
491 parser.addAliasForDirective(".dword", ".8byte");
493 // Initialize the set of available features.
494 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
496 // Remember the initial assembler options. The user can not modify these.
497 AssemblerOptions.push_back(
498 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
500 // Create an assembler options environment for the user to modify.
501 AssemblerOptions.push_back(
502 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
504 getTargetStreamer().updateABIInfo(*this);
506 if (!isABI_O32() && !useOddSPReg() != 0)
507 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
511 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
513 IsCpRestoreSet = false;
514 CpRestoreOffset = -1;
516 const Triple &TheTriple = sti.getTargetTriple();
517 IsLittleEndian = TheTriple.isLittleEndian();
519 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
520 report_fatal_error("microMIPS64R6 is not supported", false);
522 if (!isABI_O32() && inMicroMipsMode())
523 report_fatal_error("microMIPS64 is not supported", false);
526 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
527 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
529 bool isGP64bit() const {
530 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
533 bool isFP64bit() const {
534 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
537 const MipsABIInfo &getABI() const { return ABI; }
538 bool isABI_N32() const { return ABI.IsN32(); }
539 bool isABI_N64() const { return ABI.IsN64(); }
540 bool isABI_O32() const { return ABI.IsO32(); }
541 bool isABI_FPXX() const {
542 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
545 bool useOddSPReg() const {
546 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
549 bool inMicroMipsMode() const {
550 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
553 bool hasMips1() const {
554 return getSTI().getFeatureBits()[Mips::FeatureMips1];
557 bool hasMips2() const {
558 return getSTI().getFeatureBits()[Mips::FeatureMips2];
561 bool hasMips3() const {
562 return getSTI().getFeatureBits()[Mips::FeatureMips3];
565 bool hasMips4() const {
566 return getSTI().getFeatureBits()[Mips::FeatureMips4];
569 bool hasMips5() const {
570 return getSTI().getFeatureBits()[Mips::FeatureMips5];
573 bool hasMips32() const {
574 return getSTI().getFeatureBits()[Mips::FeatureMips32];
577 bool hasMips64() const {
578 return getSTI().getFeatureBits()[Mips::FeatureMips64];
581 bool hasMips32r2() const {
582 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
585 bool hasMips64r2() const {
586 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
589 bool hasMips32r3() const {
590 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
593 bool hasMips64r3() const {
594 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
597 bool hasMips32r5() const {
598 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
601 bool hasMips64r5() const {
602 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
605 bool hasMips32r6() const {
606 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
609 bool hasMips64r6() const {
610 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
613 bool hasDSP() const {
614 return getSTI().getFeatureBits()[Mips::FeatureDSP];
617 bool hasDSPR2() const {
618 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
621 bool hasDSPR3() const {
622 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
625 bool hasMSA() const {
626 return getSTI().getFeatureBits()[Mips::FeatureMSA];
629 bool hasCnMips() const {
630 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
637 bool inMips16Mode() const {
638 return getSTI().getFeatureBits()[Mips::FeatureMips16];
641 bool useTraps() const {
642 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
645 bool useSoftFloat() const {
646 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
649 return getSTI().getFeatureBits()[Mips::FeatureMT];
652 bool hasCRC() const {
653 return getSTI().getFeatureBits()[Mips::FeatureCRC];
656 bool hasVirt() const {
657 return getSTI().getFeatureBits()[Mips::FeatureVirt];
660 bool hasGINV() const {
661 return getSTI().getFeatureBits()[Mips::FeatureGINV];
664 /// Warn if RegIndex is the same as the current AT.
665 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
667 void warnIfNoMacro(SMLoc Loc);
669 bool isLittle() const { return IsLittleEndian; }
671 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
672 AsmToken::TokenKind OperatorToken,
673 MCContext &Ctx) override {
674 switch(OperatorToken) {
676 llvm_unreachable("Unknown token");
678 case AsmToken::PercentCall16:
679 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
680 case AsmToken::PercentCall_Hi:
681 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
682 case AsmToken::PercentCall_Lo:
683 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
684 case AsmToken::PercentDtprel_Hi:
685 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
686 case AsmToken::PercentDtprel_Lo:
687 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
688 case AsmToken::PercentGot:
689 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
690 case AsmToken::PercentGot_Disp:
691 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
692 case AsmToken::PercentGot_Hi:
693 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
694 case AsmToken::PercentGot_Lo:
695 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
696 case AsmToken::PercentGot_Ofst:
697 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
698 case AsmToken::PercentGot_Page:
699 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
700 case AsmToken::PercentGottprel:
701 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
702 case AsmToken::PercentGp_Rel:
703 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
704 case AsmToken::PercentHi:
705 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
706 case AsmToken::PercentHigher:
707 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
708 case AsmToken::PercentHighest:
709 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
710 case AsmToken::PercentLo:
711 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
712 case AsmToken::PercentNeg:
713 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
714 case AsmToken::PercentPcrel_Hi:
715 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
716 case AsmToken::PercentPcrel_Lo:
717 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
718 case AsmToken::PercentTlsgd:
719 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
720 case AsmToken::PercentTlsldm:
721 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
722 case AsmToken::PercentTprel_Hi:
723 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
724 case AsmToken::PercentTprel_Lo:
725 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
730 /// MipsOperand - Instances of this class represent a parsed Mips machine
732 class MipsOperand : public MCParsedAsmOperand {
734 /// Broad categories of register classes
735 /// The exact class is finalized by the render method.
737 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
738 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
740 RegKind_FCC = 4, /// FCC
741 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
742 RegKind_MSACtrl = 16, /// MSA control registers
743 RegKind_COP2 = 32, /// COP2
744 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
746 RegKind_CCR = 128, /// CCR
747 RegKind_HWRegs = 256, /// HWRegs
748 RegKind_COP3 = 512, /// COP3
749 RegKind_COP0 = 1024, /// COP0
750 /// Potentially any (e.g. $1)
751 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
752 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
753 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
758 k_Immediate, /// An immediate (possibly involving symbol references)
759 k_Memory, /// Base + Offset Memory Address
760 k_RegisterIndex, /// A register index in one or more RegKind.
761 k_Token, /// A simple token
762 k_RegList, /// A physical register list
763 k_RegPair /// A pair of physical register
767 MipsOperand(KindTy K, MipsAsmParser &Parser)
768 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
770 ~MipsOperand() override {
779 case k_RegisterIndex:
787 /// For diagnostics, and checking the assembler temporary
788 MipsAsmParser &AsmParser;
796 unsigned Index; /// Index into the register class
797 RegKind Kind; /// Bitfield of the kinds it could possibly be
798 struct Token Tok; /// The input token this operand originated from.
799 const MCRegisterInfo *RegInfo;
812 SmallVector<unsigned, 10> *List;
817 struct RegIdxOp RegIdx;
820 struct RegListOp RegList;
823 SMLoc StartLoc, EndLoc;
825 /// Internal constructor for register kinds
826 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
828 const MCRegisterInfo *RegInfo,
830 MipsAsmParser &Parser) {
831 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
832 Op->RegIdx.Index = Index;
833 Op->RegIdx.RegInfo = RegInfo;
834 Op->RegIdx.Kind = RegKind;
835 Op->RegIdx.Tok.Data = Str.data();
836 Op->RegIdx.Tok.Length = Str.size();
843 /// Coerce the register to GPR32 and return the real register for the current
845 unsigned getGPR32Reg() const {
846 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
847 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
848 unsigned ClassID = Mips::GPR32RegClassID;
849 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
852 /// Coerce the register to GPR32 and return the real register for the current
854 unsigned getGPRMM16Reg() const {
855 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
856 unsigned ClassID = Mips::GPR32RegClassID;
857 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
860 /// Coerce the register to GPR64 and return the real register for the current
862 unsigned getGPR64Reg() const {
863 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
864 unsigned ClassID = Mips::GPR64RegClassID;
865 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
869 /// Coerce the register to AFGR64 and return the real register for the current
871 unsigned getAFGR64Reg() const {
872 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
873 if (RegIdx.Index % 2 != 0)
874 AsmParser.Warning(StartLoc, "Float register should be even.");
875 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
876 .getRegister(RegIdx.Index / 2);
879 /// Coerce the register to FGR64 and return the real register for the current
881 unsigned getFGR64Reg() const {
882 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
883 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
884 .getRegister(RegIdx.Index);
887 /// Coerce the register to FGR32 and return the real register for the current
889 unsigned getFGR32Reg() const {
890 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
891 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
892 .getRegister(RegIdx.Index);
895 /// Coerce the register to FGRH32 and return the real register for the current
897 unsigned getFGRH32Reg() const {
898 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
899 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
900 .getRegister(RegIdx.Index);
903 /// Coerce the register to FCC and return the real register for the current
905 unsigned getFCCReg() const {
906 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
907 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
908 .getRegister(RegIdx.Index);
911 /// Coerce the register to MSA128 and return the real register for the current
913 unsigned getMSA128Reg() const {
914 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
915 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
917 unsigned ClassID = Mips::MSA128BRegClassID;
918 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
921 /// Coerce the register to MSACtrl and return the real register for the
923 unsigned getMSACtrlReg() const {
924 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
925 unsigned ClassID = Mips::MSACtrlRegClassID;
926 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
929 /// Coerce the register to COP0 and return the real register for the
931 unsigned getCOP0Reg() const {
932 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
933 unsigned ClassID = Mips::COP0RegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 /// Coerce the register to COP2 and return the real register for the
939 unsigned getCOP2Reg() const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
941 unsigned ClassID = Mips::COP2RegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 /// Coerce the register to COP3 and return the real register for the
947 unsigned getCOP3Reg() const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
949 unsigned ClassID = Mips::COP3RegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
953 /// Coerce the register to ACC64DSP and return the real register for the
955 unsigned getACC64DSPReg() const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
957 unsigned ClassID = Mips::ACC64DSPRegClassID;
958 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
961 /// Coerce the register to HI32DSP and return the real register for the
963 unsigned getHI32DSPReg() const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
965 unsigned ClassID = Mips::HI32DSPRegClassID;
966 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
969 /// Coerce the register to LO32DSP and return the real register for the
971 unsigned getLO32DSPReg() const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
973 unsigned ClassID = Mips::LO32DSPRegClassID;
974 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
977 /// Coerce the register to CCR and return the real register for the
979 unsigned getCCRReg() const {
980 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
981 unsigned ClassID = Mips::CCRRegClassID;
982 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985 /// Coerce the register to HWRegs and return the real register for the
987 unsigned getHWRegsReg() const {
988 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
989 unsigned ClassID = Mips::HWRegsRegClassID;
990 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
994 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
995 // Add as immediate when possible. Null MCExpr = 0.
997 Inst.addOperand(MCOperand::createImm(0));
998 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
999 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1001 Inst.addOperand(MCOperand::createExpr(Expr));
1004 void addRegOperands(MCInst &Inst, unsigned N) const {
1005 llvm_unreachable("Use a custom parser instead");
1008 /// Render the operand to an MCInst as a GPR32
1009 /// Asserts if the wrong number of operands are requested, or the operand
1010 /// is not a k_RegisterIndex compatible with RegKind_GPR
1011 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1012 assert(N == 1 && "Invalid number of operands!");
1013 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1016 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1017 assert(N == 1 && "Invalid number of operands!");
1018 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1021 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1022 assert(N == 1 && "Invalid number of operands!");
1023 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1026 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1027 assert(N == 1 && "Invalid number of operands!");
1028 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1031 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1032 assert(N == 1 && "Invalid number of operands!");
1033 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1036 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1037 assert(N == 1 && "Invalid number of operands!");
1038 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1041 /// Render the operand to an MCInst as a GPR64
1042 /// Asserts if the wrong number of operands are requested, or the operand
1043 /// is not a k_RegisterIndex compatible with RegKind_GPR
1044 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1045 assert(N == 1 && "Invalid number of operands!");
1046 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1049 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1050 assert(N == 1 && "Invalid number of operands!");
1051 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1054 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1055 assert(N == 1 && "Invalid number of operands!");
1056 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1059 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1060 assert(N == 1 && "Invalid number of operands!");
1061 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1064 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1065 assert(N == 1 && "Invalid number of operands!");
1066 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1069 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1070 assert(N == 1 && "Invalid number of operands!");
1071 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1072 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1073 // FIXME: This should propagate failure up to parseStatement.
1074 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1075 AsmParser.getParser().printError(
1076 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1080 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1081 assert(N == 1 && "Invalid number of operands!");
1082 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1083 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1084 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1085 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1089 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1090 assert(N == 1 && "Invalid number of operands!");
1091 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1094 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1095 assert(N == 1 && "Invalid number of operands!");
1096 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1099 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1100 assert(N == 1 && "Invalid number of operands!");
1101 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1104 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1105 assert(N == 1 && "Invalid number of operands!");
1106 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1109 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1110 assert(N == 1 && "Invalid number of operands!");
1111 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1114 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1115 assert(N == 1 && "Invalid number of operands!");
1116 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1119 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1120 assert(N == 1 && "Invalid number of operands!");
1121 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1124 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1125 assert(N == 1 && "Invalid number of operands!");
1126 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1129 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1130 assert(N == 1 && "Invalid number of operands!");
1131 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1134 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1135 assert(N == 1 && "Invalid number of operands!");
1136 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1139 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1140 assert(N == 1 && "Invalid number of operands!");
1141 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1144 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1145 assert(N == 1 && "Invalid number of operands!");
1146 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1149 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1150 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1151 assert(N == 1 && "Invalid number of operands!");
1152 uint64_t Imm = getConstantImm() - Offset;
1153 Imm &= (1ULL << Bits) - 1;
1155 Imm += AdjustOffset;
1156 Inst.addOperand(MCOperand::createImm(Imm));
1159 template <unsigned Bits>
1160 void addSImmOperands(MCInst &Inst, unsigned N) const {
1161 if (isImm() && !isConstantImm()) {
1162 addExpr(Inst, getImm());
1165 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1168 template <unsigned Bits>
1169 void addUImmOperands(MCInst &Inst, unsigned N) const {
1170 if (isImm() && !isConstantImm()) {
1171 addExpr(Inst, getImm());
1174 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1177 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1178 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1179 assert(N == 1 && "Invalid number of operands!");
1180 int64_t Imm = getConstantImm() - Offset;
1181 Imm = SignExtend64<Bits>(Imm);
1183 Imm += AdjustOffset;
1184 Inst.addOperand(MCOperand::createImm(Imm));
1187 void addImmOperands(MCInst &Inst, unsigned N) const {
1188 assert(N == 1 && "Invalid number of operands!");
1189 const MCExpr *Expr = getImm();
1190 addExpr(Inst, Expr);
1193 void addMemOperands(MCInst &Inst, unsigned N) const {
1194 assert(N == 2 && "Invalid number of operands!");
1196 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1197 ? getMemBase()->getGPR64Reg()
1198 : getMemBase()->getGPR32Reg()));
1200 const MCExpr *Expr = getMemOff();
1201 addExpr(Inst, Expr);
1204 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1205 assert(N == 2 && "Invalid number of operands!");
1207 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1209 const MCExpr *Expr = getMemOff();
1210 addExpr(Inst, Expr);
1213 void addRegListOperands(MCInst &Inst, unsigned N) const {
1214 assert(N == 1 && "Invalid number of operands!");
1216 for (auto RegNo : getRegList())
1217 Inst.addOperand(MCOperand::createReg(RegNo));
1220 void addRegPairOperands(MCInst &Inst, unsigned N) const {
1221 assert(N == 2 && "Invalid number of operands!");
1222 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1223 unsigned RegNo = getRegPair();
1224 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1225 Inst.addOperand(MCOperand::createReg(
1226 RegIdx.RegInfo->getRegClass(
1227 AsmParser.getABI().AreGprs64bit()
1228 ? Mips::GPR64RegClassID
1229 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1230 Inst.addOperand(MCOperand::createReg(
1231 RegIdx.RegInfo->getRegClass(
1232 AsmParser.getABI().AreGprs64bit()
1233 ? Mips::GPR64RegClassID
1234 : Mips::GPR32RegClassID).getRegister(RegNo)));
1237 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1238 assert(N == 2 && "Invalid number of operands!");
1239 for (auto RegNo : getRegList())
1240 Inst.addOperand(MCOperand::createReg(RegNo));
1243 bool isReg() const override {
1244 // As a special case until we sort out the definition of div/divu, accept
1245 // $0/$zero here so that MCK_ZERO works correctly.
1246 return isGPRAsmReg() && RegIdx.Index == 0;
1249 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1250 bool isImm() const override { return Kind == k_Immediate; }
1252 bool isConstantImm() const {
1254 return isImm() && getImm()->evaluateAsAbsolute(Res);
1257 bool isConstantImmz() const {
1258 return isConstantImm() && getConstantImm() == 0;
1261 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1262 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1265 template <unsigned Bits> bool isSImm() const {
1266 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1269 template <unsigned Bits> bool isUImm() const {
1270 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1273 template <unsigned Bits> bool isAnyImm() const {
1274 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1275 isUInt<Bits>(getConstantImm()))
1279 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1280 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1283 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1284 return isConstantImm() && getConstantImm() >= Bottom &&
1285 getConstantImm() <= Top;
1288 bool isToken() const override {
1289 // Note: It's not possible to pretend that other operand kinds are tokens.
1290 // The matcher emitter checks tokens first.
1291 return Kind == k_Token;
1294 bool isMem() const override { return Kind == k_Memory; }
1296 bool isConstantMemOff() const {
1297 return isMem() && isa<MCConstantExpr>(getMemOff());
1300 // Allow relocation operators.
1301 // FIXME: This predicate and others need to look through binary expressions
1302 // and determine whether a Value is a constant or not.
1303 template <unsigned Bits, unsigned ShiftAmount = 0>
1304 bool isMemWithSimmOffset() const {
1307 if (!getMemBase()->isGPRAsmReg())
1309 if (isa<MCTargetExpr>(getMemOff()) ||
1310 (isConstantMemOff() &&
1311 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1314 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1315 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1318 bool isMemWithPtrSizeOffset() const {
1321 if (!getMemBase()->isGPRAsmReg())
1323 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1324 if (isa<MCTargetExpr>(getMemOff()) ||
1325 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1328 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1329 return IsReloc && isIntN(PtrBits, Res.getConstant());
1332 bool isMemWithGRPMM16Base() const {
1333 return isMem() && getMemBase()->isMM16AsmReg();
1336 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1337 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1338 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1341 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1342 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1343 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1344 && (getMemBase()->getGPR32Reg() == Mips::SP);
1347 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1348 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1349 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1350 && (getMemBase()->getGPR32Reg() == Mips::GP);
1353 template <unsigned Bits, unsigned ShiftLeftAmount>
1354 bool isScaledUImm() const {
1355 return isConstantImm() &&
1356 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1359 template <unsigned Bits, unsigned ShiftLeftAmount>
1360 bool isScaledSImm() const {
1361 if (isConstantImm() &&
1362 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1364 // Operand can also be a symbol or symbol plus
1365 // offset in case of relocations.
1366 if (Kind != k_Immediate)
1369 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1370 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1373 bool isRegList16() const {
1377 int Size = RegList.List->size();
1378 if (Size < 2 || Size > 5)
1381 unsigned R0 = RegList.List->front();
1382 unsigned R1 = RegList.List->back();
1383 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1384 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1387 int PrevReg = *RegList.List->begin();
1388 for (int i = 1; i < Size - 1; i++) {
1389 int Reg = (*(RegList.List))[i];
1390 if ( Reg != PrevReg + 1)
1398 bool isInvNum() const { return Kind == k_Immediate; }
1400 bool isLSAImm() const {
1401 if (!isConstantImm())
1403 int64_t Val = getConstantImm();
1404 return 1 <= Val && Val <= 4;
1407 bool isRegList() const { return Kind == k_RegList; }
1409 bool isMovePRegPair() const {
1410 if (Kind != k_RegList || RegList.List->size() != 2)
1413 unsigned R0 = RegList.List->front();
1414 unsigned R1 = RegList.List->back();
1416 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1417 (R0 == Mips::A1 && R1 == Mips::A3) ||
1418 (R0 == Mips::A2 && R1 == Mips::A3) ||
1419 (R0 == Mips::A0 && R1 == Mips::S5) ||
1420 (R0 == Mips::A0 && R1 == Mips::S6) ||
1421 (R0 == Mips::A0 && R1 == Mips::A1) ||
1422 (R0 == Mips::A0 && R1 == Mips::A2) ||
1423 (R0 == Mips::A0 && R1 == Mips::A3) ||
1424 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1425 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1426 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1427 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1428 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1429 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1430 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1431 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1437 StringRef getToken() const {
1438 assert(Kind == k_Token && "Invalid access!");
1439 return StringRef(Tok.Data, Tok.Length);
1442 unsigned getReg() const override {
1443 // As a special case until we sort out the definition of div/divu, accept
1444 // $0/$zero here so that MCK_ZERO works correctly.
1445 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1446 RegIdx.Kind & RegKind_GPR)
1447 return getGPR32Reg(); // FIXME: GPR64 too
1449 llvm_unreachable("Invalid access!");
1453 const MCExpr *getImm() const {
1454 assert((Kind == k_Immediate) && "Invalid access!");
1458 int64_t getConstantImm() const {
1459 const MCExpr *Val = getImm();
1461 (void)Val->evaluateAsAbsolute(Value);
1465 MipsOperand *getMemBase() const {
1466 assert((Kind == k_Memory) && "Invalid access!");
1470 const MCExpr *getMemOff() const {
1471 assert((Kind == k_Memory) && "Invalid access!");
1475 int64_t getConstantMemOff() const {
1476 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1479 const SmallVectorImpl<unsigned> &getRegList() const {
1480 assert((Kind == k_RegList) && "Invalid access!");
1481 return *(RegList.List);
1484 unsigned getRegPair() const {
1485 assert((Kind == k_RegPair) && "Invalid access!");
1486 return RegIdx.Index;
1489 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1490 MipsAsmParser &Parser) {
1491 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1492 Op->Tok.Data = Str.data();
1493 Op->Tok.Length = Str.size();
1499 /// Create a numeric register (e.g. $1). The exact register remains
1500 /// unresolved until an instruction successfully matches
1501 static std::unique_ptr<MipsOperand>
1502 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1503 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1504 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1505 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1508 /// Create a register that is definitely a GPR.
1509 /// This is typically only used for named registers such as $gp.
1510 static std::unique_ptr<MipsOperand>
1511 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1512 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1513 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1516 /// Create a register that is definitely a FGR.
1517 /// This is typically only used for named registers such as $f0.
1518 static std::unique_ptr<MipsOperand>
1519 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1520 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1521 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1524 /// Create a register that is definitely a HWReg.
1525 /// This is typically only used for named registers such as $hwr_cpunum.
1526 static std::unique_ptr<MipsOperand>
1527 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1528 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1529 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1532 /// Create a register that is definitely an FCC.
1533 /// This is typically only used for named registers such as $fcc0.
1534 static std::unique_ptr<MipsOperand>
1535 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1536 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1537 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1540 /// Create a register that is definitely an ACC.
1541 /// This is typically only used for named registers such as $ac0.
1542 static std::unique_ptr<MipsOperand>
1543 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1544 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1545 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1548 /// Create a register that is definitely an MSA128.
1549 /// This is typically only used for named registers such as $w0.
1550 static std::unique_ptr<MipsOperand>
1551 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1552 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1553 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1556 /// Create a register that is definitely an MSACtrl.
1557 /// This is typically only used for named registers such as $msaaccess.
1558 static std::unique_ptr<MipsOperand>
1559 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1560 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1561 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1564 static std::unique_ptr<MipsOperand>
1565 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1566 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1573 static std::unique_ptr<MipsOperand>
1574 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1575 SMLoc E, MipsAsmParser &Parser) {
1576 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1577 Op->Mem.Base = Base.release();
1584 static std::unique_ptr<MipsOperand>
1585 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1586 MipsAsmParser &Parser) {
1587 assert(Regs.size() > 0 && "Empty list not allowed");
1589 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1590 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1591 Op->StartLoc = StartLoc;
1592 Op->EndLoc = EndLoc;
1596 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1598 MipsAsmParser &Parser) {
1599 auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
1600 Op->RegIdx.Index = MOP.RegIdx.Index;
1601 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1602 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1608 bool isGPRZeroAsmReg() const {
1609 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1612 bool isGPRNonZeroAsmReg() const {
1613 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1617 bool isGPRAsmReg() const {
1618 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1621 bool isMM16AsmReg() const {
1622 if (!(isRegIdx() && RegIdx.Kind))
1624 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1625 || RegIdx.Index == 16 || RegIdx.Index == 17);
1628 bool isMM16AsmRegZero() const {
1629 if (!(isRegIdx() && RegIdx.Kind))
1631 return (RegIdx.Index == 0 ||
1632 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1633 RegIdx.Index == 17);
1636 bool isMM16AsmRegMoveP() const {
1637 if (!(isRegIdx() && RegIdx.Kind))
1639 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1640 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1643 bool isFGRAsmReg() const {
1644 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1645 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1648 bool isStrictlyFGRAsmReg() const {
1649 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1650 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1653 bool isHWRegsAsmReg() const {
1654 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1657 bool isCCRAsmReg() const {
1658 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1661 bool isFCCAsmReg() const {
1662 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1664 return RegIdx.Index <= 7;
1667 bool isACCAsmReg() const {
1668 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1671 bool isCOP0AsmReg() const {
1672 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1675 bool isCOP2AsmReg() const {
1676 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1679 bool isCOP3AsmReg() const {
1680 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1683 bool isMSA128AsmReg() const {
1684 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1687 bool isMSACtrlAsmReg() const {
1688 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1691 /// getStartLoc - Get the location of the first token of this operand.
1692 SMLoc getStartLoc() const override { return StartLoc; }
1693 /// getEndLoc - Get the location of the last token of this operand.
1694 SMLoc getEndLoc() const override { return EndLoc; }
1696 void print(raw_ostream &OS) const override {
1705 Mem.Base->print(OS);
1710 case k_RegisterIndex:
1711 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1712 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1719 for (auto Reg : (*RegList.List))
1724 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1729 bool isValidForTie(const MipsOperand &Other) const {
1730 if (Kind != Other.Kind)
1735 llvm_unreachable("Unexpected kind");
1737 case k_RegisterIndex: {
1738 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1739 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1740 return Token == OtherToken;
1744 }; // class MipsOperand
1746 } // end anonymous namespace
1750 extern const MCInstrDesc MipsInsts[];
1752 } // end namespace llvm
1754 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1755 return MipsInsts[Opcode];
1758 static bool hasShortDelaySlot(unsigned Opcode) {
1761 case Mips::JALRS_MM:
1762 case Mips::JALRS16_MM:
1763 case Mips::BGEZALS_MM:
1764 case Mips::BLTZALS_MM:
1771 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1772 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1773 return &SRExpr->getSymbol();
1776 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1777 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1778 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1789 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1790 return getSingleMCSymbol(UExpr->getSubExpr());
1795 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1796 if (isa<MCSymbolRefExpr>(Expr))
1799 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1800 return countMCSymbolRefExpr(BExpr->getLHS()) +
1801 countMCSymbolRefExpr(BExpr->getRHS());
1803 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1804 return countMCSymbolRefExpr(UExpr->getSubExpr());
1809 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1811 const MCSubtargetInfo *STI) {
1812 MipsTargetStreamer &TOut = getTargetStreamer();
1813 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1814 bool ExpandedJalSym = false;
1818 if (MCID.isBranch() || MCID.isCall()) {
1819 const unsigned Opcode = Inst.getOpcode();
1829 assert(hasCnMips() && "instruction only valid for octeon cpus");
1836 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1837 Offset = Inst.getOperand(2);
1838 if (!Offset.isImm())
1839 break; // We'll deal with this situation later on when applying fixups.
1840 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1841 return Error(IDLoc, "branch target out of range");
1842 if (OffsetToAlignment(Offset.getImm(),
1843 1LL << (inMicroMipsMode() ? 1 : 2)))
1844 return Error(IDLoc, "branch to misaligned address");
1858 case Mips::BGEZAL_MM:
1859 case Mips::BLTZAL_MM:
1862 case Mips::BC1EQZC_MMR6:
1863 case Mips::BC1NEZC_MMR6:
1864 case Mips::BC2EQZC_MMR6:
1865 case Mips::BC2NEZC_MMR6:
1866 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1867 Offset = Inst.getOperand(1);
1868 if (!Offset.isImm())
1869 break; // We'll deal with this situation later on when applying fixups.
1870 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1871 return Error(IDLoc, "branch target out of range");
1872 if (OffsetToAlignment(Offset.getImm(),
1873 1LL << (inMicroMipsMode() ? 1 : 2)))
1874 return Error(IDLoc, "branch to misaligned address");
1876 case Mips::BGEC: case Mips::BGEC_MMR6:
1877 case Mips::BLTC: case Mips::BLTC_MMR6:
1878 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1879 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1880 case Mips::BEQC: case Mips::BEQC_MMR6:
1881 case Mips::BNEC: case Mips::BNEC_MMR6:
1882 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1883 Offset = Inst.getOperand(2);
1884 if (!Offset.isImm())
1885 break; // We'll deal with this situation later on when applying fixups.
1886 if (!isIntN(18, Offset.getImm()))
1887 return Error(IDLoc, "branch target out of range");
1888 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1889 return Error(IDLoc, "branch to misaligned address");
1891 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1892 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1893 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1894 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1895 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1896 Offset = Inst.getOperand(1);
1897 if (!Offset.isImm())
1898 break; // We'll deal with this situation later on when applying fixups.
1899 if (!isIntN(18, Offset.getImm()))
1900 return Error(IDLoc, "branch target out of range");
1901 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1902 return Error(IDLoc, "branch to misaligned address");
1904 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1905 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1906 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1907 Offset = Inst.getOperand(1);
1908 if (!Offset.isImm())
1909 break; // We'll deal with this situation later on when applying fixups.
1910 if (!isIntN(23, Offset.getImm()))
1911 return Error(IDLoc, "branch target out of range");
1912 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1913 return Error(IDLoc, "branch to misaligned address");
1915 case Mips::BEQZ16_MM:
1916 case Mips::BEQZC16_MMR6:
1917 case Mips::BNEZ16_MM:
1918 case Mips::BNEZC16_MMR6:
1919 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1920 Offset = Inst.getOperand(1);
1921 if (!Offset.isImm())
1922 break; // We'll deal with this situation later on when applying fixups.
1923 if (!isInt<8>(Offset.getImm()))
1924 return Error(IDLoc, "branch target out of range");
1925 if (OffsetToAlignment(Offset.getImm(), 2LL))
1926 return Error(IDLoc, "branch to misaligned address");
1931 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1932 // We still accept it but it is a normal nop.
1933 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1934 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1935 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1940 const unsigned Opcode = Inst.getOpcode();
1952 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1953 // The offset is handled above
1954 Opnd = Inst.getOperand(1);
1956 return Error(IDLoc, "expected immediate operand kind");
1957 Imm = Opnd.getImm();
1958 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1959 Opcode == Mips::BBIT1 ? 63 : 31))
1960 return Error(IDLoc, "immediate operand value out of range");
1962 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1964 Inst.getOperand(1).setImm(Imm - 32);
1970 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1971 Opnd = Inst.getOperand(2);
1973 return Error(IDLoc, "expected immediate operand kind");
1974 Imm = Opnd.getImm();
1975 if (!isInt<10>(Imm))
1976 return Error(IDLoc, "immediate operand value out of range");
1981 // Warn on division by zero. We're checking here as all instructions get
1982 // processed here, not just the macros that need expansion.
1984 // The MIPS backend models most of the divison instructions and macros as
1985 // three operand instructions. The pre-R6 divide instructions however have
1986 // two operands and explicitly define HI/LO as part of the instruction,
1987 // not in the operands.
1988 unsigned FirstOp = 1;
1989 unsigned SecondOp = 2;
1990 switch (Inst.getOpcode()) {
1993 case Mips::SDivIMacro:
1994 case Mips::UDivIMacro:
1995 case Mips::DSDivIMacro:
1996 case Mips::DUDivIMacro:
1997 if (Inst.getOperand(2).getImm() == 0) {
1998 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1999 Inst.getOperand(1).getReg() == Mips::ZERO_64)
2000 Warning(IDLoc, "dividing zero by zero");
2002 Warning(IDLoc, "division by zero");
2014 case Mips::SDivMacro:
2015 case Mips::DSDivMacro:
2016 case Mips::UDivMacro:
2017 case Mips::DUDivMacro:
2022 case Mips::DIVU_MMR6:
2023 case Mips::DIV_MMR6:
2024 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2025 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2026 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2027 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2028 Warning(IDLoc, "dividing zero by zero");
2030 Warning(IDLoc, "division by zero");
2035 // For PIC code convert unconditional jump to unconditional branch.
2036 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2039 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2040 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2041 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2042 BInst.addOperand(Inst.getOperand(0));
2046 // This expansion is not in a function called by tryExpandInstruction()
2047 // because the pseudo-instruction doesn't have a distinct opcode.
2048 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2050 warnIfNoMacro(IDLoc);
2052 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2054 // We can do this expansion if there's only 1 symbol in the argument
2056 if (countMCSymbolRefExpr(JalExpr) > 1)
2057 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2059 // FIXME: This is checking the expression can be handled by the later stages
2060 // of the assembler. We ought to leave it to those later stages.
2061 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2063 // FIXME: Add support for label+offset operands (currently causes an error).
2064 // FIXME: Add support for forward-declared local symbols.
2065 // FIXME: Add expansion for when the LargeGOT option is enabled.
2066 if (JalSym->isInSection() || JalSym->isTemporary() ||
2068 cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2070 // If it's a local symbol and the O32 ABI is being used, we expand to:
2072 // R_(MICRO)MIPS_GOT16 label
2073 // addiu $25, $25, 0
2074 // R_(MICRO)MIPS_LO16 label
2076 const MCExpr *Got16RelocExpr =
2077 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2078 const MCExpr *Lo16RelocExpr =
2079 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2081 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2082 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2083 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2084 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2085 } else if (isABI_N32() || isABI_N64()) {
2086 // If it's a local symbol and the N32/N64 ABIs are being used,
2088 // lw/ld $25, 0($gp)
2089 // R_(MICRO)MIPS_GOT_DISP label
2091 const MCExpr *GotDispRelocExpr =
2092 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2094 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2095 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2099 // If it's an external/weak symbol, we expand to:
2100 // lw/ld $25, 0($gp)
2101 // R_(MICRO)MIPS_CALL16 label
2103 const MCExpr *Call16RelocExpr =
2104 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2106 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2107 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2111 if (IsCpRestoreSet && inMicroMipsMode())
2112 JalrInst.setOpcode(Mips::JALRS_MM);
2114 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2115 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2116 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2118 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
2119 // This relocation is supposed to be an optimization hint for the linker
2120 // and is not necessary for correctness.
2123 ExpandedJalSym = true;
2126 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2127 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2128 // Check the offset of memory operand, if it is a symbol
2129 // reference or immediate we may have to expand instructions.
2130 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2131 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2132 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2133 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2134 MCOperand &Op = Inst.getOperand(i);
2136 int64_t MemOffset = Op.getImm();
2137 if (MemOffset < -32768 || MemOffset > 32767) {
2138 // Offset can't exceed 16bit value.
2139 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2140 return getParser().hasPendingError();
2142 } else if (Op.isExpr()) {
2143 const MCExpr *Expr = Op.getExpr();
2144 if (Expr->getKind() == MCExpr::SymbolRef) {
2145 const MCSymbolRefExpr *SR =
2146 static_cast<const MCSymbolRefExpr *>(Expr);
2147 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2149 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2150 return getParser().hasPendingError();
2152 } else if (!isEvaluated(Expr)) {
2153 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2154 return getParser().hasPendingError();
2161 if (inMicroMipsMode()) {
2162 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2163 // Try to create 16-bit GP relative load instruction.
2164 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2165 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2166 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2167 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2168 MCOperand &Op = Inst.getOperand(i);
2170 int MemOffset = Op.getImm();
2171 MCOperand &DstReg = Inst.getOperand(0);
2172 MCOperand &BaseReg = Inst.getOperand(1);
2173 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2174 getContext().getRegisterInfo()->getRegClass(
2175 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2176 (BaseReg.getReg() == Mips::GP ||
2177 BaseReg.getReg() == Mips::GP_64)) {
2179 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2188 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2193 switch (Inst.getOpcode()) {
2196 case Mips::ADDIUSP_MM:
2197 Opnd = Inst.getOperand(0);
2199 return Error(IDLoc, "expected immediate operand kind");
2200 Imm = Opnd.getImm();
2201 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2203 return Error(IDLoc, "immediate operand value out of range");
2205 case Mips::SLL16_MM:
2206 case Mips::SRL16_MM:
2207 Opnd = Inst.getOperand(2);
2209 return Error(IDLoc, "expected immediate operand kind");
2210 Imm = Opnd.getImm();
2211 if (Imm < 1 || Imm > 8)
2212 return Error(IDLoc, "immediate operand value out of range");
2215 Opnd = Inst.getOperand(1);
2217 return Error(IDLoc, "expected immediate operand kind");
2218 Imm = Opnd.getImm();
2219 if (Imm < -1 || Imm > 126)
2220 return Error(IDLoc, "immediate operand value out of range");
2222 case Mips::ADDIUR2_MM:
2223 Opnd = Inst.getOperand(2);
2225 return Error(IDLoc, "expected immediate operand kind");
2226 Imm = Opnd.getImm();
2227 if (!(Imm == 1 || Imm == -1 ||
2228 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2229 return Error(IDLoc, "immediate operand value out of range");
2231 case Mips::ANDI16_MM:
2232 Opnd = Inst.getOperand(2);
2234 return Error(IDLoc, "expected immediate operand kind");
2235 Imm = Opnd.getImm();
2236 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2237 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2238 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2239 return Error(IDLoc, "immediate operand value out of range");
2241 case Mips::LBU16_MM:
2242 Opnd = Inst.getOperand(2);
2244 return Error(IDLoc, "expected immediate operand kind");
2245 Imm = Opnd.getImm();
2246 if (Imm < -1 || Imm > 14)
2247 return Error(IDLoc, "immediate operand value out of range");
2250 case Mips::SB16_MMR6:
2251 Opnd = Inst.getOperand(2);
2253 return Error(IDLoc, "expected immediate operand kind");
2254 Imm = Opnd.getImm();
2255 if (Imm < 0 || Imm > 15)
2256 return Error(IDLoc, "immediate operand value out of range");
2258 case Mips::LHU16_MM:
2260 case Mips::SH16_MMR6:
2261 Opnd = Inst.getOperand(2);
2263 return Error(IDLoc, "expected immediate operand kind");
2264 Imm = Opnd.getImm();
2265 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2266 return Error(IDLoc, "immediate operand value out of range");
2270 case Mips::SW16_MMR6:
2271 Opnd = Inst.getOperand(2);
2273 return Error(IDLoc, "expected immediate operand kind");
2274 Imm = Opnd.getImm();
2275 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2276 return Error(IDLoc, "immediate operand value out of range");
2278 case Mips::ADDIUPC_MM:
2279 Opnd = Inst.getOperand(1);
2281 return Error(IDLoc, "expected immediate operand kind");
2282 Imm = Opnd.getImm();
2283 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2284 return Error(IDLoc, "immediate operand value out of range");
2288 if (Inst.getOperand(0).getReg() == Mips::RA)
2289 return Error(IDLoc, "invalid operand for instruction");
2294 bool FillDelaySlot =
2295 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2297 TOut.emitDirectiveSetNoReorder();
2299 MacroExpanderResultTy ExpandResult =
2300 tryExpandInstruction(Inst, IDLoc, Out, STI);
2301 switch (ExpandResult) {
2303 Out.EmitInstruction(Inst, *STI);
2311 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2312 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2313 if (inMicroMipsMode()) {
2314 TOut.setUsesMicroMips();
2315 TOut.updateABIInfo(*this);
2318 // If this instruction has a delay slot and .set reorder is active,
2319 // emit a NOP after it.
2320 if (FillDelaySlot) {
2321 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2322 TOut.emitDirectiveSetReorder();
2325 if ((Inst.getOpcode() == Mips::JalOneReg ||
2326 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2327 isPicAndNotNxxAbi()) {
2328 if (IsCpRestoreSet) {
2329 // We need a NOP between the JALR and the LW:
2330 // If .set reorder has been used, we've already emitted a NOP.
2331 // If .set noreorder has been used, we need to emit a NOP at this point.
2332 if (!AssemblerOptions.back()->isReorder())
2333 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2336 // Load the $gp from the stack.
2337 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2339 Warning(IDLoc, "no .cprestore used in PIC mode");
2345 MipsAsmParser::MacroExpanderResultTy
2346 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2347 const MCSubtargetInfo *STI) {
2348 switch (Inst.getOpcode()) {
2350 return MER_NotAMacro;
2351 case Mips::LoadImm32:
2352 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2353 case Mips::LoadImm64:
2354 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2355 case Mips::LoadAddrImm32:
2356 case Mips::LoadAddrImm64:
2357 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2358 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2359 "expected immediate operand kind");
2361 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2363 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2367 case Mips::LoadAddrReg32:
2368 case Mips::LoadAddrReg64:
2369 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2370 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2371 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2372 "expected immediate operand kind");
2374 return expandLoadAddress(Inst.getOperand(0).getReg(),
2375 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2376 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2380 case Mips::B_MM_Pseudo:
2381 case Mips::B_MMR6_Pseudo:
2382 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2386 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2388 case Mips::JalOneReg:
2389 case Mips::JalTwoReg:
2390 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2393 case Mips::BEQLImmMacro:
2394 case Mips::BNELImmMacro:
2395 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2412 case Mips::BLTImmMacro:
2413 case Mips::BLEImmMacro:
2414 case Mips::BGEImmMacro:
2415 case Mips::BGTImmMacro:
2416 case Mips::BLTUImmMacro:
2417 case Mips::BLEUImmMacro:
2418 case Mips::BGEUImmMacro:
2419 case Mips::BGTUImmMacro:
2420 case Mips::BLTLImmMacro:
2421 case Mips::BLELImmMacro:
2422 case Mips::BGELImmMacro:
2423 case Mips::BGTLImmMacro:
2424 case Mips::BLTULImmMacro:
2425 case Mips::BLEULImmMacro:
2426 case Mips::BGEULImmMacro:
2427 case Mips::BGTULImmMacro:
2428 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2429 case Mips::SDivMacro:
2430 case Mips::SDivIMacro:
2431 case Mips::SRemMacro:
2432 case Mips::SRemIMacro:
2433 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2435 case Mips::DSDivMacro:
2436 case Mips::DSDivIMacro:
2437 case Mips::DSRemMacro:
2438 case Mips::DSRemIMacro:
2439 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2441 case Mips::UDivMacro:
2442 case Mips::UDivIMacro:
2443 case Mips::URemMacro:
2444 case Mips::URemIMacro:
2445 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2447 case Mips::DUDivMacro:
2448 case Mips::DUDivIMacro:
2449 case Mips::DURemMacro:
2450 case Mips::DURemIMacro:
2451 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2453 case Mips::PseudoTRUNC_W_S:
2454 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2456 case Mips::PseudoTRUNC_W_D32:
2457 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2459 case Mips::PseudoTRUNC_W_D:
2460 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2463 case Mips::LoadImmSingleGPR:
2464 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2467 case Mips::LoadImmSingleFGR:
2468 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2471 case Mips::LoadImmDoubleGPR:
2472 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2475 case Mips::LoadImmDoubleFGR:
2476 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2479 case Mips::LoadImmDoubleFGR_32:
2480 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2484 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2486 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2488 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2491 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 case Mips::NORImm64:
2494 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2495 case Mips::SLTImm64:
2496 if (isInt<16>(Inst.getOperand(2).getImm())) {
2497 Inst.setOpcode(Mips::SLTi64);
2498 return MER_NotAMacro;
2500 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2501 case Mips::SLTUImm64:
2502 if (isInt<16>(Inst.getOperand(2).getImm())) {
2503 Inst.setOpcode(Mips::SLTiu64);
2504 return MER_NotAMacro;
2506 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2507 case Mips::ADDi: case Mips::ADDi_MM:
2508 case Mips::ADDiu: case Mips::ADDiu_MM:
2509 case Mips::SLTi: case Mips::SLTi_MM:
2510 case Mips::SLTiu: case Mips::SLTiu_MM:
2511 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2512 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2513 int64_t ImmValue = Inst.getOperand(2).getImm();
2514 if (isInt<16>(ImmValue))
2515 return MER_NotAMacro;
2516 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2519 return MER_NotAMacro;
2520 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2521 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2522 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2523 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2524 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2525 int64_t ImmValue = Inst.getOperand(2).getImm();
2526 if (isUInt<16>(ImmValue))
2527 return MER_NotAMacro;
2528 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2531 return MER_NotAMacro;
2534 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2540 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2544 case Mips::ABSMacro:
2545 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2546 case Mips::MULImmMacro:
2547 case Mips::DMULImmMacro:
2548 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 case Mips::MULOMacro:
2550 case Mips::DMULOMacro:
2551 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 case Mips::MULOUMacro:
2553 case Mips::DMULOUMacro:
2554 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::DMULMacro:
2556 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2559 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2560 Inst.getOpcode() == Mips::LDMacro)
2563 case Mips::SEQMacro:
2564 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 case Mips::SEQIMacro:
2566 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2567 case Mips::MFTC0: case Mips::MTTC0:
2568 case Mips::MFTGPR: case Mips::MTTGPR:
2569 case Mips::MFTLO: case Mips::MTTLO:
2570 case Mips::MFTHI: case Mips::MTTHI:
2571 case Mips::MFTACX: case Mips::MTTACX:
2572 case Mips::MFTDSP: case Mips::MTTDSP:
2573 case Mips::MFTC1: case Mips::MTTC1:
2574 case Mips::MFTHC1: case Mips::MTTHC1:
2575 case Mips::CFTC1: case Mips::CTTC1:
2576 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2580 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2582 const MCSubtargetInfo *STI) {
2583 MipsTargetStreamer &TOut = getTargetStreamer();
2585 // Create a JALR instruction which is going to replace the pseudo-JAL.
2587 JalrInst.setLoc(IDLoc);
2588 const MCOperand FirstRegOp = Inst.getOperand(0);
2589 const unsigned Opcode = Inst.getOpcode();
2591 if (Opcode == Mips::JalOneReg) {
2592 // jal $rs => jalr $rs
2593 if (IsCpRestoreSet && inMicroMipsMode()) {
2594 JalrInst.setOpcode(Mips::JALRS16_MM);
2595 JalrInst.addOperand(FirstRegOp);
2596 } else if (inMicroMipsMode()) {
2597 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2598 JalrInst.addOperand(FirstRegOp);
2600 JalrInst.setOpcode(Mips::JALR);
2601 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2602 JalrInst.addOperand(FirstRegOp);
2604 } else if (Opcode == Mips::JalTwoReg) {
2605 // jal $rd, $rs => jalr $rd, $rs
2606 if (IsCpRestoreSet && inMicroMipsMode())
2607 JalrInst.setOpcode(Mips::JALRS_MM);
2609 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2610 JalrInst.addOperand(FirstRegOp);
2611 const MCOperand SecondRegOp = Inst.getOperand(1);
2612 JalrInst.addOperand(SecondRegOp);
2614 Out.EmitInstruction(JalrInst, *STI);
2616 // If .set reorder is active and branch instruction has a delay slot,
2617 // emit a NOP after it.
2618 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2619 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2620 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2626 /// Can the value be represented by a unsigned N-bit value and a shift left?
2627 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2628 unsigned BitNum = findFirstSet(x);
2630 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2633 /// Load (or add) an immediate into a register.
2635 /// @param ImmValue The immediate to load.
2636 /// @param DstReg The register that will hold the immediate.
2637 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2638 /// for a simple initialization.
2639 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2640 /// @param IsAddress True if the immediate represents an address. False if it
2642 /// @param IDLoc Location of the immediate in the source file.
2643 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2644 unsigned SrcReg, bool Is32BitImm,
2645 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2646 const MCSubtargetInfo *STI) {
2647 MipsTargetStreamer &TOut = getTargetStreamer();
2649 if (!Is32BitImm && !isGP64bit()) {
2650 Error(IDLoc, "instruction requires a 64-bit architecture");
2655 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2656 // Sign extend up to 64-bit so that the predicates match the hardware
2657 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2659 ImmValue = SignExtend64<32>(ImmValue);
2661 Error(IDLoc, "instruction requires a 32-bit immediate");
2666 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2667 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2669 bool UseSrcReg = false;
2670 if (SrcReg != Mips::NoRegister)
2673 unsigned TmpReg = DstReg;
2675 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2676 // At this point we need AT to perform the expansions and we exit if it is
2678 unsigned ATReg = getATReg(IDLoc);
2684 if (isInt<16>(ImmValue)) {
2688 // This doesn't quite follow the usual ABI expectations for N32 but matches
2689 // traditional assembler behaviour. N32 would normally use addiu for both
2690 // integers and addresses.
2691 if (IsAddress && !Is32BitImm) {
2692 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2696 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2700 if (isUInt<16>(ImmValue)) {
2701 unsigned TmpReg = DstReg;
2702 if (SrcReg == DstReg) {
2703 TmpReg = getATReg(IDLoc);
2708 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2710 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2714 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2715 warnIfNoMacro(IDLoc);
2717 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2718 uint16_t Bits15To0 = ImmValue & 0xffff;
2719 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2720 // Traditional behaviour seems to special case this particular value. It's
2721 // not clear why other masks are handled differently.
2722 if (ImmValue == 0xffffffff) {
2723 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2724 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2726 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2730 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2732 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2733 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2735 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2737 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2741 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2743 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2745 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2749 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2751 Error(IDLoc, "instruction requires a 32-bit immediate");
2755 // Traditionally, these immediates are shifted as little as possible and as
2756 // such we align the most significant bit to bit 15 of our temporary.
2757 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2758 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2759 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2760 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2761 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2762 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2765 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2770 warnIfNoMacro(IDLoc);
2772 // The remaining case is packed with a sequence of dsll and ori with zeros
2773 // being omitted and any neighbouring dsll's being coalesced.
2774 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2776 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2777 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2781 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2782 // skip it and defer the shift to the next chunk.
2783 unsigned ShiftCarriedForwards = 16;
2784 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2785 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2787 if (ImmChunk != 0) {
2788 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2789 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2790 ShiftCarriedForwards = 0;
2793 ShiftCarriedForwards += 16;
2795 ShiftCarriedForwards -= 16;
2797 // Finish any remaining shifts left by trailing zeros.
2798 if (ShiftCarriedForwards)
2799 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2802 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2807 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2808 MCStreamer &Out, const MCSubtargetInfo *STI) {
2809 const MCOperand &ImmOp = Inst.getOperand(1);
2810 assert(ImmOp.isImm() && "expected immediate operand kind");
2811 const MCOperand &DstRegOp = Inst.getOperand(0);
2812 assert(DstRegOp.isReg() && "expected register operand kind");
2814 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2815 Is32BitImm, false, IDLoc, Out, STI))
2821 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2822 const MCOperand &Offset,
2823 bool Is32BitAddress, SMLoc IDLoc,
2825 const MCSubtargetInfo *STI) {
2826 // la can't produce a usable address when addresses are 64-bit.
2827 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2828 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2829 // We currently can't do this because we depend on the equality
2830 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2831 Error(IDLoc, "la used to load 64-bit address");
2832 // Continue as if we had 'dla' instead.
2833 Is32BitAddress = false;
2837 // dla requires 64-bit addresses.
2838 if (!Is32BitAddress && !hasMips3()) {
2839 Error(IDLoc, "instruction requires a 64-bit architecture");
2843 if (!Offset.isImm())
2844 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2845 Is32BitAddress, IDLoc, Out, STI);
2847 if (!ABI.ArePtrs64bit()) {
2848 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2849 Is32BitAddress = true;
2852 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2856 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2857 unsigned DstReg, unsigned SrcReg,
2858 bool Is32BitSym, SMLoc IDLoc,
2860 const MCSubtargetInfo *STI) {
2861 // FIXME: These expansions do not respect -mxgot.
2862 MipsTargetStreamer &TOut = getTargetStreamer();
2863 bool UseSrcReg = SrcReg != Mips::NoRegister;
2864 warnIfNoMacro(IDLoc);
2866 if (inPicMode() && ABI.IsO32()) {
2868 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2869 Error(IDLoc, "expected relocatable expression");
2872 if (Res.getSymB() != nullptr) {
2873 Error(IDLoc, "expected relocatable expression with only one symbol");
2877 // The case where the result register is $25 is somewhat special. If the
2878 // symbol in the final relocation is external and not modified with a
2879 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2880 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2881 Res.getConstant() == 0 &&
2882 !(Res.getSymA()->getSymbol().isInSection() ||
2883 Res.getSymA()->getSymbol().isTemporary() ||
2884 (Res.getSymA()->getSymbol().isELF() &&
2885 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2887 const MCExpr *CallExpr =
2888 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2889 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2890 MCOperand::createExpr(CallExpr), IDLoc, STI);
2894 // The remaining cases are:
2895 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2896 // >addiu $tmp, $tmp, %lo(offset)
2897 // >addiu $rd, $tmp, $rs
2898 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2899 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2900 // >addiu $rd, $tmp, $rs
2901 // The addiu's marked with a '>' may be omitted if they are redundant. If
2902 // this happens then the last instruction must use $rd as the result
2904 const MipsMCExpr *GotExpr =
2905 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2906 const MCExpr *LoExpr = nullptr;
2907 if (Res.getSymA()->getSymbol().isInSection() ||
2908 Res.getSymA()->getSymbol().isTemporary())
2909 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2910 else if (Res.getConstant() != 0) {
2911 // External symbols fully resolve the symbol with just the %got(symbol)
2912 // but we must still account for any offset to the symbol for expressions
2914 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2917 unsigned TmpReg = DstReg;
2919 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2921 // If $rs is the same as $rd, we need to use AT.
2922 // If it is not available we exit.
2923 unsigned ATReg = getATReg(IDLoc);
2929 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2930 MCOperand::createExpr(GotExpr), IDLoc, STI);
2933 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2937 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2942 if (inPicMode() && ABI.ArePtrs64bit()) {
2944 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2945 Error(IDLoc, "expected relocatable expression");
2948 if (Res.getSymB() != nullptr) {
2949 Error(IDLoc, "expected relocatable expression with only one symbol");
2953 // The case where the result register is $25 is somewhat special. If the
2954 // symbol in the final relocation is external and not modified with a
2955 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2956 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2957 Res.getConstant() == 0 &&
2958 !(Res.getSymA()->getSymbol().isInSection() ||
2959 Res.getSymA()->getSymbol().isTemporary() ||
2960 (Res.getSymA()->getSymbol().isELF() &&
2961 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2963 const MCExpr *CallExpr =
2964 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2965 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2966 MCOperand::createExpr(CallExpr), IDLoc, STI);
2970 // The remaining cases are:
2971 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2972 // >daddiu $tmp, $tmp, offset
2973 // >daddu $rd, $tmp, $rs
2974 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2975 // this happens then the last instruction must use $rd as the result
2977 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2980 const MCExpr *LoExpr = nullptr;
2981 if (Res.getConstant() != 0) {
2982 // Symbols fully resolve with just the %got_disp(symbol) but we
2983 // must still account for any offset to the symbol for
2984 // expressions like symbol+8.
2985 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2987 // FIXME: Offsets greater than 16 bits are not yet implemented.
2988 // FIXME: The correct range is a 32-bit sign-extended number.
2989 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2990 Error(IDLoc, "macro instruction uses large offset, which is not "
2991 "currently supported");
2996 unsigned TmpReg = DstReg;
2998 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3000 // If $rs is the same as $rd, we need to use AT.
3001 // If it is not available we exit.
3002 unsigned ATReg = getATReg(IDLoc);
3008 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
3009 MCOperand::createExpr(GotExpr), IDLoc, STI);
3012 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3016 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3021 const MipsMCExpr *HiExpr =
3022 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3023 const MipsMCExpr *LoExpr =
3024 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3026 // This is the 64-bit symbol address expansion.
3027 if (ABI.ArePtrs64bit() && isGP64bit()) {
3028 // We need AT for the 64-bit expansion in the cases where the optional
3029 // source register is the destination register and for the superscalar
3032 // If it is not available we exit if the destination is the same as the
3035 const MipsMCExpr *HighestExpr =
3036 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3037 const MipsMCExpr *HigherExpr =
3038 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3041 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3043 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3044 unsigned ATReg = getATReg(IDLoc);
3046 // If $rs is the same as $rd:
3047 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3048 // daddiu $at, $at, %higher(sym)
3049 // dsll $at, $at, 16
3050 // daddiu $at, $at, %hi(sym)
3051 // dsll $at, $at, 16
3052 // daddiu $at, $at, %lo(sym)
3053 // daddu $rd, $at, $rd
3054 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3056 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3057 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3058 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3059 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3061 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3062 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3064 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3067 } else if (canUseATReg() && !RdRegIsRsReg) {
3068 unsigned ATReg = getATReg(IDLoc);
3070 // If the $rs is different from $rd or if $rs isn't specified and we
3071 // have $at available:
3072 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3073 // lui $at, %hi(sym)
3074 // daddiu $rd, $rd, %higher(sym)
3075 // daddiu $at, $at, %lo(sym)
3076 // dsll32 $rd, $rd, 0
3077 // daddu $rd, $rd, $at
3078 // (daddu $rd, $rd, $rs)
3080 // Which is preferred for superscalar issue.
3081 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3083 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3084 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3085 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3086 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3088 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3089 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3091 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3094 } else if (!canUseATReg() && !RdRegIsRsReg) {
3095 // Otherwise, synthesize the address in the destination register
3097 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3098 // daddiu $rd, $rd, %higher(sym)
3099 // dsll $rd, $rd, 16
3100 // daddiu $rd, $rd, %hi(sym)
3101 // dsll $rd, $rd, 16
3102 // daddiu $rd, $rd, %lo(sym)
3103 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3105 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3106 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3107 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3108 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3109 MCOperand::createExpr(HiExpr), IDLoc, STI);
3110 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3111 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3112 MCOperand::createExpr(LoExpr), IDLoc, STI);
3114 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3118 // We have a case where SrcReg == DstReg and we don't have $at
3119 // available. We can't expand this case, so error out appropriately.
3120 assert(SrcReg == DstReg && !canUseATReg() &&
3121 "Could have expanded dla but didn't?");
3122 reportParseError(IDLoc,
3123 "pseudo-instruction requires $at, which is not available");
3128 // And now, the 32-bit symbol address expansion:
3129 // If $rs is the same as $rd:
3130 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3131 // ori $at, $at, %lo(sym)
3132 // addu $rd, $at, $rd
3133 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3134 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3135 // ori $rd, $rd, %lo(sym)
3136 // (addu $rd, $rd, $rs)
3137 unsigned TmpReg = DstReg;
3139 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3140 // If $rs is the same as $rd, we need to use AT.
3141 // If it is not available we exit.
3142 unsigned ATReg = getATReg(IDLoc);
3148 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3149 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3153 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3156 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3161 // Each double-precision register DO-D15 overlaps with two of the single
3162 // precision registers F0-F31. As an example, all of the following hold true:
3163 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3164 static unsigned nextReg(unsigned Reg) {
3165 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3166 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3168 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3169 case Mips::ZERO: return Mips::AT;
3170 case Mips::AT: return Mips::V0;
3171 case Mips::V0: return Mips::V1;
3172 case Mips::V1: return Mips::A0;
3173 case Mips::A0: return Mips::A1;
3174 case Mips::A1: return Mips::A2;
3175 case Mips::A2: return Mips::A3;
3176 case Mips::A3: return Mips::T0;
3177 case Mips::T0: return Mips::T1;
3178 case Mips::T1: return Mips::T2;
3179 case Mips::T2: return Mips::T3;
3180 case Mips::T3: return Mips::T4;
3181 case Mips::T4: return Mips::T5;
3182 case Mips::T5: return Mips::T6;
3183 case Mips::T6: return Mips::T7;
3184 case Mips::T7: return Mips::S0;
3185 case Mips::S0: return Mips::S1;
3186 case Mips::S1: return Mips::S2;
3187 case Mips::S2: return Mips::S3;
3188 case Mips::S3: return Mips::S4;
3189 case Mips::S4: return Mips::S5;
3190 case Mips::S5: return Mips::S6;
3191 case Mips::S6: return Mips::S7;
3192 case Mips::S7: return Mips::T8;
3193 case Mips::T8: return Mips::T9;
3194 case Mips::T9: return Mips::K0;
3195 case Mips::K0: return Mips::K1;
3196 case Mips::K1: return Mips::GP;
3197 case Mips::GP: return Mips::SP;
3198 case Mips::SP: return Mips::FP;
3199 case Mips::FP: return Mips::RA;
3200 case Mips::RA: return Mips::ZERO;
3201 case Mips::D0: return Mips::F1;
3202 case Mips::D1: return Mips::F3;
3203 case Mips::D2: return Mips::F5;
3204 case Mips::D3: return Mips::F7;
3205 case Mips::D4: return Mips::F9;
3206 case Mips::D5: return Mips::F11;
3207 case Mips::D6: return Mips::F13;
3208 case Mips::D7: return Mips::F15;
3209 case Mips::D8: return Mips::F17;
3210 case Mips::D9: return Mips::F19;
3211 case Mips::D10: return Mips::F21;
3212 case Mips::D11: return Mips::F23;
3213 case Mips::D12: return Mips::F25;
3214 case Mips::D13: return Mips::F27;
3215 case Mips::D14: return Mips::F29;
3216 case Mips::D15: return Mips::F31;
3220 // FIXME: This method is too general. In principle we should compute the number
3221 // of instructions required to synthesize the immediate inline compared to
3222 // synthesizing the address inline and relying on non .text sections.
3223 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3224 // likely to yield a much larger benefit as we have to synthesize a 64bit
3225 // address to load a 64 bit value.
3226 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3228 unsigned ATReg = getATReg(IDLoc);
3233 const MCExpr *GotSym =
3234 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3235 const MipsMCExpr *GotExpr =
3236 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3238 if(isABI_O32() || isABI_N32()) {
3239 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3241 } else { //isABI_N64()
3242 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3245 } else { //!IsPicEnabled
3246 const MCExpr *HiSym =
3247 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3248 const MipsMCExpr *HiExpr =
3249 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3251 // FIXME: This is technically correct but gives a different result to gas,
3252 // but gas is incomplete there (it has a fixme noting it doesn't work with
3253 // 64-bit addresses).
3254 // FIXME: With -msym32 option, the address expansion for N64 should probably
3255 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3256 // symbol's value is considered sign extended.
3257 if(isABI_O32() || isABI_N32()) {
3258 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3259 } else { //isABI_N64()
3260 const MCExpr *HighestSym =
3261 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3262 const MipsMCExpr *HighestExpr =
3263 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3264 const MCExpr *HigherSym =
3265 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3266 const MipsMCExpr *HigherExpr =
3267 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3269 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3271 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3272 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3273 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3274 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3276 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3282 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3283 bool Is64FPU, SMLoc IDLoc,
3285 const MCSubtargetInfo *STI) {
3286 MipsTargetStreamer &TOut = getTargetStreamer();
3287 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3288 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3289 "Invalid instruction operand.");
3291 unsigned FirstReg = Inst.getOperand(0).getReg();
3292 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3294 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3295 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3296 // exponent field), convert it to double (e.g. 1 to 1.0)
3297 if ((HiImmOp64 & 0x7ff00000) == 0) {
3298 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3299 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3302 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3303 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3306 // Conversion of a double in an uint64_t to a float in a uint32_t,
3307 // retaining the bit pattern of a float.
3309 double doubleImm = BitsToDouble(ImmOp64);
3310 float tmp_float = static_cast<float>(doubleImm);
3311 ImmOp32 = FloatToBits(tmp_float);
3314 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3319 unsigned ATReg = getATReg(IDLoc);
3322 if (LoImmOp64 == 0) {
3323 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3326 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3330 MCSection *CS = getStreamer().getCurrentSectionOnly();
3331 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3332 // where appropriate.
3333 MCSection *ReadOnlySection = getContext().getELFSection(
3334 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3336 MCSymbol *Sym = getContext().createTempSymbol();
3337 const MCExpr *LoSym =
3338 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3339 const MipsMCExpr *LoExpr =
3340 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3342 getStreamer().SwitchSection(ReadOnlySection);
3343 getStreamer().EmitLabel(Sym, IDLoc);
3344 getStreamer().EmitIntValue(ImmOp32, 4);
3345 getStreamer().SwitchSection(CS);
3347 if(emitPartialAddress(TOut, IDLoc, Sym))
3349 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3350 MCOperand::createExpr(LoExpr), IDLoc, STI);
3356 unsigned ATReg = getATReg(IDLoc);
3361 if (LoImmOp64 == 0) {
3362 if(isABI_N32() || isABI_N64()) {
3363 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3368 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3372 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3379 MCSection *CS = getStreamer().getCurrentSectionOnly();
3380 MCSection *ReadOnlySection = getContext().getELFSection(
3381 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3383 MCSymbol *Sym = getContext().createTempSymbol();
3384 const MCExpr *LoSym =
3385 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3386 const MipsMCExpr *LoExpr =
3387 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3389 getStreamer().SwitchSection(ReadOnlySection);
3390 getStreamer().EmitLabel(Sym, IDLoc);
3391 getStreamer().EmitIntValue(HiImmOp64, 4);
3392 getStreamer().EmitIntValue(LoImmOp64, 4);
3393 getStreamer().SwitchSection(CS);
3395 if(emitPartialAddress(TOut, IDLoc, Sym))
3398 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3399 MCOperand::createExpr(LoExpr), IDLoc, STI);
3401 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3402 MCOperand::createExpr(LoExpr), IDLoc, STI);
3404 if(isABI_N32() || isABI_N64())
3405 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3407 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3408 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3411 } else { // if(!IsGPR && !IsSingle)
3412 if ((LoImmOp64 == 0) &&
3413 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3414 // FIXME: In the case where the constant is zero, we can load the
3415 // register directly from the zero register.
3416 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3419 if (isABI_N32() || isABI_N64())
3420 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3421 else if (hasMips32r2()) {
3422 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3423 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3425 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3426 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3431 MCSection *CS = getStreamer().getCurrentSectionOnly();
3432 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3433 // where appropriate.
3434 MCSection *ReadOnlySection = getContext().getELFSection(
3435 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3437 MCSymbol *Sym = getContext().createTempSymbol();
3438 const MCExpr *LoSym =
3439 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3440 const MipsMCExpr *LoExpr =
3441 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3443 getStreamer().SwitchSection(ReadOnlySection);
3444 getStreamer().EmitLabel(Sym, IDLoc);
3445 getStreamer().EmitIntValue(HiImmOp64, 4);
3446 getStreamer().EmitIntValue(LoImmOp64, 4);
3447 getStreamer().SwitchSection(CS);
3449 if(emitPartialAddress(TOut, IDLoc, Sym))
3451 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3452 MCOperand::createExpr(LoExpr), IDLoc, STI);
3457 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3459 const MCSubtargetInfo *STI) {
3460 MipsTargetStreamer &TOut = getTargetStreamer();
3462 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3463 "unexpected number of operands");
3465 MCOperand Offset = Inst.getOperand(0);
3466 if (Offset.isExpr()) {
3468 Inst.setOpcode(Mips::BEQ_MM);
3469 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3470 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3471 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3473 assert(Offset.isImm() && "expected immediate operand kind");
3474 if (isInt<11>(Offset.getImm())) {
3475 // If offset fits into 11 bits then this instruction becomes microMIPS
3476 // 16-bit unconditional branch instruction.
3477 if (inMicroMipsMode())
3478 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3480 if (!isInt<17>(Offset.getImm()))
3481 return Error(IDLoc, "branch target out of range");
3482 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3483 return Error(IDLoc, "branch to misaligned address");
3485 Inst.setOpcode(Mips::BEQ_MM);
3486 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3487 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3488 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3491 Out.EmitInstruction(Inst, *STI);
3493 // If .set reorder is active and branch instruction has a delay slot,
3494 // emit a NOP after it.
3495 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3496 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3497 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3502 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3503 const MCSubtargetInfo *STI) {
3504 MipsTargetStreamer &TOut = getTargetStreamer();
3505 const MCOperand &DstRegOp = Inst.getOperand(0);
3506 assert(DstRegOp.isReg() && "expected register operand kind");
3508 const MCOperand &ImmOp = Inst.getOperand(1);
3509 assert(ImmOp.isImm() && "expected immediate operand kind");
3511 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3512 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3513 "expected immediate or expression operand");
3515 bool IsLikely = false;
3517 unsigned OpCode = 0;
3518 switch(Inst.getOpcode()) {
3525 case Mips::BEQLImmMacro:
3526 OpCode = Mips::BEQL;
3529 case Mips::BNELImmMacro:
3530 OpCode = Mips::BNEL;
3534 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3538 int64_t ImmValue = ImmOp.getImm();
3539 if (ImmValue == 0) {
3541 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3542 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3543 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3545 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3548 warnIfNoMacro(IDLoc);
3550 unsigned ATReg = getATReg(IDLoc);
3554 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3559 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3560 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3561 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3563 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3568 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3569 const MCSubtargetInfo *STI, bool IsLoad) {
3570 const MCOperand &DstRegOp = Inst.getOperand(0);
3571 assert(DstRegOp.isReg() && "expected register operand kind");
3572 const MCOperand &BaseRegOp = Inst.getOperand(1);
3573 assert(BaseRegOp.isReg() && "expected register operand kind");
3574 const MCOperand &OffsetOp = Inst.getOperand(2);
3576 MipsTargetStreamer &TOut = getTargetStreamer();
3577 unsigned DstReg = DstRegOp.getReg();
3578 unsigned BaseReg = BaseRegOp.getReg();
3579 unsigned TmpReg = DstReg;
3581 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3582 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3583 unsigned DstRegClassID =
3584 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3585 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3586 (DstRegClassID == Mips::GPR64RegClassID);
3588 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3589 // At this point we need AT to perform the expansions
3590 // and we exit if it is not available.
3591 TmpReg = getATReg(IDLoc);
3596 if (OffsetOp.isImm()) {
3597 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3598 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3600 // If msb of LoOffset is 1(negative number) we must increment
3601 // HiOffset to account for the sign-extension of the low part.
3602 if (LoOffset & 0x8000)
3603 HiOffset += 0x10000;
3605 bool IsLargeOffset = HiOffset != 0;
3607 if (IsLargeOffset) {
3608 bool Is32BitImm = (HiOffset >> 32) == 0;
3609 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3614 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3615 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3616 BaseReg, IDLoc, STI);
3617 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3619 assert(OffsetOp.isExpr() && "expected expression operand kind");
3620 const MCExpr *ExprOffset = OffsetOp.getExpr();
3621 MCOperand LoOperand = MCOperand::createExpr(
3622 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3623 MCOperand HiOperand = MCOperand::createExpr(
3624 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3627 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3628 LoOperand, TmpReg, IDLoc, STI);
3630 TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3631 LoOperand, TmpReg, IDLoc, STI);
3635 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3637 const MCSubtargetInfo *STI) {
3638 unsigned OpNum = Inst.getNumOperands();
3639 unsigned Opcode = Inst.getOpcode();
3640 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3642 assert(Inst.getOperand(OpNum - 1).isImm() &&
3643 Inst.getOperand(OpNum - 2).isReg() &&
3644 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3646 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3647 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3648 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3649 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3650 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3651 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3652 // It can be implemented as SWM16 or LWM16 instruction.
3653 if (inMicroMipsMode() && hasMips32r6())
3654 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3656 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3659 Inst.setOpcode(NewOpcode);
3660 Out.EmitInstruction(Inst, *STI);
3664 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3666 const MCSubtargetInfo *STI) {
3667 MipsTargetStreamer &TOut = getTargetStreamer();
3668 bool EmittedNoMacroWarning = false;
3669 unsigned PseudoOpcode = Inst.getOpcode();
3670 unsigned SrcReg = Inst.getOperand(0).getReg();
3671 const MCOperand &TrgOp = Inst.getOperand(1);
3672 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3674 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3675 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3679 TrgReg = TrgOp.getReg();
3680 else if (TrgOp.isImm()) {
3681 warnIfNoMacro(IDLoc);
3682 EmittedNoMacroWarning = true;
3684 TrgReg = getATReg(IDLoc);
3688 switch(PseudoOpcode) {
3690 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3691 case Mips::BLTImmMacro:
3692 PseudoOpcode = Mips::BLT;
3694 case Mips::BLEImmMacro:
3695 PseudoOpcode = Mips::BLE;
3697 case Mips::BGEImmMacro:
3698 PseudoOpcode = Mips::BGE;
3700 case Mips::BGTImmMacro:
3701 PseudoOpcode = Mips::BGT;
3703 case Mips::BLTUImmMacro:
3704 PseudoOpcode = Mips::BLTU;
3706 case Mips::BLEUImmMacro:
3707 PseudoOpcode = Mips::BLEU;
3709 case Mips::BGEUImmMacro:
3710 PseudoOpcode = Mips::BGEU;
3712 case Mips::BGTUImmMacro:
3713 PseudoOpcode = Mips::BGTU;
3715 case Mips::BLTLImmMacro:
3716 PseudoOpcode = Mips::BLTL;
3718 case Mips::BLELImmMacro:
3719 PseudoOpcode = Mips::BLEL;
3721 case Mips::BGELImmMacro:
3722 PseudoOpcode = Mips::BGEL;
3724 case Mips::BGTLImmMacro:
3725 PseudoOpcode = Mips::BGTL;
3727 case Mips::BLTULImmMacro:
3728 PseudoOpcode = Mips::BLTUL;
3730 case Mips::BLEULImmMacro:
3731 PseudoOpcode = Mips::BLEUL;
3733 case Mips::BGEULImmMacro:
3734 PseudoOpcode = Mips::BGEUL;
3736 case Mips::BGTULImmMacro:
3737 PseudoOpcode = Mips::BGTUL;
3741 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3742 false, IDLoc, Out, STI))
3746 switch (PseudoOpcode) {
3751 AcceptsEquality = false;
3752 ReverseOrderSLT = false;
3754 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3755 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3756 ZeroSrcOpcode = Mips::BGTZ;
3757 ZeroTrgOpcode = Mips::BLTZ;
3763 AcceptsEquality = true;
3764 ReverseOrderSLT = true;
3766 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3767 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3768 ZeroSrcOpcode = Mips::BGEZ;
3769 ZeroTrgOpcode = Mips::BLEZ;
3775 AcceptsEquality = true;
3776 ReverseOrderSLT = false;
3778 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3779 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3780 ZeroSrcOpcode = Mips::BLEZ;
3781 ZeroTrgOpcode = Mips::BGEZ;
3787 AcceptsEquality = false;
3788 ReverseOrderSLT = true;
3790 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3791 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3792 ZeroSrcOpcode = Mips::BLTZ;
3793 ZeroTrgOpcode = Mips::BGTZ;
3796 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3799 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3800 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3801 if (IsSrcRegZero && IsTrgRegZero) {
3802 // FIXME: All of these Opcode-specific if's are needed for compatibility
3803 // with GAS' behaviour. However, they may not generate the most efficient
3804 // code in some circumstances.
3805 if (PseudoOpcode == Mips::BLT) {
3806 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3810 if (PseudoOpcode == Mips::BLE) {
3811 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3813 Warning(IDLoc, "branch is always taken");
3816 if (PseudoOpcode == Mips::BGE) {
3817 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3819 Warning(IDLoc, "branch is always taken");
3822 if (PseudoOpcode == Mips::BGT) {
3823 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3827 if (PseudoOpcode == Mips::BGTU) {
3828 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3829 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3832 if (AcceptsEquality) {
3833 // If both registers are $0 and the pseudo-branch accepts equality, it
3834 // will always be taken, so we emit an unconditional branch.
3835 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3836 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3837 Warning(IDLoc, "branch is always taken");
3840 // If both registers are $0 and the pseudo-branch does not accept
3841 // equality, it will never be taken, so we don't have to emit anything.
3844 if (IsSrcRegZero || IsTrgRegZero) {
3845 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3846 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3847 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3848 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3849 // the pseudo-branch will never be taken, so we don't emit anything.
3850 // This only applies to unsigned pseudo-branches.
3853 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3854 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3855 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3856 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3857 // the pseudo-branch will always be taken, so we emit an unconditional
3859 // This only applies to unsigned pseudo-branches.
3860 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3861 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3862 Warning(IDLoc, "branch is always taken");
3866 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3867 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3868 // the pseudo-branch will be taken only when the non-zero register is
3869 // different from 0, so we emit a BNEZ.
3871 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3872 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3873 // the pseudo-branch will be taken only when the non-zero register is
3874 // equal to 0, so we emit a BEQZ.
3876 // Because only BLEU and BGEU branch on equality, we can use the
3877 // AcceptsEquality variable to decide when to emit the BEQZ.
3878 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3879 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3880 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3883 // If we have a signed pseudo-branch and one of the registers is $0,
3884 // we can use an appropriate compare-to-zero branch. We select which one
3885 // to use in the switch statement above.
3886 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3887 IsSrcRegZero ? TrgReg : SrcReg,
3888 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3892 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3893 // expansions. If it is not available, we return.
3894 unsigned ATRegNum = getATReg(IDLoc);
3898 if (!EmittedNoMacroWarning)
3899 warnIfNoMacro(IDLoc);
3901 // SLT fits well with 2 of our 4 pseudo-branches:
3902 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3903 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3904 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3905 // This is accomplished by using a BNEZ with the result of the SLT.
3907 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3908 // and BLE with BGT), so we change the BNEZ into a BEQZ.
3909 // Because only BGE and BLE branch on equality, we can use the
3910 // AcceptsEquality variable to decide when to emit the BEQZ.
3911 // Note that the order of the SLT arguments doesn't change between
3914 // The same applies to the unsigned variants, except that SLTu is used
3916 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3917 ReverseOrderSLT ? TrgReg : SrcReg,
3918 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3920 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3921 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3922 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3927 // Expand a integer division macro.
3929 // Notably we don't have to emit a warning when encountering $rt as the $zero
3930 // register, or 0 as an immediate. processInstruction() has already done that.
3932 // The destination register can only be $zero when expanding (S)DivIMacro or
3935 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3936 const MCSubtargetInfo *STI, const bool IsMips64,
3937 const bool Signed) {
3938 MipsTargetStreamer &TOut = getTargetStreamer();
3940 warnIfNoMacro(IDLoc);
3942 const MCOperand &RdRegOp = Inst.getOperand(0);
3943 assert(RdRegOp.isReg() && "expected register operand kind");
3944 unsigned RdReg = RdRegOp.getReg();
3946 const MCOperand &RsRegOp = Inst.getOperand(1);
3947 assert(RsRegOp.isReg() && "expected register operand kind");
3948 unsigned RsReg = RsRegOp.getReg();
3953 const MCOperand &RtOp = Inst.getOperand(2);
3954 assert((RtOp.isReg() || RtOp.isImm()) &&
3955 "expected register or immediate operand kind");
3957 RtReg = RtOp.getReg();
3959 ImmValue = RtOp.getImm();
3966 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3967 ZeroReg = Mips::ZERO_64;
3970 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3971 ZeroReg = Mips::ZERO;
3975 bool UseTraps = useTraps();
3977 unsigned Opcode = Inst.getOpcode();
3978 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
3979 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
3980 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
3981 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
3983 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
3984 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
3985 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
3986 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
3989 unsigned ATReg = getATReg(IDLoc);
3993 if (ImmValue == 0) {
3995 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3997 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4001 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4002 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4004 } else if (isDiv && ImmValue == 1) {
4005 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4007 } else if (isDiv && Signed && ImmValue == -1) {
4008 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4011 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4012 false, Inst.getLoc(), Out, STI))
4014 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4015 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4021 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4022 // break, insert the trap/break and exit. This gives a different result to
4023 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4024 // are handled equivalently. As the observed behaviour is the same, we're ok.
4025 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4027 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4030 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4034 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4035 // not expand to macro sequence.
4036 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4037 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4041 // Temporary label for first branch traget
4042 MCContext &Context = TOut.getStreamer().getContext();
4047 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4049 // Branch to the li instruction.
4050 BrTarget = Context.createTempSymbol();
4051 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4052 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4055 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4058 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4062 TOut.getStreamer().EmitLabel(BrTarget);
4064 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4068 unsigned ATReg = getATReg(IDLoc);
4073 TOut.getStreamer().EmitLabel(BrTarget);
4075 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4077 // Temporary label for the second branch target.
4078 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4079 MCOperand LabelOpEnd =
4080 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4082 // Branch to the mflo instruction.
4083 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4086 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4087 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4089 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4093 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4095 // Branch to the mflo instruction.
4096 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4097 TOut.emitNop(IDLoc, STI);
4098 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4101 TOut.getStreamer().EmitLabel(BrTargetEnd);
4102 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4106 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4107 SMLoc IDLoc, MCStreamer &Out,
4108 const MCSubtargetInfo *STI) {
4109 MipsTargetStreamer &TOut = getTargetStreamer();
4111 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4112 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4113 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4115 unsigned FirstReg = Inst.getOperand(0).getReg();
4116 unsigned SecondReg = Inst.getOperand(1).getReg();
4117 unsigned ThirdReg = Inst.getOperand(2).getReg();
4119 if (hasMips1() && !hasMips2()) {
4120 unsigned ATReg = getATReg(IDLoc);
4123 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4124 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4125 TOut.emitNop(IDLoc, STI);
4126 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4127 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4128 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4129 TOut.emitNop(IDLoc, STI);
4130 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4132 FirstReg, SecondReg, IDLoc, STI);
4133 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4134 TOut.emitNop(IDLoc, STI);
4138 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4140 FirstReg, SecondReg, IDLoc, STI);
4145 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4146 MCStreamer &Out, const MCSubtargetInfo *STI) {
4147 if (hasMips32r6() || hasMips64r6()) {
4148 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4151 const MCOperand &DstRegOp = Inst.getOperand(0);
4152 assert(DstRegOp.isReg() && "expected register operand kind");
4153 const MCOperand &SrcRegOp = Inst.getOperand(1);
4154 assert(SrcRegOp.isReg() && "expected register operand kind");
4155 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4156 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4158 MipsTargetStreamer &TOut = getTargetStreamer();
4159 unsigned DstReg = DstRegOp.getReg();
4160 unsigned SrcReg = SrcRegOp.getReg();
4161 int64_t OffsetValue = OffsetImmOp.getImm();
4163 // NOTE: We always need AT for ULHU, as it is always used as the source
4164 // register for one of the LBu's.
4165 warnIfNoMacro(IDLoc);
4166 unsigned ATReg = getATReg(IDLoc);
4170 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4171 if (IsLargeOffset) {
4172 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4177 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4178 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4180 std::swap(FirstOffset, SecondOffset);
4182 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4183 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4185 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4186 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4188 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4189 FirstOffset, IDLoc, STI);
4190 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4191 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4192 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4197 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4198 const MCSubtargetInfo *STI) {
4199 if (hasMips32r6() || hasMips64r6()) {
4200 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4203 const MCOperand &DstRegOp = Inst.getOperand(0);
4204 assert(DstRegOp.isReg() && "expected register operand kind");
4205 const MCOperand &SrcRegOp = Inst.getOperand(1);
4206 assert(SrcRegOp.isReg() && "expected register operand kind");
4207 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4208 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4210 MipsTargetStreamer &TOut = getTargetStreamer();
4211 unsigned DstReg = DstRegOp.getReg();
4212 unsigned SrcReg = SrcRegOp.getReg();
4213 int64_t OffsetValue = OffsetImmOp.getImm();
4215 warnIfNoMacro(IDLoc);
4216 unsigned ATReg = getATReg(IDLoc);
4220 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4221 if (IsLargeOffset) {
4222 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4227 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4228 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4230 std::swap(FirstOffset, SecondOffset);
4232 if (IsLargeOffset) {
4233 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4234 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4235 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4236 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4237 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4238 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4240 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4241 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4242 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4248 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4249 const MCSubtargetInfo *STI) {
4250 if (hasMips32r6() || hasMips64r6()) {
4251 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4254 const MCOperand &DstRegOp = Inst.getOperand(0);
4255 assert(DstRegOp.isReg() && "expected register operand kind");
4256 const MCOperand &SrcRegOp = Inst.getOperand(1);
4257 assert(SrcRegOp.isReg() && "expected register operand kind");
4258 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4259 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4261 MipsTargetStreamer &TOut = getTargetStreamer();
4262 unsigned DstReg = DstRegOp.getReg();
4263 unsigned SrcReg = SrcRegOp.getReg();
4264 int64_t OffsetValue = OffsetImmOp.getImm();
4266 // Compute left/right load/store offsets.
4267 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4268 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4269 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4271 std::swap(LxlOffset, LxrOffset);
4273 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4274 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4275 unsigned TmpReg = SrcReg;
4276 if (IsLargeOffset || DoMove) {
4277 warnIfNoMacro(IDLoc);
4278 TmpReg = getATReg(IDLoc);
4283 if (IsLargeOffset) {
4284 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4290 std::swap(DstReg, TmpReg);
4292 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4293 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4294 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4295 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4298 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4303 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4305 const MCSubtargetInfo *STI) {
4306 MipsTargetStreamer &TOut = getTargetStreamer();
4308 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4309 assert(Inst.getOperand(0).isReg() &&
4310 Inst.getOperand(1).isReg() &&
4311 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4313 unsigned ATReg = Mips::NoRegister;
4314 unsigned FinalDstReg = Mips::NoRegister;
4315 unsigned DstReg = Inst.getOperand(0).getReg();
4316 unsigned SrcReg = Inst.getOperand(1).getReg();
4317 int64_t ImmValue = Inst.getOperand(2).getImm();
4319 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4321 unsigned FinalOpcode = Inst.getOpcode();
4323 if (DstReg == SrcReg) {
4324 ATReg = getATReg(Inst.getLoc());
4327 FinalDstReg = DstReg;
4331 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4332 Inst.getLoc(), Out, STI)) {
4333 switch (FinalOpcode) {
4335 llvm_unreachable("unimplemented expansion");
4337 FinalOpcode = Mips::ADD;
4340 FinalOpcode = Mips::ADDu;
4343 FinalOpcode = Mips::AND;
4346 FinalOpcode = Mips::NOR;
4349 FinalOpcode = Mips::OR;
4352 FinalOpcode = Mips::SLT;
4355 FinalOpcode = Mips::SLTu;
4358 FinalOpcode = Mips::XOR;
4361 FinalOpcode = Mips::ADD_MM;
4363 case Mips::ADDiu_MM:
4364 FinalOpcode = Mips::ADDu_MM;
4367 FinalOpcode = Mips::AND_MM;
4370 FinalOpcode = Mips::OR_MM;
4373 FinalOpcode = Mips::SLT_MM;
4375 case Mips::SLTiu_MM:
4376 FinalOpcode = Mips::SLTu_MM;
4379 FinalOpcode = Mips::XOR_MM;
4382 FinalOpcode = Mips::AND64;
4384 case Mips::NORImm64:
4385 FinalOpcode = Mips::NOR64;
4388 FinalOpcode = Mips::OR64;
4390 case Mips::SLTImm64:
4391 FinalOpcode = Mips::SLT64;
4393 case Mips::SLTUImm64:
4394 FinalOpcode = Mips::SLTu64;
4397 FinalOpcode = Mips::XOR64;
4401 if (FinalDstReg == Mips::NoRegister)
4402 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4404 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4410 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4411 const MCSubtargetInfo *STI) {
4412 MipsTargetStreamer &TOut = getTargetStreamer();
4413 unsigned ATReg = Mips::NoRegister;
4414 unsigned DReg = Inst.getOperand(0).getReg();
4415 unsigned SReg = Inst.getOperand(1).getReg();
4416 unsigned TReg = Inst.getOperand(2).getReg();
4417 unsigned TmpReg = DReg;
4419 unsigned FirstShift = Mips::NOP;
4420 unsigned SecondShift = Mips::NOP;
4422 if (hasMips32r2()) {
4424 TmpReg = getATReg(Inst.getLoc());
4429 if (Inst.getOpcode() == Mips::ROL) {
4430 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4431 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4435 if (Inst.getOpcode() == Mips::ROR) {
4436 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4444 switch (Inst.getOpcode()) {
4446 llvm_unreachable("unexpected instruction opcode");
4448 FirstShift = Mips::SRLV;
4449 SecondShift = Mips::SLLV;
4452 FirstShift = Mips::SLLV;
4453 SecondShift = Mips::SRLV;
4457 ATReg = getATReg(Inst.getLoc());
4461 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4462 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4463 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4464 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4472 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4474 const MCSubtargetInfo *STI) {
4475 MipsTargetStreamer &TOut = getTargetStreamer();
4476 unsigned ATReg = Mips::NoRegister;
4477 unsigned DReg = Inst.getOperand(0).getReg();
4478 unsigned SReg = Inst.getOperand(1).getReg();
4479 int64_t ImmValue = Inst.getOperand(2).getImm();
4481 unsigned FirstShift = Mips::NOP;
4482 unsigned SecondShift = Mips::NOP;
4484 if (hasMips32r2()) {
4485 if (Inst.getOpcode() == Mips::ROLImm) {
4486 uint64_t MaxShift = 32;
4487 uint64_t ShiftValue = ImmValue;
4489 ShiftValue = MaxShift - ImmValue;
4490 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4494 if (Inst.getOpcode() == Mips::RORImm) {
4495 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4503 if (ImmValue == 0) {
4504 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4508 switch (Inst.getOpcode()) {
4510 llvm_unreachable("unexpected instruction opcode");
4512 FirstShift = Mips::SLL;
4513 SecondShift = Mips::SRL;
4516 FirstShift = Mips::SRL;
4517 SecondShift = Mips::SLL;
4521 ATReg = getATReg(Inst.getLoc());
4525 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4526 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4527 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4535 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4536 const MCSubtargetInfo *STI) {
4537 MipsTargetStreamer &TOut = getTargetStreamer();
4538 unsigned ATReg = Mips::NoRegister;
4539 unsigned DReg = Inst.getOperand(0).getReg();
4540 unsigned SReg = Inst.getOperand(1).getReg();
4541 unsigned TReg = Inst.getOperand(2).getReg();
4542 unsigned TmpReg = DReg;
4544 unsigned FirstShift = Mips::NOP;
4545 unsigned SecondShift = Mips::NOP;
4547 if (hasMips64r2()) {
4548 if (TmpReg == SReg) {
4549 TmpReg = getATReg(Inst.getLoc());
4554 if (Inst.getOpcode() == Mips::DROL) {
4555 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4556 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4560 if (Inst.getOpcode() == Mips::DROR) {
4561 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4569 switch (Inst.getOpcode()) {
4571 llvm_unreachable("unexpected instruction opcode");
4573 FirstShift = Mips::DSRLV;
4574 SecondShift = Mips::DSLLV;
4577 FirstShift = Mips::DSLLV;
4578 SecondShift = Mips::DSRLV;
4582 ATReg = getATReg(Inst.getLoc());
4586 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4587 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4588 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4589 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4597 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4599 const MCSubtargetInfo *STI) {
4600 MipsTargetStreamer &TOut = getTargetStreamer();
4601 unsigned ATReg = Mips::NoRegister;
4602 unsigned DReg = Inst.getOperand(0).getReg();
4603 unsigned SReg = Inst.getOperand(1).getReg();
4604 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4606 unsigned FirstShift = Mips::NOP;
4607 unsigned SecondShift = Mips::NOP;
4611 if (hasMips64r2()) {
4612 unsigned FinalOpcode = Mips::NOP;
4614 FinalOpcode = Mips::DROTR;
4615 else if (ImmValue % 32 == 0)
4616 FinalOpcode = Mips::DROTR32;
4617 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4618 if (Inst.getOpcode() == Mips::DROLImm)
4619 FinalOpcode = Mips::DROTR32;
4621 FinalOpcode = Mips::DROTR;
4622 } else if (ImmValue >= 33) {
4623 if (Inst.getOpcode() == Mips::DROLImm)
4624 FinalOpcode = Mips::DROTR;
4626 FinalOpcode = Mips::DROTR32;
4629 uint64_t ShiftValue = ImmValue % 32;
4630 if (Inst.getOpcode() == Mips::DROLImm)
4631 ShiftValue = (32 - ImmValue % 32) % 32;
4633 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4639 if (ImmValue == 0) {
4640 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4644 switch (Inst.getOpcode()) {
4646 llvm_unreachable("unexpected instruction opcode");
4648 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4649 FirstShift = Mips::DSLL;
4650 SecondShift = Mips::DSRL32;
4652 if (ImmValue == 32) {
4653 FirstShift = Mips::DSLL32;
4654 SecondShift = Mips::DSRL32;
4656 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4657 FirstShift = Mips::DSLL32;
4658 SecondShift = Mips::DSRL;
4662 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4663 FirstShift = Mips::DSRL;
4664 SecondShift = Mips::DSLL32;
4666 if (ImmValue == 32) {
4667 FirstShift = Mips::DSRL32;
4668 SecondShift = Mips::DSLL32;
4670 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4671 FirstShift = Mips::DSRL32;
4672 SecondShift = Mips::DSLL;
4677 ATReg = getATReg(Inst.getLoc());
4681 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4682 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4683 Inst.getLoc(), STI);
4684 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4692 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4693 const MCSubtargetInfo *STI) {
4694 MipsTargetStreamer &TOut = getTargetStreamer();
4695 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4696 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4698 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4699 if (FirstRegOp != SecondRegOp)
4700 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4702 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4703 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4708 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4709 const MCSubtargetInfo *STI) {
4710 MipsTargetStreamer &TOut = getTargetStreamer();
4711 unsigned ATReg = Mips::NoRegister;
4712 unsigned DstReg = Inst.getOperand(0).getReg();
4713 unsigned SrcReg = Inst.getOperand(1).getReg();
4714 int32_t ImmValue = Inst.getOperand(2).getImm();
4716 ATReg = getATReg(IDLoc);
4720 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4723 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4724 SrcReg, ATReg, IDLoc, STI);
4726 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4731 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4732 const MCSubtargetInfo *STI) {
4733 MipsTargetStreamer &TOut = getTargetStreamer();
4734 unsigned ATReg = Mips::NoRegister;
4735 unsigned DstReg = Inst.getOperand(0).getReg();
4736 unsigned SrcReg = Inst.getOperand(1).getReg();
4737 unsigned TmpReg = Inst.getOperand(2).getReg();
4739 ATReg = getATReg(Inst.getLoc());
4743 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4744 SrcReg, TmpReg, IDLoc, STI);
4746 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4748 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4749 DstReg, DstReg, 0x1F, IDLoc, STI);
4751 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4754 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4756 MCContext & Context = TOut.getStreamer().getContext();
4757 MCSymbol * BrTarget = Context.createTempSymbol();
4759 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4761 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4762 if (AssemblerOptions.back()->isReorder())
4763 TOut.emitNop(IDLoc, STI);
4764 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4766 TOut.getStreamer().EmitLabel(BrTarget);
4768 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4773 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4774 const MCSubtargetInfo *STI) {
4775 MipsTargetStreamer &TOut = getTargetStreamer();
4776 unsigned ATReg = Mips::NoRegister;
4777 unsigned DstReg = Inst.getOperand(0).getReg();
4778 unsigned SrcReg = Inst.getOperand(1).getReg();
4779 unsigned TmpReg = Inst.getOperand(2).getReg();
4781 ATReg = getATReg(IDLoc);
4785 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4786 SrcReg, TmpReg, IDLoc, STI);
4788 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4789 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4791 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4793 MCContext & Context = TOut.getStreamer().getContext();
4794 MCSymbol * BrTarget = Context.createTempSymbol();
4796 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4798 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4799 if (AssemblerOptions.back()->isReorder())
4800 TOut.emitNop(IDLoc, STI);
4801 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4803 TOut.getStreamer().EmitLabel(BrTarget);
4809 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4810 const MCSubtargetInfo *STI) {
4811 MipsTargetStreamer &TOut = getTargetStreamer();
4812 unsigned DstReg = Inst.getOperand(0).getReg();
4813 unsigned SrcReg = Inst.getOperand(1).getReg();
4814 unsigned TmpReg = Inst.getOperand(2).getReg();
4816 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4817 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4822 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4823 // lw $<reg+1>>, offset+4($reg2)'
4824 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4825 // sw $<reg+1>>, offset+4($reg2)'
4827 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4829 const MCSubtargetInfo *STI,
4834 warnIfNoMacro(IDLoc);
4836 MipsTargetStreamer &TOut = getTargetStreamer();
4837 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4838 unsigned FirstReg = Inst.getOperand(0).getReg();
4839 unsigned SecondReg = nextReg(FirstReg);
4840 unsigned BaseReg = Inst.getOperand(1).getReg();
4844 warnIfRegIndexIsAT(FirstReg, IDLoc);
4846 assert(Inst.getOperand(2).isImm() &&
4847 "Offset for load macro is not immediate!");
4849 MCOperand &FirstOffset = Inst.getOperand(2);
4850 signed NextOffset = FirstOffset.getImm() + 4;
4851 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4853 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4856 // For loads, clobber the base register with the second load instead of the
4857 // first if the BaseReg == FirstReg.
4858 if (FirstReg != BaseReg || !IsLoad) {
4859 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4860 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4862 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4863 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4869 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4870 const MCSubtargetInfo *STI) {
4872 warnIfNoMacro(IDLoc);
4873 MipsTargetStreamer &TOut = getTargetStreamer();
4875 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4876 Inst.getOperand(2).getReg() != Mips::ZERO) {
4877 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4878 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4880 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4881 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4886 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4887 Reg = Inst.getOperand(2).getReg();
4889 Reg = Inst.getOperand(1).getReg();
4891 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4895 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4896 const MCSubtargetInfo *STI) {
4897 warnIfNoMacro(IDLoc);
4898 MipsTargetStreamer &TOut = getTargetStreamer();
4901 int64_t Imm = Inst.getOperand(2).getImm();
4902 unsigned Reg = Inst.getOperand(1).getReg();
4905 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4906 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4910 if (Reg == Mips::ZERO) {
4911 Warning(IDLoc, "comparison is always false");
4912 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4913 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4917 if (Imm > -0x8000 && Imm < 0) {
4919 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4924 if (!isUInt<16>(Imm)) {
4925 unsigned ATReg = getATReg(IDLoc);
4929 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4933 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4934 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4935 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4936 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4940 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4942 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4943 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4947 // Map the DSP accumulator and control register to the corresponding gpr
4948 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
4949 // do not map the DSP registers contigously to gpr registers.
4950 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
4951 switch (Inst.getOpcode()) {
4954 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4964 llvm_unreachable("Unknown register for 'mttr' alias!");
4968 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4978 llvm_unreachable("Unknown register for 'mttr' alias!");
4982 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4992 llvm_unreachable("Unknown register for 'mttr' alias!");
4998 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5002 // Map the floating point register operand to the corresponding register
5004 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5005 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5006 case Mips::F0: return Mips::ZERO;
5007 case Mips::F1: return Mips::AT;
5008 case Mips::F2: return Mips::V0;
5009 case Mips::F3: return Mips::V1;
5010 case Mips::F4: return Mips::A0;
5011 case Mips::F5: return Mips::A1;
5012 case Mips::F6: return Mips::A2;
5013 case Mips::F7: return Mips::A3;
5014 case Mips::F8: return Mips::T0;
5015 case Mips::F9: return Mips::T1;
5016 case Mips::F10: return Mips::T2;
5017 case Mips::F11: return Mips::T3;
5018 case Mips::F12: return Mips::T4;
5019 case Mips::F13: return Mips::T5;
5020 case Mips::F14: return Mips::T6;
5021 case Mips::F15: return Mips::T7;
5022 case Mips::F16: return Mips::S0;
5023 case Mips::F17: return Mips::S1;
5024 case Mips::F18: return Mips::S2;
5025 case Mips::F19: return Mips::S3;
5026 case Mips::F20: return Mips::S4;
5027 case Mips::F21: return Mips::S5;
5028 case Mips::F22: return Mips::S6;
5029 case Mips::F23: return Mips::S7;
5030 case Mips::F24: return Mips::T8;
5031 case Mips::F25: return Mips::T9;
5032 case Mips::F26: return Mips::K0;
5033 case Mips::F27: return Mips::K1;
5034 case Mips::F28: return Mips::GP;
5035 case Mips::F29: return Mips::SP;
5036 case Mips::F30: return Mips::FP;
5037 case Mips::F31: return Mips::RA;
5038 default: llvm_unreachable("Unknown register for mttc1 alias!");
5042 // Map the coprocessor operand the corresponding gpr register operand.
5043 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5044 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5045 case Mips::COP00: return Mips::ZERO;
5046 case Mips::COP01: return Mips::AT;
5047 case Mips::COP02: return Mips::V0;
5048 case Mips::COP03: return Mips::V1;
5049 case Mips::COP04: return Mips::A0;
5050 case Mips::COP05: return Mips::A1;
5051 case Mips::COP06: return Mips::A2;
5052 case Mips::COP07: return Mips::A3;
5053 case Mips::COP08: return Mips::T0;
5054 case Mips::COP09: return Mips::T1;
5055 case Mips::COP010: return Mips::T2;
5056 case Mips::COP011: return Mips::T3;
5057 case Mips::COP012: return Mips::T4;
5058 case Mips::COP013: return Mips::T5;
5059 case Mips::COP014: return Mips::T6;
5060 case Mips::COP015: return Mips::T7;
5061 case Mips::COP016: return Mips::S0;
5062 case Mips::COP017: return Mips::S1;
5063 case Mips::COP018: return Mips::S2;
5064 case Mips::COP019: return Mips::S3;
5065 case Mips::COP020: return Mips::S4;
5066 case Mips::COP021: return Mips::S5;
5067 case Mips::COP022: return Mips::S6;
5068 case Mips::COP023: return Mips::S7;
5069 case Mips::COP024: return Mips::T8;
5070 case Mips::COP025: return Mips::T9;
5071 case Mips::COP026: return Mips::K0;
5072 case Mips::COP027: return Mips::K1;
5073 case Mips::COP028: return Mips::GP;
5074 case Mips::COP029: return Mips::SP;
5075 case Mips::COP030: return Mips::FP;
5076 case Mips::COP031: return Mips::RA;
5077 default: llvm_unreachable("Unknown register for mttc0 alias!");
5081 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5082 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5083 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5084 const MCSubtargetInfo *STI) {
5085 MipsTargetStreamer &TOut = getTargetStreamer();
5090 bool IsMFTR = false;
5091 switch (Inst.getOpcode()) {
5097 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5098 sel = Inst.getOperand(2).getImm();
5104 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5116 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5124 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5131 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5138 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5142 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5145 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5146 : Inst.getOperand(0).getReg());
5148 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5154 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5155 const OperandVector &Operands) {
5156 switch (Inst.getOpcode()) {
5158 return Match_Success;
5161 if (static_cast<MipsOperand &>(*Operands[1])
5162 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5163 return Match_Success;
5164 return Match_RequiresSameSrcAndDst;
5168 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5169 switch (Inst.getOpcode()) {
5170 // As described by the MIPSR6 spec, daui must not use the zero operand for
5171 // its source operand.
5173 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5174 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5175 return Match_RequiresNoZeroRegister;
5176 return Match_Success;
5177 // As described by the Mips32r2 spec, the registers Rd and Rs for
5178 // jalr.hb must be different.
5179 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5180 // and registers Rd and Base for microMIPS lwp instruction
5182 case Mips::JALR_HB64:
5183 case Mips::JALRC_HB_MMR6:
5184 case Mips::JALRC_MMR6:
5185 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5186 return Match_RequiresDifferentSrcAndDst;
5187 return Match_Success;
5189 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5190 return Match_RequiresDifferentSrcAndDst;
5191 return Match_Success;
5193 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5194 return Match_NonZeroOperandForSync;
5195 return Match_Success;
5200 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5201 return Match_NonZeroOperandForMTCX;
5202 return Match_Success;
5203 // As described the MIPSR6 spec, the compact branches that compare registers
5205 // a) Not use the zero register.
5206 // b) Not use the same register twice.
5207 // c) rs < rt for bnec, beqc.
5208 // NB: For this case, the encoding will swap the operands as their
5209 // ordering doesn't matter. GAS performs this transformation too.
5210 // Hence, that constraint does not have to be enforced.
5212 // The compact branches that branch iff the signed addition of two registers
5213 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5214 // operand swapping. They do not have restriction of using the zero register.
5215 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5216 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5217 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5218 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5219 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5220 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5227 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5228 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5229 return Match_RequiresNoZeroRegister;
5230 return Match_Success;
5231 case Mips::BGEC: case Mips::BGEC_MMR6:
5232 case Mips::BLTC: case Mips::BLTC_MMR6:
5233 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5234 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5235 case Mips::BEQC: case Mips::BEQC_MMR6:
5236 case Mips::BNEC: case Mips::BNEC_MMR6:
5243 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5244 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5245 return Match_RequiresNoZeroRegister;
5246 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5247 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5248 return Match_RequiresNoZeroRegister;
5249 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5250 return Match_RequiresDifferentOperands;
5251 return Match_Success;
5253 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5254 "Operands must be immediates for dins!");
5255 const signed Pos = Inst.getOperand(2).getImm();
5256 const signed Size = Inst.getOperand(3).getImm();
5257 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5258 return Match_RequiresPosSizeRange0_32;
5259 return Match_Success;
5263 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5264 "Operands must be immediates for dinsm/dinsu!");
5265 const signed Pos = Inst.getOperand(2).getImm();
5266 const signed Size = Inst.getOperand(3).getImm();
5267 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5268 return Match_RequiresPosSizeRange33_64;
5269 return Match_Success;
5272 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5273 "Operands must be immediates for DEXTM!");
5274 const signed Pos = Inst.getOperand(2).getImm();
5275 const signed Size = Inst.getOperand(3).getImm();
5276 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5277 return Match_RequiresPosSizeUImm6;
5278 return Match_Success;
5282 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5283 "Operands must be immediates for dextm/dextu!");
5284 const signed Pos = Inst.getOperand(2).getImm();
5285 const signed Size = Inst.getOperand(3).getImm();
5286 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5287 return Match_RequiresPosSizeRange33_64;
5288 return Match_Success;
5290 case Mips::CRC32B: case Mips::CRC32CB:
5291 case Mips::CRC32H: case Mips::CRC32CH:
5292 case Mips::CRC32W: case Mips::CRC32CW:
5293 case Mips::CRC32D: case Mips::CRC32CD:
5294 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5295 return Match_RequiresSameSrcAndDst;
5296 return Match_Success;
5299 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5300 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5301 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5302 return Match_NoFCCRegisterForCurrentISA;
5304 return Match_Success;
5308 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5309 uint64_t ErrorInfo) {
5310 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5311 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5312 if (ErrorLoc == SMLoc())
5319 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5320 OperandVector &Operands,
5322 uint64_t &ErrorInfo,
5323 bool MatchingInlineAsm) {
5325 unsigned MatchResult =
5326 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5328 switch (MatchResult) {
5330 if (processInstruction(Inst, IDLoc, Out, STI))
5333 case Match_MissingFeature:
5334 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5336 case Match_InvalidOperand: {
5337 SMLoc ErrorLoc = IDLoc;
5338 if (ErrorInfo != ~0ULL) {
5339 if (ErrorInfo >= Operands.size())
5340 return Error(IDLoc, "too few operands for instruction");
5342 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5343 if (ErrorLoc == SMLoc())
5347 return Error(ErrorLoc, "invalid operand for instruction");
5349 case Match_NonZeroOperandForSync:
5351 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5352 case Match_NonZeroOperandForMTCX:
5353 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5354 case Match_MnemonicFail:
5355 return Error(IDLoc, "invalid instruction");
5356 case Match_RequiresDifferentSrcAndDst:
5357 return Error(IDLoc, "source and destination must be different");
5358 case Match_RequiresDifferentOperands:
5359 return Error(IDLoc, "registers must be different");
5360 case Match_RequiresNoZeroRegister:
5361 return Error(IDLoc, "invalid operand ($zero) for instruction");
5362 case Match_RequiresSameSrcAndDst:
5363 return Error(IDLoc, "source and destination must match");
5364 case Match_NoFCCRegisterForCurrentISA:
5365 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5366 "non-zero fcc register doesn't exist in current ISA level");
5368 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5370 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5371 "expected 1-bit unsigned immediate");
5373 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5374 "expected 2-bit unsigned immediate");
5376 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5377 "expected immediate in range 1 .. 4");
5379 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5380 "expected 3-bit unsigned immediate");
5382 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5383 "expected 4-bit unsigned immediate");
5385 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5386 "expected 4-bit signed immediate");
5388 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5389 "expected 5-bit unsigned immediate");
5391 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5392 "expected 5-bit signed immediate");
5394 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5395 "expected immediate in range 1 .. 32");
5396 case Match_UImm5_32:
5397 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5398 "expected immediate in range 32 .. 63");
5399 case Match_UImm5_33:
5400 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5401 "expected immediate in range 33 .. 64");
5402 case Match_UImm5_0_Report_UImm6:
5403 // This is used on UImm5 operands that have a corresponding UImm5_32
5404 // operand to avoid confusing the user.
5405 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5406 "expected 6-bit unsigned immediate");
5407 case Match_UImm5_Lsl2:
5408 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5409 "expected both 7-bit unsigned immediate and multiple of 4");
5410 case Match_UImmRange2_64:
5411 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5412 "expected immediate in range 2 .. 64");
5414 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5415 "expected 6-bit unsigned immediate");
5416 case Match_UImm6_Lsl2:
5417 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5418 "expected both 8-bit unsigned immediate and multiple of 4");
5420 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5421 "expected 6-bit signed immediate");
5423 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5424 "expected 7-bit unsigned immediate");
5425 case Match_UImm7_N1:
5426 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5427 "expected immediate in range -1 .. 126");
5428 case Match_SImm7_Lsl2:
5429 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5430 "expected both 9-bit signed immediate and multiple of 4");
5432 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5433 "expected 8-bit unsigned immediate");
5434 case Match_UImm10_0:
5435 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5436 "expected 10-bit unsigned immediate");
5437 case Match_SImm10_0:
5438 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5439 "expected 10-bit signed immediate");
5440 case Match_SImm11_0:
5441 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5442 "expected 11-bit signed immediate");
5444 case Match_UImm16_Relaxed:
5445 case Match_UImm16_AltRelaxed:
5446 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5447 "expected 16-bit unsigned immediate");
5449 case Match_SImm16_Relaxed:
5450 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5451 "expected 16-bit signed immediate");
5452 case Match_SImm19_Lsl2:
5453 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5454 "expected both 19-bit signed immediate and multiple of 4");
5455 case Match_UImm20_0:
5456 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5457 "expected 20-bit unsigned immediate");
5458 case Match_UImm26_0:
5459 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5460 "expected 26-bit unsigned immediate");
5462 case Match_SImm32_Relaxed:
5463 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5464 "expected 32-bit signed immediate");
5465 case Match_UImm32_Coerced:
5466 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5467 "expected 32-bit immediate");
5468 case Match_MemSImm9:
5469 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5470 "expected memory with 9-bit signed offset");
5471 case Match_MemSImm10:
5472 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5473 "expected memory with 10-bit signed offset");
5474 case Match_MemSImm10Lsl1:
5475 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5476 "expected memory with 11-bit signed offset and multiple of 2");
5477 case Match_MemSImm10Lsl2:
5478 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5479 "expected memory with 12-bit signed offset and multiple of 4");
5480 case Match_MemSImm10Lsl3:
5481 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5482 "expected memory with 13-bit signed offset and multiple of 8");
5483 case Match_MemSImm11:
5484 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5485 "expected memory with 11-bit signed offset");
5486 case Match_MemSImm12:
5487 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5488 "expected memory with 12-bit signed offset");
5489 case Match_MemSImm16:
5490 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5491 "expected memory with 16-bit signed offset");
5492 case Match_MemSImmPtr:
5493 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5494 "expected memory with 32-bit signed offset");
5495 case Match_RequiresPosSizeRange0_32: {
5496 SMLoc ErrorStart = Operands[3]->getStartLoc();
5497 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5498 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5499 SMRange(ErrorStart, ErrorEnd));
5501 case Match_RequiresPosSizeUImm6: {
5502 SMLoc ErrorStart = Operands[3]->getStartLoc();
5503 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5504 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5505 SMRange(ErrorStart, ErrorEnd));
5507 case Match_RequiresPosSizeRange33_64: {
5508 SMLoc ErrorStart = Operands[3]->getStartLoc();
5509 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5510 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5511 SMRange(ErrorStart, ErrorEnd));
5515 llvm_unreachable("Implement any new match types added!");
5518 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5519 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5520 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5521 ") without \".set noat\"");
5524 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5525 if (!AssemblerOptions.back()->isMacro())
5526 Warning(Loc, "macro instruction expanded into multiple instructions");
5529 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5530 const OperandVector &Operands) {
5532 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
5533 "Unexpected instruction!");
5534 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5535 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5536 Inst.addOperand(MCOperand::createReg(NextReg));
5537 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5541 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5542 SMRange Range, bool ShowColors) {
5543 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5544 Range, SMFixIt(Range, FixMsg),
5548 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5551 CC = StringSwitch<unsigned>(Name)
5553 .Cases("at", "AT", 1)
5587 if (!(isABI_N32() || isABI_N64()))
5590 if (12 <= CC && CC <= 15) {
5591 // Name is one of t4-t7
5592 AsmToken RegTok = getLexer().peekTok();
5593 SMRange RegRange = RegTok.getLocRange();
5595 StringRef FixedName = StringSwitch<StringRef>(Name)
5601 assert(FixedName != "" && "Register name is not one of t4-t7.");
5603 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5604 "Did you mean $" + FixedName + "?", RegRange);
5607 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5608 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5609 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5610 if (8 <= CC && CC <= 11)
5614 CC = StringSwitch<unsigned>(Name)
5626 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5629 CC = StringSwitch<unsigned>(Name)
5630 .Case("hwr_cpunum", 0)
5631 .Case("hwr_synci_step", 1)
5633 .Case("hwr_ccres", 3)
5634 .Case("hwr_ulr", 29)
5640 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5641 if (Name[0] == 'f') {
5642 StringRef NumString = Name.substr(1);
5644 if (NumString.getAsInteger(10, IntVal))
5645 return -1; // This is not an integer.
5646 if (IntVal > 31) // Maximum index for fpu register.
5653 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5654 if (Name.startswith("fcc")) {
5655 StringRef NumString = Name.substr(3);
5657 if (NumString.getAsInteger(10, IntVal))
5658 return -1; // This is not an integer.
5659 if (IntVal > 7) // There are only 8 fcc registers.
5666 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5667 if (Name.startswith("ac")) {
5668 StringRef NumString = Name.substr(2);
5670 if (NumString.getAsInteger(10, IntVal))
5671 return -1; // This is not an integer.
5672 if (IntVal > 3) // There are only 3 acc registers.
5679 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5682 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5691 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5694 CC = StringSwitch<unsigned>(Name)
5697 .Case("msaaccess", 2)
5699 .Case("msamodify", 4)
5700 .Case("msarequest", 5)
5702 .Case("msaunmap", 7)
5708 bool MipsAsmParser::canUseATReg() {
5709 return AssemblerOptions.back()->getATRegIndex() != 0;
5712 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5713 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5715 reportParseError(Loc,
5716 "pseudo-instruction requires $at, which is not available");
5719 unsigned AT = getReg(
5720 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5724 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5725 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5728 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5729 MCAsmParser &Parser = getParser();
5730 LLVM_DEBUG(dbgs() << "parseOperand\n");
5732 // Check if the current operand has a custom associated parser, if so, try to
5733 // custom parse the operand, or fallback to the general approach.
5734 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5735 if (ResTy == MatchOperand_Success)
5737 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5738 // there was a match, but an error occurred, in which case, just return that
5739 // the operand parsing failed.
5740 if (ResTy == MatchOperand_ParseFail)
5743 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
5745 switch (getLexer().getKind()) {
5746 case AsmToken::Dollar: {
5747 // Parse the register.
5748 SMLoc S = Parser.getTok().getLoc();
5750 // Almost all registers have been parsed by custom parsers. There is only
5751 // one exception to this. $zero (and it's alias $0) will reach this point
5752 // for div, divu, and similar instructions because it is not an operand
5753 // to the instruction definition but an explicit register. Special case
5754 // this situation for now.
5755 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5758 // Maybe it is a symbol reference.
5759 StringRef Identifier;
5760 if (Parser.parseIdentifier(Identifier))
5763 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5764 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5765 // Otherwise create a symbol reference.
5767 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5769 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5773 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
5776 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5777 if (getParser().parseExpression(Expr))
5780 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5782 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5785 } // switch(getLexer().getKind())
5789 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5790 switch (Expr->getKind()) {
5791 case MCExpr::Constant:
5793 case MCExpr::SymbolRef:
5794 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5795 case MCExpr::Binary: {
5796 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
5797 if (!isEvaluated(BE->getLHS()))
5799 return isEvaluated(BE->getRHS());
5802 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5803 case MCExpr::Target:
5809 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5811 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5812 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5813 if (ResTy == MatchOperand_Success) {
5814 assert(Operands.size() == 1);
5815 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5816 StartLoc = Operand.getStartLoc();
5817 EndLoc = Operand.getEndLoc();
5819 // AFAIK, we only support numeric registers and named GPR's in CFI
5821 // Don't worry about eating tokens before failing. Using an unrecognised
5822 // register is a parse error.
5823 if (Operand.isGPRAsmReg()) {
5824 // Resolve to GPR32 or GPR64 appropriately.
5825 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5828 return (RegNo == (unsigned)-1);
5831 assert(Operands.size() == 0);
5832 return (RegNo == (unsigned)-1);
5835 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5839 return getParser().parseParenExprOfDepth(0, Res, S);
5840 return getParser().parseExpression(Res);
5843 OperandMatchResultTy
5844 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5845 MCAsmParser &Parser = getParser();
5846 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
5847 const MCExpr *IdVal = nullptr;
5849 bool isParenExpr = false;
5850 OperandMatchResultTy Res = MatchOperand_NoMatch;
5851 // First operand is the offset.
5852 S = Parser.getTok().getLoc();
5854 if (getLexer().getKind() == AsmToken::LParen) {
5859 if (getLexer().getKind() != AsmToken::Dollar) {
5860 if (parseMemOffset(IdVal, isParenExpr))
5861 return MatchOperand_ParseFail;
5863 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5864 if (Tok.isNot(AsmToken::LParen)) {
5865 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5866 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5868 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5869 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5870 return MatchOperand_Success;
5872 if (Tok.is(AsmToken::EndOfStatement)) {
5874 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5876 // Zero register assumed, add a memory operand with ZERO as its base.
5877 // "Base" will be managed by k_Memory.
5878 auto Base = MipsOperand::createGPRReg(
5879 0, "0", getContext().getRegisterInfo(), S, E, *this);
5881 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5882 return MatchOperand_Success;
5884 MCBinaryExpr::Opcode Opcode;
5885 // GAS and LLVM treat comparison operators different. GAS will generate -1
5886 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5887 // highly unlikely to be found in a memory offset expression, we don't
5889 switch (Tok.getKind()) {
5890 case AsmToken::Plus:
5891 Opcode = MCBinaryExpr::Add;
5894 case AsmToken::Minus:
5895 Opcode = MCBinaryExpr::Sub;
5898 case AsmToken::Star:
5899 Opcode = MCBinaryExpr::Mul;
5902 case AsmToken::Pipe:
5903 Opcode = MCBinaryExpr::Or;
5907 Opcode = MCBinaryExpr::And;
5910 case AsmToken::LessLess:
5911 Opcode = MCBinaryExpr::Shl;
5914 case AsmToken::GreaterGreater:
5915 Opcode = MCBinaryExpr::LShr;
5918 case AsmToken::Caret:
5919 Opcode = MCBinaryExpr::Xor;
5922 case AsmToken::Slash:
5923 Opcode = MCBinaryExpr::Div;
5926 case AsmToken::Percent:
5927 Opcode = MCBinaryExpr::Mod;
5931 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5932 return MatchOperand_ParseFail;
5934 const MCExpr * NextExpr;
5935 if (getParser().parseExpression(NextExpr))
5936 return MatchOperand_ParseFail;
5937 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5940 Parser.Lex(); // Eat the '(' token.
5943 Res = parseAnyRegister(Operands);
5944 if (Res != MatchOperand_Success)
5947 if (Parser.getTok().isNot(AsmToken::RParen)) {
5948 Error(Parser.getTok().getLoc(), "')' expected");
5949 return MatchOperand_ParseFail;
5952 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5954 Parser.Lex(); // Eat the ')' token.
5957 IdVal = MCConstantExpr::create(0, getContext());
5959 // Replace the register operand with the memory operand.
5960 std::unique_ptr<MipsOperand> op(
5961 static_cast<MipsOperand *>(Operands.back().release()));
5962 // Remove the register from the operands.
5963 // "op" will be managed by k_Memory.
5964 Operands.pop_back();
5965 // Add the memory operand.
5966 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5968 if (IdVal->evaluateAsAbsolute(Imm))
5969 IdVal = MCConstantExpr::create(Imm, getContext());
5970 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5971 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5975 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5976 return MatchOperand_Success;
5979 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5980 MCAsmParser &Parser = getParser();
5981 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5985 SMLoc S = Parser.getTok().getLoc();
5986 if (Sym->isVariable()) {
5987 const MCExpr *Expr = Sym->getVariableValue();
5988 if (Expr->getKind() == MCExpr::SymbolRef) {
5989 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5990 StringRef DefSymbol = Ref->getSymbol().getName();
5991 if (DefSymbol.startswith("$")) {
5992 OperandMatchResultTy ResTy =
5993 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5994 if (ResTy == MatchOperand_Success) {
5998 if (ResTy == MatchOperand_ParseFail)
5999 llvm_unreachable("Should never ParseFail");
6002 } else if (Sym->isUnset()) {
6003 // If symbol is unset, it might be created in the `parseSetAssignment`
6004 // routine as an alias for a numeric register name.
6005 // Lookup in the aliases list.
6006 auto Entry = RegisterSets.find(Sym->getName());
6007 if (Entry != RegisterSets.end()) {
6008 OperandMatchResultTy ResTy =
6009 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6010 if (ResTy == MatchOperand_Success) {
6020 OperandMatchResultTy
6021 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6022 StringRef Identifier,
6024 int Index = matchCPURegisterName(Identifier);
6026 Operands.push_back(MipsOperand::createGPRReg(
6027 Index, Identifier, getContext().getRegisterInfo(), S,
6028 getLexer().getLoc(), *this));
6029 return MatchOperand_Success;
6032 Index = matchHWRegsRegisterName(Identifier);
6034 Operands.push_back(MipsOperand::createHWRegsReg(
6035 Index, Identifier, getContext().getRegisterInfo(), S,
6036 getLexer().getLoc(), *this));
6037 return MatchOperand_Success;
6040 Index = matchFPURegisterName(Identifier);
6042 Operands.push_back(MipsOperand::createFGRReg(
6043 Index, Identifier, getContext().getRegisterInfo(), S,
6044 getLexer().getLoc(), *this));
6045 return MatchOperand_Success;
6048 Index = matchFCCRegisterName(Identifier);
6050 Operands.push_back(MipsOperand::createFCCReg(
6051 Index, Identifier, getContext().getRegisterInfo(), S,
6052 getLexer().getLoc(), *this));
6053 return MatchOperand_Success;
6056 Index = matchACRegisterName(Identifier);
6058 Operands.push_back(MipsOperand::createACCReg(
6059 Index, Identifier, getContext().getRegisterInfo(), S,
6060 getLexer().getLoc(), *this));
6061 return MatchOperand_Success;
6064 Index = matchMSA128RegisterName(Identifier);
6066 Operands.push_back(MipsOperand::createMSA128Reg(
6067 Index, Identifier, getContext().getRegisterInfo(), S,
6068 getLexer().getLoc(), *this));
6069 return MatchOperand_Success;
6072 Index = matchMSA128CtrlRegisterName(Identifier);
6074 Operands.push_back(MipsOperand::createMSACtrlReg(
6075 Index, Identifier, getContext().getRegisterInfo(), S,
6076 getLexer().getLoc(), *this));
6077 return MatchOperand_Success;
6080 return MatchOperand_NoMatch;
6083 OperandMatchResultTy
6084 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6085 const AsmToken &Token, SMLoc S) {
6086 if (Token.is(AsmToken::Identifier)) {
6087 LLVM_DEBUG(dbgs() << ".. identifier\n");
6088 StringRef Identifier = Token.getIdentifier();
6089 OperandMatchResultTy ResTy =
6090 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6092 } else if (Token.is(AsmToken::Integer)) {
6093 LLVM_DEBUG(dbgs() << ".. integer\n");
6094 int64_t RegNum = Token.getIntVal();
6095 if (RegNum < 0 || RegNum > 31) {
6096 // Show the error, but treat invalid register
6097 // number as a normal one to continue parsing
6098 // and catch other possible errors.
6099 Error(getLexer().getLoc(), "invalid register number");
6101 Operands.push_back(MipsOperand::createNumericReg(
6102 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6103 Token.getLoc(), *this));
6104 return MatchOperand_Success;
6107 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6109 return MatchOperand_NoMatch;
6112 OperandMatchResultTy
6113 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6114 auto Token = getLexer().peekTok(false);
6115 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6118 OperandMatchResultTy
6119 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6120 MCAsmParser &Parser = getParser();
6121 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6123 auto Token = Parser.getTok();
6125 SMLoc S = Token.getLoc();
6127 if (Token.isNot(AsmToken::Dollar)) {
6128 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6129 if (Token.is(AsmToken::Identifier)) {
6130 if (searchSymbolAlias(Operands))
6131 return MatchOperand_Success;
6133 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6134 return MatchOperand_NoMatch;
6136 LLVM_DEBUG(dbgs() << ".. $\n");
6138 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6139 if (ResTy == MatchOperand_Success) {
6141 Parser.Lex(); // identifier
6146 OperandMatchResultTy
6147 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6148 MCAsmParser &Parser = getParser();
6149 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6151 SMLoc S = getLexer().getLoc();
6153 // Registers are a valid target and have priority over symbols.
6154 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6155 if (ResTy != MatchOperand_NoMatch)
6158 // Integers and expressions are acceptable
6159 const MCExpr *Expr = nullptr;
6160 if (Parser.parseExpression(Expr)) {
6161 // We have no way of knowing if a symbol was consumed so we must ParseFail
6162 return MatchOperand_ParseFail;
6165 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6166 return MatchOperand_Success;
6169 OperandMatchResultTy
6170 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6171 MCAsmParser &Parser = getParser();
6172 const MCExpr *IdVal;
6173 // If the first token is '$' we may have register operand. We have to reject
6174 // cases where it is not a register. Complicating the matter is that
6175 // register names are not reserved across all ABIs.
6176 // Peek past the dollar to see if it's a register name for this ABI.
6177 SMLoc S = Parser.getTok().getLoc();
6178 if (Parser.getTok().is(AsmToken::Dollar)) {
6179 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6180 ? MatchOperand_ParseFail
6181 : MatchOperand_NoMatch;
6183 if (getParser().parseExpression(IdVal))
6184 return MatchOperand_ParseFail;
6185 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6187 return MatchOperand_NoMatch;
6188 int64_t Val = MCE->getValue();
6189 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6190 Operands.push_back(MipsOperand::CreateImm(
6191 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6192 return MatchOperand_Success;
6195 OperandMatchResultTy
6196 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6197 MCAsmParser &Parser = getParser();
6198 SmallVector<unsigned, 10> Regs;
6200 unsigned PrevReg = Mips::NoRegister;
6201 bool RegRange = false;
6202 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6204 if (Parser.getTok().isNot(AsmToken::Dollar))
6205 return MatchOperand_ParseFail;
6207 SMLoc S = Parser.getTok().getLoc();
6208 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6209 SMLoc E = getLexer().getLoc();
6210 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6211 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6213 // Remove last register operand because registers from register range
6214 // should be inserted first.
6215 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6216 (!isGP64bit() && RegNo == Mips::RA)) {
6217 Regs.push_back(RegNo);
6219 unsigned TmpReg = PrevReg + 1;
6220 while (TmpReg <= RegNo) {
6221 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6222 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6224 Error(E, "invalid register operand");
6225 return MatchOperand_ParseFail;
6229 Regs.push_back(TmpReg++);
6235 if ((PrevReg == Mips::NoRegister) &&
6236 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6237 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6238 Error(E, "$16 or $31 expected");
6239 return MatchOperand_ParseFail;
6240 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6241 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6243 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6244 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6246 Error(E, "invalid register operand");
6247 return MatchOperand_ParseFail;
6248 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6249 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6250 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6252 Error(E, "consecutive register numbers expected");
6253 return MatchOperand_ParseFail;
6256 Regs.push_back(RegNo);
6259 if (Parser.getTok().is(AsmToken::Minus))
6262 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6263 !Parser.getTok().isNot(AsmToken::Comma)) {
6264 Error(E, "',' or '-' expected");
6265 return MatchOperand_ParseFail;
6268 Lex(); // Consume comma or minus
6269 if (Parser.getTok().isNot(AsmToken::Dollar))
6275 SMLoc E = Parser.getTok().getLoc();
6276 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6277 parseMemOperand(Operands);
6278 return MatchOperand_Success;
6281 OperandMatchResultTy
6282 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
6283 MCAsmParser &Parser = getParser();
6284 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6285 SmallVector<unsigned, 10> Regs;
6287 if (Parser.getTok().isNot(AsmToken::Dollar))
6288 return MatchOperand_ParseFail;
6290 SMLoc S = Parser.getTok().getLoc();
6292 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6293 return MatchOperand_ParseFail;
6295 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
6296 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6297 Regs.push_back(RegNo);
6299 SMLoc E = Parser.getTok().getLoc();
6300 if (Parser.getTok().isNot(AsmToken::Comma)) {
6301 Error(E, "',' expected");
6302 return MatchOperand_ParseFail;
6308 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
6309 return MatchOperand_ParseFail;
6311 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
6312 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
6313 Regs.push_back(RegNo);
6315 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6317 return MatchOperand_Success;
6320 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6322 /// ::= '(', register, ')'
6323 /// handle it before we iterate so we don't get tripped up by the lack of
6325 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6326 MCAsmParser &Parser = getParser();
6327 if (getLexer().is(AsmToken::LParen)) {
6329 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6331 if (parseOperand(Operands, Name)) {
6332 SMLoc Loc = getLexer().getLoc();
6333 return Error(Loc, "unexpected token in argument list");
6335 if (Parser.getTok().isNot(AsmToken::RParen)) {
6336 SMLoc Loc = getLexer().getLoc();
6337 return Error(Loc, "unexpected token, expected ')'");
6340 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6346 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6347 /// either one of these.
6348 /// ::= '[', register, ']'
6349 /// ::= '[', integer, ']'
6350 /// handle it before we iterate so we don't get tripped up by the lack of
6352 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6353 OperandVector &Operands) {
6354 MCAsmParser &Parser = getParser();
6355 if (getLexer().is(AsmToken::LBrac)) {
6357 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6359 if (parseOperand(Operands, Name)) {
6360 SMLoc Loc = getLexer().getLoc();
6361 return Error(Loc, "unexpected token in argument list");
6363 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6364 SMLoc Loc = getLexer().getLoc();
6365 return Error(Loc, "unexpected token, expected ']'");
6368 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6374 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6375 SMLoc NameLoc, OperandVector &Operands) {
6376 MCAsmParser &Parser = getParser();
6377 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6379 // We have reached first instruction, module directive are now forbidden.
6380 getTargetStreamer().forbidModuleDirective();
6382 // Check if we have valid mnemonic
6383 if (!mnemonicIsValid(Name, 0)) {
6384 return Error(NameLoc, "unknown instruction");
6386 // First operand in MCInst is instruction mnemonic.
6387 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6389 // Read the remaining operands.
6390 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6391 // Read the first operand.
6392 if (parseOperand(Operands, Name)) {
6393 SMLoc Loc = getLexer().getLoc();
6394 return Error(Loc, "unexpected token in argument list");
6396 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6398 // AFAIK, parenthesis suffixes are never on the first operand
6400 while (getLexer().is(AsmToken::Comma)) {
6401 Parser.Lex(); // Eat the comma.
6402 // Parse and remember the operand.
6403 if (parseOperand(Operands, Name)) {
6404 SMLoc Loc = getLexer().getLoc();
6405 return Error(Loc, "unexpected token in argument list");
6407 // Parse bracket and parenthesis suffixes before we iterate
6408 if (getLexer().is(AsmToken::LBrac)) {
6409 if (parseBracketSuffix(Name, Operands))
6411 } else if (getLexer().is(AsmToken::LParen) &&
6412 parseParenSuffix(Name, Operands))
6416 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6417 SMLoc Loc = getLexer().getLoc();
6418 return Error(Loc, "unexpected token in argument list");
6420 Parser.Lex(); // Consume the EndOfStatement.
6424 // FIXME: Given that these have the same name, these should both be
6425 // consistent on affecting the Parser.
6426 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6427 SMLoc Loc = getLexer().getLoc();
6428 return Error(Loc, ErrorMsg);
6431 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6432 return Error(Loc, ErrorMsg);
6435 bool MipsAsmParser::parseSetNoAtDirective() {
6436 MCAsmParser &Parser = getParser();
6437 // Line should look like: ".set noat".
6439 // Set the $at register to $0.
6440 AssemblerOptions.back()->setATRegIndex(0);
6442 Parser.Lex(); // Eat "noat".
6444 // If this is not the end of the statement, report an error.
6445 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6446 reportParseError("unexpected token, expected end of statement");
6450 getTargetStreamer().emitDirectiveSetNoAt();
6451 Parser.Lex(); // Consume the EndOfStatement.
6455 bool MipsAsmParser::parseSetAtDirective() {
6456 // Line can be: ".set at", which sets $at to $1
6457 // or ".set at=$reg", which sets $at to $reg.
6458 MCAsmParser &Parser = getParser();
6459 Parser.Lex(); // Eat "at".
6461 if (getLexer().is(AsmToken::EndOfStatement)) {
6462 // No register was specified, so we set $at to $1.
6463 AssemblerOptions.back()->setATRegIndex(1);
6465 getTargetStreamer().emitDirectiveSetAt();
6466 Parser.Lex(); // Consume the EndOfStatement.
6470 if (getLexer().isNot(AsmToken::Equal)) {
6471 reportParseError("unexpected token, expected equals sign");
6474 Parser.Lex(); // Eat "=".
6476 if (getLexer().isNot(AsmToken::Dollar)) {
6477 if (getLexer().is(AsmToken::EndOfStatement)) {
6478 reportParseError("no register specified");
6481 reportParseError("unexpected token, expected dollar sign '$'");
6485 Parser.Lex(); // Eat "$".
6487 // Find out what "reg" is.
6489 const AsmToken &Reg = Parser.getTok();
6490 if (Reg.is(AsmToken::Identifier)) {
6491 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6492 } else if (Reg.is(AsmToken::Integer)) {
6493 AtRegNo = Reg.getIntVal();
6495 reportParseError("unexpected token, expected identifier or integer");
6499 // Check if $reg is a valid register. If it is, set $at to $reg.
6500 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6501 reportParseError("invalid register");
6504 Parser.Lex(); // Eat "reg".
6506 // If this is not the end of the statement, report an error.
6507 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6508 reportParseError("unexpected token, expected end of statement");
6512 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6514 Parser.Lex(); // Consume the EndOfStatement.
6518 bool MipsAsmParser::parseSetReorderDirective() {
6519 MCAsmParser &Parser = getParser();
6521 // If this is not the end of the statement, report an error.
6522 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6523 reportParseError("unexpected token, expected end of statement");
6526 AssemblerOptions.back()->setReorder();
6527 getTargetStreamer().emitDirectiveSetReorder();
6528 Parser.Lex(); // Consume the EndOfStatement.
6532 bool MipsAsmParser::parseSetNoReorderDirective() {
6533 MCAsmParser &Parser = getParser();
6535 // If this is not the end of the statement, report an error.
6536 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6537 reportParseError("unexpected token, expected end of statement");
6540 AssemblerOptions.back()->setNoReorder();
6541 getTargetStreamer().emitDirectiveSetNoReorder();
6542 Parser.Lex(); // Consume the EndOfStatement.
6546 bool MipsAsmParser::parseSetMacroDirective() {
6547 MCAsmParser &Parser = getParser();
6549 // If this is not the end of the statement, report an error.
6550 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6551 reportParseError("unexpected token, expected end of statement");
6554 AssemblerOptions.back()->setMacro();
6555 getTargetStreamer().emitDirectiveSetMacro();
6556 Parser.Lex(); // Consume the EndOfStatement.
6560 bool MipsAsmParser::parseSetNoMacroDirective() {
6561 MCAsmParser &Parser = getParser();
6563 // If this is not the end of the statement, report an error.
6564 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6565 reportParseError("unexpected token, expected end of statement");
6568 if (AssemblerOptions.back()->isReorder()) {
6569 reportParseError("`noreorder' must be set before `nomacro'");
6572 AssemblerOptions.back()->setNoMacro();
6573 getTargetStreamer().emitDirectiveSetNoMacro();
6574 Parser.Lex(); // Consume the EndOfStatement.
6578 bool MipsAsmParser::parseSetMsaDirective() {
6579 MCAsmParser &Parser = getParser();
6582 // If this is not the end of the statement, report an error.
6583 if (getLexer().isNot(AsmToken::EndOfStatement))
6584 return reportParseError("unexpected token, expected end of statement");
6586 setFeatureBits(Mips::FeatureMSA, "msa");
6587 getTargetStreamer().emitDirectiveSetMsa();
6591 bool MipsAsmParser::parseSetNoMsaDirective() {
6592 MCAsmParser &Parser = getParser();
6595 // If this is not the end of the statement, report an error.
6596 if (getLexer().isNot(AsmToken::EndOfStatement))
6597 return reportParseError("unexpected token, expected end of statement");
6599 clearFeatureBits(Mips::FeatureMSA, "msa");
6600 getTargetStreamer().emitDirectiveSetNoMsa();
6604 bool MipsAsmParser::parseSetNoDspDirective() {
6605 MCAsmParser &Parser = getParser();
6606 Parser.Lex(); // Eat "nodsp".
6608 // If this is not the end of the statement, report an error.
6609 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6610 reportParseError("unexpected token, expected end of statement");
6614 clearFeatureBits(Mips::FeatureDSP, "dsp");
6615 getTargetStreamer().emitDirectiveSetNoDsp();
6619 bool MipsAsmParser::parseSetMips16Directive() {
6620 MCAsmParser &Parser = getParser();
6621 Parser.Lex(); // Eat "mips16".
6623 // If this is not the end of the statement, report an error.
6624 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6625 reportParseError("unexpected token, expected end of statement");
6629 setFeatureBits(Mips::FeatureMips16, "mips16");
6630 getTargetStreamer().emitDirectiveSetMips16();
6631 Parser.Lex(); // Consume the EndOfStatement.
6635 bool MipsAsmParser::parseSetNoMips16Directive() {
6636 MCAsmParser &Parser = getParser();
6637 Parser.Lex(); // Eat "nomips16".
6639 // If this is not the end of the statement, report an error.
6640 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6641 reportParseError("unexpected token, expected end of statement");
6645 clearFeatureBits(Mips::FeatureMips16, "mips16");
6646 getTargetStreamer().emitDirectiveSetNoMips16();
6647 Parser.Lex(); // Consume the EndOfStatement.
6651 bool MipsAsmParser::parseSetFpDirective() {
6652 MCAsmParser &Parser = getParser();
6653 MipsABIFlagsSection::FpABIKind FpAbiVal;
6654 // Line can be: .set fp=32
6657 Parser.Lex(); // Eat fp token
6658 AsmToken Tok = Parser.getTok();
6659 if (Tok.isNot(AsmToken::Equal)) {
6660 reportParseError("unexpected token, expected equals sign '='");
6663 Parser.Lex(); // Eat '=' token.
6664 Tok = Parser.getTok();
6666 if (!parseFpABIValue(FpAbiVal, ".set"))
6669 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6670 reportParseError("unexpected token, expected end of statement");
6673 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6674 Parser.Lex(); // Consume the EndOfStatement.
6678 bool MipsAsmParser::parseSetOddSPRegDirective() {
6679 MCAsmParser &Parser = getParser();
6681 Parser.Lex(); // Eat "oddspreg".
6682 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6683 reportParseError("unexpected token, expected end of statement");
6687 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6688 getTargetStreamer().emitDirectiveSetOddSPReg();
6692 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6693 MCAsmParser &Parser = getParser();
6695 Parser.Lex(); // Eat "nooddspreg".
6696 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6697 reportParseError("unexpected token, expected end of statement");
6701 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6702 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6706 bool MipsAsmParser::parseSetMtDirective() {
6707 MCAsmParser &Parser = getParser();
6708 Parser.Lex(); // Eat "mt".
6710 // If this is not the end of the statement, report an error.
6711 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6712 reportParseError("unexpected token, expected end of statement");
6716 setFeatureBits(Mips::FeatureMT, "mt");
6717 getTargetStreamer().emitDirectiveSetMt();
6718 Parser.Lex(); // Consume the EndOfStatement.
6722 bool MipsAsmParser::parseSetNoMtDirective() {
6723 MCAsmParser &Parser = getParser();
6724 Parser.Lex(); // Eat "nomt".
6726 // If this is not the end of the statement, report an error.
6727 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6728 reportParseError("unexpected token, expected end of statement");
6732 clearFeatureBits(Mips::FeatureMT, "mt");
6734 getTargetStreamer().emitDirectiveSetNoMt();
6735 Parser.Lex(); // Consume the EndOfStatement.
6739 bool MipsAsmParser::parseSetNoCRCDirective() {
6740 MCAsmParser &Parser = getParser();
6741 Parser.Lex(); // Eat "nocrc".
6743 // If this is not the end of the statement, report an error.
6744 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6745 reportParseError("unexpected token, expected end of statement");
6749 clearFeatureBits(Mips::FeatureCRC, "crc");
6751 getTargetStreamer().emitDirectiveSetNoCRC();
6752 Parser.Lex(); // Consume the EndOfStatement.
6756 bool MipsAsmParser::parseSetNoVirtDirective() {
6757 MCAsmParser &Parser = getParser();
6758 Parser.Lex(); // Eat "novirt".
6760 // If this is not the end of the statement, report an error.
6761 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6762 reportParseError("unexpected token, expected end of statement");
6766 clearFeatureBits(Mips::FeatureVirt, "virt");
6768 getTargetStreamer().emitDirectiveSetNoVirt();
6769 Parser.Lex(); // Consume the EndOfStatement.
6773 bool MipsAsmParser::parseSetNoGINVDirective() {
6774 MCAsmParser &Parser = getParser();
6775 Parser.Lex(); // Eat "noginv".
6777 // If this is not the end of the statement, report an error.
6778 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6779 reportParseError("unexpected token, expected end of statement");
6783 clearFeatureBits(Mips::FeatureGINV, "ginv");
6785 getTargetStreamer().emitDirectiveSetNoGINV();
6786 Parser.Lex(); // Consume the EndOfStatement.
6790 bool MipsAsmParser::parseSetPopDirective() {
6791 MCAsmParser &Parser = getParser();
6792 SMLoc Loc = getLexer().getLoc();
6795 if (getLexer().isNot(AsmToken::EndOfStatement))
6796 return reportParseError("unexpected token, expected end of statement");
6798 // Always keep an element on the options "stack" to prevent the user
6799 // from changing the initial options. This is how we remember them.
6800 if (AssemblerOptions.size() == 2)
6801 return reportParseError(Loc, ".set pop with no .set push");
6803 MCSubtargetInfo &STI = copySTI();
6804 AssemblerOptions.pop_back();
6805 setAvailableFeatures(
6806 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6807 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6809 getTargetStreamer().emitDirectiveSetPop();
6813 bool MipsAsmParser::parseSetPushDirective() {
6814 MCAsmParser &Parser = getParser();
6816 if (getLexer().isNot(AsmToken::EndOfStatement))
6817 return reportParseError("unexpected token, expected end of statement");
6819 // Create a copy of the current assembler options environment and push it.
6820 AssemblerOptions.push_back(
6821 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6823 getTargetStreamer().emitDirectiveSetPush();
6827 bool MipsAsmParser::parseSetSoftFloatDirective() {
6828 MCAsmParser &Parser = getParser();
6830 if (getLexer().isNot(AsmToken::EndOfStatement))
6831 return reportParseError("unexpected token, expected end of statement");
6833 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6834 getTargetStreamer().emitDirectiveSetSoftFloat();
6838 bool MipsAsmParser::parseSetHardFloatDirective() {
6839 MCAsmParser &Parser = getParser();
6841 if (getLexer().isNot(AsmToken::EndOfStatement))
6842 return reportParseError("unexpected token, expected end of statement");
6844 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6845 getTargetStreamer().emitDirectiveSetHardFloat();
6849 bool MipsAsmParser::parseSetAssignment() {
6851 const MCExpr *Value;
6852 MCAsmParser &Parser = getParser();
6854 if (Parser.parseIdentifier(Name))
6855 return reportParseError("expected identifier after .set");
6857 if (getLexer().isNot(AsmToken::Comma))
6858 return reportParseError("unexpected token, expected comma");
6861 if (getLexer().is(AsmToken::Dollar) &&
6862 getLexer().peekTok().is(AsmToken::Integer)) {
6863 // Parse assignment of a numeric register:
6865 Parser.Lex(); // Eat $.
6866 RegisterSets[Name] = Parser.getTok();
6867 Parser.Lex(); // Eat identifier.
6868 getContext().getOrCreateSymbol(Name);
6869 } else if (!Parser.parseExpression(Value)) {
6870 // Parse assignment of an expression including
6871 // symbolic registers:
6872 // .set $tmp, $BB0-$BB1
6874 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6875 Sym->setVariableValue(Value);
6877 return reportParseError("expected valid expression after comma");
6883 bool MipsAsmParser::parseSetMips0Directive() {
6884 MCAsmParser &Parser = getParser();
6886 if (getLexer().isNot(AsmToken::EndOfStatement))
6887 return reportParseError("unexpected token, expected end of statement");
6889 // Reset assembler options to their initial values.
6890 MCSubtargetInfo &STI = copySTI();
6891 setAvailableFeatures(
6892 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6893 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6894 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6896 getTargetStreamer().emitDirectiveSetMips0();
6900 bool MipsAsmParser::parseSetArchDirective() {
6901 MCAsmParser &Parser = getParser();
6903 if (getLexer().isNot(AsmToken::Equal))
6904 return reportParseError("unexpected token, expected equals sign");
6908 if (Parser.parseIdentifier(Arch))
6909 return reportParseError("expected arch identifier");
6911 StringRef ArchFeatureName =
6912 StringSwitch<StringRef>(Arch)
6913 .Case("mips1", "mips1")
6914 .Case("mips2", "mips2")
6915 .Case("mips3", "mips3")
6916 .Case("mips4", "mips4")
6917 .Case("mips5", "mips5")
6918 .Case("mips32", "mips32")
6919 .Case("mips32r2", "mips32r2")
6920 .Case("mips32r3", "mips32r3")
6921 .Case("mips32r5", "mips32r5")
6922 .Case("mips32r6", "mips32r6")
6923 .Case("mips64", "mips64")
6924 .Case("mips64r2", "mips64r2")
6925 .Case("mips64r3", "mips64r3")
6926 .Case("mips64r5", "mips64r5")
6927 .Case("mips64r6", "mips64r6")
6928 .Case("octeon", "cnmips")
6929 .Case("r4000", "mips3") // This is an implementation of Mips3.
6932 if (ArchFeatureName.empty())
6933 return reportParseError("unsupported architecture");
6935 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
6936 return reportParseError("mips64r6 does not support microMIPS");
6938 selectArch(ArchFeatureName);
6939 getTargetStreamer().emitDirectiveSetArch(Arch);
6943 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6944 MCAsmParser &Parser = getParser();
6946 if (getLexer().isNot(AsmToken::EndOfStatement))
6947 return reportParseError("unexpected token, expected end of statement");
6951 llvm_unreachable("Unimplemented feature");
6952 case Mips::FeatureDSP:
6953 setFeatureBits(Mips::FeatureDSP, "dsp");
6954 getTargetStreamer().emitDirectiveSetDsp();
6956 case Mips::FeatureDSPR2:
6957 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
6958 getTargetStreamer().emitDirectiveSetDspr2();
6960 case Mips::FeatureMicroMips:
6961 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6962 getTargetStreamer().emitDirectiveSetMicroMips();
6964 case Mips::FeatureMips1:
6965 selectArch("mips1");
6966 getTargetStreamer().emitDirectiveSetMips1();
6968 case Mips::FeatureMips2:
6969 selectArch("mips2");
6970 getTargetStreamer().emitDirectiveSetMips2();
6972 case Mips::FeatureMips3:
6973 selectArch("mips3");
6974 getTargetStreamer().emitDirectiveSetMips3();
6976 case Mips::FeatureMips4:
6977 selectArch("mips4");
6978 getTargetStreamer().emitDirectiveSetMips4();
6980 case Mips::FeatureMips5:
6981 selectArch("mips5");
6982 getTargetStreamer().emitDirectiveSetMips5();
6984 case Mips::FeatureMips32:
6985 selectArch("mips32");
6986 getTargetStreamer().emitDirectiveSetMips32();
6988 case Mips::FeatureMips32r2:
6989 selectArch("mips32r2");
6990 getTargetStreamer().emitDirectiveSetMips32R2();
6992 case Mips::FeatureMips32r3:
6993 selectArch("mips32r3");
6994 getTargetStreamer().emitDirectiveSetMips32R3();
6996 case Mips::FeatureMips32r5:
6997 selectArch("mips32r5");
6998 getTargetStreamer().emitDirectiveSetMips32R5();
7000 case Mips::FeatureMips32r6:
7001 selectArch("mips32r6");
7002 getTargetStreamer().emitDirectiveSetMips32R6();
7004 case Mips::FeatureMips64:
7005 selectArch("mips64");
7006 getTargetStreamer().emitDirectiveSetMips64();
7008 case Mips::FeatureMips64r2:
7009 selectArch("mips64r2");
7010 getTargetStreamer().emitDirectiveSetMips64R2();
7012 case Mips::FeatureMips64r3:
7013 selectArch("mips64r3");
7014 getTargetStreamer().emitDirectiveSetMips64R3();
7016 case Mips::FeatureMips64r5:
7017 selectArch("mips64r5");
7018 getTargetStreamer().emitDirectiveSetMips64R5();
7020 case Mips::FeatureMips64r6:
7021 selectArch("mips64r6");
7022 getTargetStreamer().emitDirectiveSetMips64R6();
7024 case Mips::FeatureCRC:
7025 setFeatureBits(Mips::FeatureCRC, "crc");
7026 getTargetStreamer().emitDirectiveSetCRC();
7028 case Mips::FeatureVirt:
7029 setFeatureBits(Mips::FeatureVirt, "virt");
7030 getTargetStreamer().emitDirectiveSetVirt();
7032 case Mips::FeatureGINV:
7033 setFeatureBits(Mips::FeatureGINV, "ginv");
7034 getTargetStreamer().emitDirectiveSetGINV();
7040 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7041 MCAsmParser &Parser = getParser();
7042 if (getLexer().isNot(AsmToken::Comma)) {
7043 SMLoc Loc = getLexer().getLoc();
7044 return Error(Loc, ErrorStr);
7047 Parser.Lex(); // Eat the comma.
7051 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7052 // In this class, it is only used for .cprestore.
7053 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7054 // MipsTargetELFStreamer and MipsAsmParser.
7055 bool MipsAsmParser::isPicAndNotNxxAbi() {
7056 return inPicMode() && !(isABI_N32() || isABI_N64());
7059 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7060 if (AssemblerOptions.back()->isReorder())
7061 Warning(Loc, ".cpload should be inside a noreorder section");
7063 if (inMips16Mode()) {
7064 reportParseError(".cpload is not supported in Mips16 mode");
7068 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7069 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7070 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7071 reportParseError("expected register containing function address");
7075 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7076 if (!RegOpnd.isGPRAsmReg()) {
7077 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7081 // If this is not the end of the statement, report an error.
7082 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7083 reportParseError("unexpected token, expected end of statement");
7087 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7091 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7092 MCAsmParser &Parser = getParser();
7094 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7095 // is used in non-PIC mode.
7097 if (inMips16Mode()) {
7098 reportParseError(".cprestore is not supported in Mips16 mode");
7102 // Get the stack offset value.
7103 const MCExpr *StackOffset;
7104 int64_t StackOffsetVal;
7105 if (Parser.parseExpression(StackOffset)) {
7106 reportParseError("expected stack offset value");
7110 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7111 reportParseError("stack offset is not an absolute expression");
7115 if (StackOffsetVal < 0) {
7116 Warning(Loc, ".cprestore with negative stack offset has no effect");
7117 IsCpRestoreSet = false;
7119 IsCpRestoreSet = true;
7120 CpRestoreOffset = StackOffsetVal;
7123 // If this is not the end of the statement, report an error.
7124 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7125 reportParseError("unexpected token, expected end of statement");
7129 if (!getTargetStreamer().emitDirectiveCpRestore(
7130 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7132 Parser.Lex(); // Consume the EndOfStatement.
7136 bool MipsAsmParser::parseDirectiveCPSetup() {
7137 MCAsmParser &Parser = getParser();
7140 bool SaveIsReg = true;
7142 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7143 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7144 if (ResTy == MatchOperand_NoMatch) {
7145 reportParseError("expected register containing function address");
7149 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7150 if (!FuncRegOpnd.isGPRAsmReg()) {
7151 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7155 FuncReg = FuncRegOpnd.getGPR32Reg();
7158 if (!eatComma("unexpected token, expected comma"))
7161 ResTy = parseAnyRegister(TmpReg);
7162 if (ResTy == MatchOperand_NoMatch) {
7163 const MCExpr *OffsetExpr;
7165 SMLoc ExprLoc = getLexer().getLoc();
7167 if (Parser.parseExpression(OffsetExpr) ||
7168 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7169 reportParseError(ExprLoc, "expected save register or stack offset");
7176 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7177 if (!SaveOpnd.isGPRAsmReg()) {
7178 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7181 Save = SaveOpnd.getGPR32Reg();
7184 if (!eatComma("unexpected token, expected comma"))
7188 if (Parser.parseExpression(Expr)) {
7189 reportParseError("expected expression");
7193 if (Expr->getKind() != MCExpr::SymbolRef) {
7194 reportParseError("expected symbol");
7197 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7199 CpSaveLocation = Save;
7200 CpSaveLocationIsRegister = SaveIsReg;
7202 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7207 bool MipsAsmParser::parseDirectiveCPReturn() {
7208 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7209 CpSaveLocationIsRegister);
7213 bool MipsAsmParser::parseDirectiveNaN() {
7214 MCAsmParser &Parser = getParser();
7215 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7216 const AsmToken &Tok = Parser.getTok();
7218 if (Tok.getString() == "2008") {
7220 getTargetStreamer().emitDirectiveNaN2008();
7222 } else if (Tok.getString() == "legacy") {
7224 getTargetStreamer().emitDirectiveNaNLegacy();
7228 // If we don't recognize the option passed to the .nan
7229 // directive (e.g. no option or unknown option), emit an error.
7230 reportParseError("invalid option in .nan directive");
7234 bool MipsAsmParser::parseDirectiveSet() {
7235 const AsmToken &Tok = getParser().getTok();
7236 StringRef IdVal = Tok.getString();
7237 SMLoc Loc = Tok.getLoc();
7239 if (IdVal == "noat")
7240 return parseSetNoAtDirective();
7242 return parseSetAtDirective();
7243 if (IdVal == "arch")
7244 return parseSetArchDirective();
7245 if (IdVal == "bopt") {
7246 Warning(Loc, "'bopt' feature is unsupported");
7250 if (IdVal == "nobopt") {
7251 // We're already running in nobopt mode, so nothing to do.
7256 return parseSetFpDirective();
7257 if (IdVal == "oddspreg")
7258 return parseSetOddSPRegDirective();
7259 if (IdVal == "nooddspreg")
7260 return parseSetNoOddSPRegDirective();
7262 return parseSetPopDirective();
7263 if (IdVal == "push")
7264 return parseSetPushDirective();
7265 if (IdVal == "reorder")
7266 return parseSetReorderDirective();
7267 if (IdVal == "noreorder")
7268 return parseSetNoReorderDirective();
7269 if (IdVal == "macro")
7270 return parseSetMacroDirective();
7271 if (IdVal == "nomacro")
7272 return parseSetNoMacroDirective();
7273 if (IdVal == "mips16")
7274 return parseSetMips16Directive();
7275 if (IdVal == "nomips16")
7276 return parseSetNoMips16Directive();
7277 if (IdVal == "nomicromips") {
7278 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7279 getTargetStreamer().emitDirectiveSetNoMicroMips();
7280 getParser().eatToEndOfStatement();
7283 if (IdVal == "micromips") {
7284 if (hasMips64r6()) {
7285 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7288 return parseSetFeature(Mips::FeatureMicroMips);
7290 if (IdVal == "mips0")
7291 return parseSetMips0Directive();
7292 if (IdVal == "mips1")
7293 return parseSetFeature(Mips::FeatureMips1);
7294 if (IdVal == "mips2")
7295 return parseSetFeature(Mips::FeatureMips2);
7296 if (IdVal == "mips3")
7297 return parseSetFeature(Mips::FeatureMips3);
7298 if (IdVal == "mips4")
7299 return parseSetFeature(Mips::FeatureMips4);
7300 if (IdVal == "mips5")
7301 return parseSetFeature(Mips::FeatureMips5);
7302 if (IdVal == "mips32")
7303 return parseSetFeature(Mips::FeatureMips32);
7304 if (IdVal == "mips32r2")
7305 return parseSetFeature(Mips::FeatureMips32r2);
7306 if (IdVal == "mips32r3")
7307 return parseSetFeature(Mips::FeatureMips32r3);
7308 if (IdVal == "mips32r5")
7309 return parseSetFeature(Mips::FeatureMips32r5);
7310 if (IdVal == "mips32r6")
7311 return parseSetFeature(Mips::FeatureMips32r6);
7312 if (IdVal == "mips64")
7313 return parseSetFeature(Mips::FeatureMips64);
7314 if (IdVal == "mips64r2")
7315 return parseSetFeature(Mips::FeatureMips64r2);
7316 if (IdVal == "mips64r3")
7317 return parseSetFeature(Mips::FeatureMips64r3);
7318 if (IdVal == "mips64r5")
7319 return parseSetFeature(Mips::FeatureMips64r5);
7320 if (IdVal == "mips64r6") {
7321 if (inMicroMipsMode()) {
7322 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7325 return parseSetFeature(Mips::FeatureMips64r6);
7328 return parseSetFeature(Mips::FeatureDSP);
7329 if (IdVal == "dspr2")
7330 return parseSetFeature(Mips::FeatureDSPR2);
7331 if (IdVal == "nodsp")
7332 return parseSetNoDspDirective();
7334 return parseSetMsaDirective();
7335 if (IdVal == "nomsa")
7336 return parseSetNoMsaDirective();
7338 return parseSetMtDirective();
7339 if (IdVal == "nomt")
7340 return parseSetNoMtDirective();
7341 if (IdVal == "softfloat")
7342 return parseSetSoftFloatDirective();
7343 if (IdVal == "hardfloat")
7344 return parseSetHardFloatDirective();
7346 return parseSetFeature(Mips::FeatureCRC);
7347 if (IdVal == "nocrc")
7348 return parseSetNoCRCDirective();
7349 if (IdVal == "virt")
7350 return parseSetFeature(Mips::FeatureVirt);
7351 if (IdVal == "novirt")
7352 return parseSetNoVirtDirective();
7353 if (IdVal == "ginv")
7354 return parseSetFeature(Mips::FeatureGINV);
7355 if (IdVal == "noginv")
7356 return parseSetNoGINVDirective();
7358 // It is just an identifier, look for an assignment.
7359 return parseSetAssignment();
7362 /// parseDirectiveGpWord
7363 /// ::= .gpword local_sym
7364 bool MipsAsmParser::parseDirectiveGpWord() {
7365 MCAsmParser &Parser = getParser();
7366 const MCExpr *Value;
7367 // EmitGPRel32Value requires an expression, so we are using base class
7368 // method to evaluate the expression.
7369 if (getParser().parseExpression(Value))
7371 getParser().getStreamer().EmitGPRel32Value(Value);
7373 if (getLexer().isNot(AsmToken::EndOfStatement))
7374 return Error(getLexer().getLoc(),
7375 "unexpected token, expected end of statement");
7376 Parser.Lex(); // Eat EndOfStatement token.
7380 /// parseDirectiveGpDWord
7381 /// ::= .gpdword local_sym
7382 bool MipsAsmParser::parseDirectiveGpDWord() {
7383 MCAsmParser &Parser = getParser();
7384 const MCExpr *Value;
7385 // EmitGPRel64Value requires an expression, so we are using base class
7386 // method to evaluate the expression.
7387 if (getParser().parseExpression(Value))
7389 getParser().getStreamer().EmitGPRel64Value(Value);
7391 if (getLexer().isNot(AsmToken::EndOfStatement))
7392 return Error(getLexer().getLoc(),
7393 "unexpected token, expected end of statement");
7394 Parser.Lex(); // Eat EndOfStatement token.
7398 /// parseDirectiveDtpRelWord
7399 /// ::= .dtprelword tls_sym
7400 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7401 MCAsmParser &Parser = getParser();
7402 const MCExpr *Value;
7403 // EmitDTPRel32Value requires an expression, so we are using base class
7404 // method to evaluate the expression.
7405 if (getParser().parseExpression(Value))
7407 getParser().getStreamer().EmitDTPRel32Value(Value);
7409 if (getLexer().isNot(AsmToken::EndOfStatement))
7410 return Error(getLexer().getLoc(),
7411 "unexpected token, expected end of statement");
7412 Parser.Lex(); // Eat EndOfStatement token.
7416 /// parseDirectiveDtpRelDWord
7417 /// ::= .dtpreldword tls_sym
7418 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7419 MCAsmParser &Parser = getParser();
7420 const MCExpr *Value;
7421 // EmitDTPRel64Value requires an expression, so we are using base class
7422 // method to evaluate the expression.
7423 if (getParser().parseExpression(Value))
7425 getParser().getStreamer().EmitDTPRel64Value(Value);
7427 if (getLexer().isNot(AsmToken::EndOfStatement))
7428 return Error(getLexer().getLoc(),
7429 "unexpected token, expected end of statement");
7430 Parser.Lex(); // Eat EndOfStatement token.
7434 /// parseDirectiveTpRelWord
7435 /// ::= .tprelword tls_sym
7436 bool MipsAsmParser::parseDirectiveTpRelWord() {
7437 MCAsmParser &Parser = getParser();
7438 const MCExpr *Value;
7439 // EmitTPRel32Value requires an expression, so we are using base class
7440 // method to evaluate the expression.
7441 if (getParser().parseExpression(Value))
7443 getParser().getStreamer().EmitTPRel32Value(Value);
7445 if (getLexer().isNot(AsmToken::EndOfStatement))
7446 return Error(getLexer().getLoc(),
7447 "unexpected token, expected end of statement");
7448 Parser.Lex(); // Eat EndOfStatement token.
7452 /// parseDirectiveTpRelDWord
7453 /// ::= .tpreldword tls_sym
7454 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7455 MCAsmParser &Parser = getParser();
7456 const MCExpr *Value;
7457 // EmitTPRel64Value requires an expression, so we are using base class
7458 // method to evaluate the expression.
7459 if (getParser().parseExpression(Value))
7461 getParser().getStreamer().EmitTPRel64Value(Value);
7463 if (getLexer().isNot(AsmToken::EndOfStatement))
7464 return Error(getLexer().getLoc(),
7465 "unexpected token, expected end of statement");
7466 Parser.Lex(); // Eat EndOfStatement token.
7470 bool MipsAsmParser::parseDirectiveOption() {
7471 MCAsmParser &Parser = getParser();
7472 // Get the option token.
7473 AsmToken Tok = Parser.getTok();
7474 // At the moment only identifiers are supported.
7475 if (Tok.isNot(AsmToken::Identifier)) {
7476 return Error(Parser.getTok().getLoc(),
7477 "unexpected token, expected identifier");
7480 StringRef Option = Tok.getIdentifier();
7482 if (Option == "pic0") {
7483 // MipsAsmParser needs to know if the current PIC mode changes.
7484 IsPicEnabled = false;
7486 getTargetStreamer().emitDirectiveOptionPic0();
7488 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7489 return Error(Parser.getTok().getLoc(),
7490 "unexpected token, expected end of statement");
7495 if (Option == "pic2") {
7496 // MipsAsmParser needs to know if the current PIC mode changes.
7497 IsPicEnabled = true;
7499 getTargetStreamer().emitDirectiveOptionPic2();
7501 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7502 return Error(Parser.getTok().getLoc(),
7503 "unexpected token, expected end of statement");
7509 Warning(Parser.getTok().getLoc(),
7510 "unknown option, expected 'pic0' or 'pic2'");
7511 Parser.eatToEndOfStatement();
7515 /// parseInsnDirective
7517 bool MipsAsmParser::parseInsnDirective() {
7518 // If this is not the end of the statement, report an error.
7519 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7520 reportParseError("unexpected token, expected end of statement");
7524 // The actual label marking happens in
7525 // MipsELFStreamer::createPendingLabelRelocs().
7526 getTargetStreamer().emitDirectiveInsn();
7528 getParser().Lex(); // Eat EndOfStatement token.
7532 /// parseRSectionDirective
7534 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7535 // If this is not the end of the statement, report an error.
7536 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7537 reportParseError("unexpected token, expected end of statement");
7541 MCSection *ELFSection = getContext().getELFSection(
7542 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7543 getParser().getStreamer().SwitchSection(ELFSection);
7545 getParser().Lex(); // Eat EndOfStatement token.
7549 /// parseSSectionDirective
7552 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7553 // If this is not the end of the statement, report an error.
7554 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7555 reportParseError("unexpected token, expected end of statement");
7559 MCSection *ELFSection = getContext().getELFSection(
7560 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7561 getParser().getStreamer().SwitchSection(ELFSection);
7563 getParser().Lex(); // Eat EndOfStatement token.
7567 /// parseDirectiveModule
7568 /// ::= .module oddspreg
7569 /// ::= .module nooddspreg
7570 /// ::= .module fp=value
7571 /// ::= .module softfloat
7572 /// ::= .module hardfloat
7575 /// ::= .module nocrc
7576 /// ::= .module virt
7577 /// ::= .module novirt
7578 /// ::= .module ginv
7579 /// ::= .module noginv
7580 bool MipsAsmParser::parseDirectiveModule() {
7581 MCAsmParser &Parser = getParser();
7582 MCAsmLexer &Lexer = getLexer();
7583 SMLoc L = Lexer.getLoc();
7585 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7586 // TODO : get a better message.
7587 reportParseError(".module directive must appear before any code");
7592 if (Parser.parseIdentifier(Option)) {
7593 reportParseError("expected .module option identifier");
7597 if (Option == "oddspreg") {
7598 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7600 // Synchronize the abiflags information with the FeatureBits information we
7602 getTargetStreamer().updateABIInfo(*this);
7604 // If printing assembly, use the recently updated abiflags information.
7605 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7606 // emitted at the end).
7607 getTargetStreamer().emitDirectiveModuleOddSPReg();
7609 // If this is not the end of the statement, report an error.
7610 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7611 reportParseError("unexpected token, expected end of statement");
7615 return false; // parseDirectiveModule has finished successfully.
7616 } else if (Option == "nooddspreg") {
7618 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7621 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7623 // Synchronize the abiflags information with the FeatureBits information we
7625 getTargetStreamer().updateABIInfo(*this);
7627 // If printing assembly, use the recently updated abiflags information.
7628 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7629 // emitted at the end).
7630 getTargetStreamer().emitDirectiveModuleOddSPReg();
7632 // If this is not the end of the statement, report an error.
7633 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7634 reportParseError("unexpected token, expected end of statement");
7638 return false; // parseDirectiveModule has finished successfully.
7639 } else if (Option == "fp") {
7640 return parseDirectiveModuleFP();
7641 } else if (Option == "softfloat") {
7642 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7644 // Synchronize the ABI Flags information with the FeatureBits information we
7646 getTargetStreamer().updateABIInfo(*this);
7648 // If printing assembly, use the recently updated ABI Flags information.
7649 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7651 getTargetStreamer().emitDirectiveModuleSoftFloat();
7653 // If this is not the end of the statement, report an error.
7654 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7655 reportParseError("unexpected token, expected end of statement");
7659 return false; // parseDirectiveModule has finished successfully.
7660 } else if (Option == "hardfloat") {
7661 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7663 // Synchronize the ABI Flags information with the FeatureBits information we
7665 getTargetStreamer().updateABIInfo(*this);
7667 // If printing assembly, use the recently updated ABI Flags information.
7668 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7670 getTargetStreamer().emitDirectiveModuleHardFloat();
7672 // If this is not the end of the statement, report an error.
7673 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7674 reportParseError("unexpected token, expected end of statement");
7678 return false; // parseDirectiveModule has finished successfully.
7679 } else if (Option == "mt") {
7680 setModuleFeatureBits(Mips::FeatureMT, "mt");
7682 // Synchronize the ABI Flags information with the FeatureBits information we
7684 getTargetStreamer().updateABIInfo(*this);
7686 // If printing assembly, use the recently updated ABI Flags information.
7687 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7689 getTargetStreamer().emitDirectiveModuleMT();
7691 // If this is not the end of the statement, report an error.
7692 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7693 reportParseError("unexpected token, expected end of statement");
7697 return false; // parseDirectiveModule has finished successfully.
7698 } else if (Option == "crc") {
7699 setModuleFeatureBits(Mips::FeatureCRC, "crc");
7701 // Synchronize the ABI Flags information with the FeatureBits information we
7703 getTargetStreamer().updateABIInfo(*this);
7705 // If printing assembly, use the recently updated ABI Flags information.
7706 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7708 getTargetStreamer().emitDirectiveModuleCRC();
7710 // If this is not the end of the statement, report an error.
7711 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7712 reportParseError("unexpected token, expected end of statement");
7716 return false; // parseDirectiveModule has finished successfully.
7717 } else if (Option == "nocrc") {
7718 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
7720 // Synchronize the ABI Flags information with the FeatureBits information we
7722 getTargetStreamer().updateABIInfo(*this);
7724 // If printing assembly, use the recently updated ABI Flags information.
7725 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7727 getTargetStreamer().emitDirectiveModuleNoCRC();
7729 // If this is not the end of the statement, report an error.
7730 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7731 reportParseError("unexpected token, expected end of statement");
7735 return false; // parseDirectiveModule has finished successfully.
7736 } else if (Option == "virt") {
7737 setModuleFeatureBits(Mips::FeatureVirt, "virt");
7739 // Synchronize the ABI Flags information with the FeatureBits information we
7741 getTargetStreamer().updateABIInfo(*this);
7743 // If printing assembly, use the recently updated ABI Flags information.
7744 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7746 getTargetStreamer().emitDirectiveModuleVirt();
7748 // If this is not the end of the statement, report an error.
7749 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7750 reportParseError("unexpected token, expected end of statement");
7754 return false; // parseDirectiveModule has finished successfully.
7755 } else if (Option == "novirt") {
7756 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
7758 // Synchronize the ABI Flags information with the FeatureBits information we
7760 getTargetStreamer().updateABIInfo(*this);
7762 // If printing assembly, use the recently updated ABI Flags information.
7763 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7765 getTargetStreamer().emitDirectiveModuleNoVirt();
7767 // If this is not the end of the statement, report an error.
7768 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7769 reportParseError("unexpected token, expected end of statement");
7773 return false; // parseDirectiveModule has finished successfully.
7774 } else if (Option == "ginv") {
7775 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
7777 // Synchronize the ABI Flags information with the FeatureBits information we
7779 getTargetStreamer().updateABIInfo(*this);
7781 // If printing assembly, use the recently updated ABI Flags information.
7782 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7784 getTargetStreamer().emitDirectiveModuleGINV();
7786 // If this is not the end of the statement, report an error.
7787 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7788 reportParseError("unexpected token, expected end of statement");
7792 return false; // parseDirectiveModule has finished successfully.
7793 } else if (Option == "noginv") {
7794 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
7796 // Synchronize the ABI Flags information with the FeatureBits information we
7798 getTargetStreamer().updateABIInfo(*this);
7800 // If printing assembly, use the recently updated ABI Flags information.
7801 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7803 getTargetStreamer().emitDirectiveModuleNoGINV();
7805 // If this is not the end of the statement, report an error.
7806 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7807 reportParseError("unexpected token, expected end of statement");
7811 return false; // parseDirectiveModule has finished successfully.
7813 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7817 /// parseDirectiveModuleFP
7821 bool MipsAsmParser::parseDirectiveModuleFP() {
7822 MCAsmParser &Parser = getParser();
7823 MCAsmLexer &Lexer = getLexer();
7825 if (Lexer.isNot(AsmToken::Equal)) {
7826 reportParseError("unexpected token, expected equals sign '='");
7829 Parser.Lex(); // Eat '=' token.
7831 MipsABIFlagsSection::FpABIKind FpABI;
7832 if (!parseFpABIValue(FpABI, ".module"))
7835 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7836 reportParseError("unexpected token, expected end of statement");
7840 // Synchronize the abiflags information with the FeatureBits information we
7842 getTargetStreamer().updateABIInfo(*this);
7844 // If printing assembly, use the recently updated abiflags information.
7845 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7846 // emitted at the end).
7847 getTargetStreamer().emitDirectiveModuleFP();
7849 Parser.Lex(); // Consume the EndOfStatement.
7853 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7854 StringRef Directive) {
7855 MCAsmParser &Parser = getParser();
7856 MCAsmLexer &Lexer = getLexer();
7857 bool ModuleLevelOptions = Directive == ".module";
7859 if (Lexer.is(AsmToken::Identifier)) {
7860 StringRef Value = Parser.getTok().getString();
7863 if (Value != "xx") {
7864 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7869 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7873 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7874 if (ModuleLevelOptions) {
7875 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7876 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7878 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7879 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7884 if (Lexer.is(AsmToken::Integer)) {
7885 unsigned Value = Parser.getTok().getIntVal();
7888 if (Value != 32 && Value != 64) {
7889 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7895 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7899 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7900 if (ModuleLevelOptions) {
7901 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7902 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7904 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7905 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7908 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7909 if (ModuleLevelOptions) {
7910 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7911 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7913 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7914 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7924 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7925 // This returns false if this function recognizes the directive
7926 // regardless of whether it is successfully handles or reports an
7927 // error. Otherwise it returns true to give the generic parser a
7928 // chance at recognizing it.
7930 MCAsmParser &Parser = getParser();
7931 StringRef IDVal = DirectiveID.getString();
7933 if (IDVal == ".cpload") {
7934 parseDirectiveCpLoad(DirectiveID.getLoc());
7937 if (IDVal == ".cprestore") {
7938 parseDirectiveCpRestore(DirectiveID.getLoc());
7941 if (IDVal == ".ent") {
7942 StringRef SymbolName;
7944 if (Parser.parseIdentifier(SymbolName)) {
7945 reportParseError("expected identifier after .ent");
7949 // There's an undocumented extension that allows an integer to
7950 // follow the name of the procedure which AFAICS is ignored by GAS.
7951 // Example: .ent foo,2
7952 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7953 if (getLexer().isNot(AsmToken::Comma)) {
7954 // Even though we accept this undocumented extension for compatibility
7955 // reasons, the additional integer argument does not actually change
7956 // the behaviour of the '.ent' directive, so we would like to discourage
7957 // its use. We do this by not referring to the extended version in
7958 // error messages which are not directly related to its use.
7959 reportParseError("unexpected token, expected end of statement");
7962 Parser.Lex(); // Eat the comma.
7963 const MCExpr *DummyNumber;
7964 int64_t DummyNumberVal;
7965 // If the user was explicitly trying to use the extended version,
7966 // we still give helpful extension-related error messages.
7967 if (Parser.parseExpression(DummyNumber)) {
7968 reportParseError("expected number after comma");
7971 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7972 reportParseError("expected an absolute expression after comma");
7977 // If this is not the end of the statement, report an error.
7978 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7979 reportParseError("unexpected token, expected end of statement");
7983 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7985 getTargetStreamer().emitDirectiveEnt(*Sym);
7987 IsCpRestoreSet = false;
7991 if (IDVal == ".end") {
7992 StringRef SymbolName;
7994 if (Parser.parseIdentifier(SymbolName)) {
7995 reportParseError("expected identifier after .end");
7999 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8000 reportParseError("unexpected token, expected end of statement");
8004 if (CurrentFn == nullptr) {
8005 reportParseError(".end used without .ent");
8009 if ((SymbolName != CurrentFn->getName())) {
8010 reportParseError(".end symbol does not match .ent symbol");
8014 getTargetStreamer().emitDirectiveEnd(SymbolName);
8015 CurrentFn = nullptr;
8016 IsCpRestoreSet = false;
8020 if (IDVal == ".frame") {
8021 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8022 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8023 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
8024 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8025 reportParseError("expected stack register");
8029 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8030 if (!StackRegOpnd.isGPRAsmReg()) {
8031 reportParseError(StackRegOpnd.getStartLoc(),
8032 "expected general purpose register");
8035 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8037 if (Parser.getTok().is(AsmToken::Comma))
8040 reportParseError("unexpected token, expected comma");
8044 // Parse the frame size.
8045 const MCExpr *FrameSize;
8046 int64_t FrameSizeVal;
8048 if (Parser.parseExpression(FrameSize)) {
8049 reportParseError("expected frame size value");
8053 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8054 reportParseError("frame size not an absolute expression");
8058 if (Parser.getTok().is(AsmToken::Comma))
8061 reportParseError("unexpected token, expected comma");
8065 // Parse the return register.
8067 ResTy = parseAnyRegister(TmpReg);
8068 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8069 reportParseError("expected return register");
8073 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8074 if (!ReturnRegOpnd.isGPRAsmReg()) {
8075 reportParseError(ReturnRegOpnd.getStartLoc(),
8076 "expected general purpose register");
8080 // If this is not the end of the statement, report an error.
8081 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8082 reportParseError("unexpected token, expected end of statement");
8086 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8087 ReturnRegOpnd.getGPR32Reg());
8088 IsCpRestoreSet = false;
8092 if (IDVal == ".set") {
8093 parseDirectiveSet();
8097 if (IDVal == ".mask" || IDVal == ".fmask") {
8098 // .mask bitmask, frame_offset
8099 // bitmask: One bit for each register used.
8100 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8101 // first register is expected to be saved.
8103 // .mask 0x80000000, -4
8104 // .fmask 0x80000000, -4
8107 // Parse the bitmask
8108 const MCExpr *BitMask;
8111 if (Parser.parseExpression(BitMask)) {
8112 reportParseError("expected bitmask value");
8116 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8117 reportParseError("bitmask not an absolute expression");
8121 if (Parser.getTok().is(AsmToken::Comma))
8124 reportParseError("unexpected token, expected comma");
8128 // Parse the frame_offset
8129 const MCExpr *FrameOffset;
8130 int64_t FrameOffsetVal;
8132 if (Parser.parseExpression(FrameOffset)) {
8133 reportParseError("expected frame offset value");
8137 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8138 reportParseError("frame offset not an absolute expression");
8142 // If this is not the end of the statement, report an error.
8143 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8144 reportParseError("unexpected token, expected end of statement");
8148 if (IDVal == ".mask")
8149 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8151 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8155 if (IDVal == ".nan")
8156 return parseDirectiveNaN();
8158 if (IDVal == ".gpword") {
8159 parseDirectiveGpWord();
8163 if (IDVal == ".gpdword") {
8164 parseDirectiveGpDWord();
8168 if (IDVal == ".dtprelword") {
8169 parseDirectiveDtpRelWord();
8173 if (IDVal == ".dtpreldword") {
8174 parseDirectiveDtpRelDWord();
8178 if (IDVal == ".tprelword") {
8179 parseDirectiveTpRelWord();
8183 if (IDVal == ".tpreldword") {
8184 parseDirectiveTpRelDWord();
8188 if (IDVal == ".option") {
8189 parseDirectiveOption();
8193 if (IDVal == ".abicalls") {
8194 getTargetStreamer().emitDirectiveAbiCalls();
8195 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8196 Error(Parser.getTok().getLoc(),
8197 "unexpected token, expected end of statement");
8202 if (IDVal == ".cpsetup") {
8203 parseDirectiveCPSetup();
8206 if (IDVal == ".cpreturn") {
8207 parseDirectiveCPReturn();
8210 if (IDVal == ".module") {
8211 parseDirectiveModule();
8214 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8215 parseInternalDirectiveReallowModule();
8218 if (IDVal == ".insn") {
8219 parseInsnDirective();
8222 if (IDVal == ".rdata") {
8223 parseRSectionDirective(".rodata");
8226 if (IDVal == ".sbss") {
8227 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8230 if (IDVal == ".sdata") {
8231 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8238 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8239 // If this is not the end of the statement, report an error.
8240 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8241 reportParseError("unexpected token, expected end of statement");
8245 getTargetStreamer().reallowModuleDirective();
8247 getParser().Lex(); // Eat EndOfStatement token.
8251 extern "C" void LLVMInitializeMipsAsmParser() {
8252 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8253 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8254 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8255 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8258 #define GET_REGISTER_MATCHER
8259 #define GET_MATCHER_IMPLEMENTATION
8260 #include "MipsGenAsmMatcher.inc"
8262 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8263 // Find the appropriate table for this asm variant.
8264 const MatchEntry *Start, *End;
8265 switch (VariantID) {
8266 default: llvm_unreachable("invalid variant!");
8267 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8269 // Search the table.
8270 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8271 return MnemonicRange.first != MnemonicRange.second;