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/CommandLine.h"
43 #include "llvm/Support/Compiler.h"
44 #include "llvm/Support/Debug.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/MathExtras.h"
47 #include "llvm/Support/SMLoc.h"
48 #include "llvm/Support/SourceMgr.h"
49 #include "llvm/Support/TargetRegistry.h"
50 #include "llvm/Support/raw_ostream.h"
60 #define DEBUG_TYPE "mips-asm-parser"
66 } // end namespace llvm
68 extern cl::opt<bool> EmitJalrReloc;
72 class MipsAssemblerOptions {
74 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
76 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
77 ATReg = Opts->getATRegIndex();
78 Reorder = Opts->isReorder();
79 Macro = Opts->isMacro();
80 Features = Opts->getFeatures();
83 unsigned getATRegIndex() const { return ATReg; }
84 bool setATRegIndex(unsigned Reg) {
92 bool isReorder() const { return Reorder; }
93 void setReorder() { Reorder = true; }
94 void setNoReorder() { Reorder = false; }
96 bool isMacro() const { return Macro; }
97 void setMacro() { Macro = true; }
98 void setNoMacro() { Macro = false; }
100 const FeatureBitset &getFeatures() const { return Features; }
101 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
103 // Set of features that are either architecture features or referenced
104 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
105 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
106 // The reason we need this mask is explained in the selectArch function.
107 // FIXME: Ideally we would like TableGen to generate this information.
108 static const FeatureBitset AllArchRelatedMask;
114 FeatureBitset Features;
117 } // end anonymous namespace
119 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
120 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
121 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
122 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
123 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
124 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
125 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
126 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
127 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
132 class MipsAsmParser : public MCTargetAsmParser {
133 MipsTargetStreamer &getTargetStreamer() {
134 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
135 return static_cast<MipsTargetStreamer &>(TS);
139 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
140 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
141 // nullptr, which indicates that no function is currently
142 // selected. This usually happens after an '.end func'
148 unsigned CpSaveLocation;
149 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
150 bool CpSaveLocationIsRegister;
152 // Map of register aliases created via the .set directive.
153 StringMap<AsmToken> RegisterSets;
155 // Print a warning along with its fix-it message at the given range.
156 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
157 SMRange Range, bool ShowColors = true);
159 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
161 #define GET_ASSEMBLER_HEADER
162 #include "MipsGenAsmMatcher.inc"
165 checkEarlyTargetMatchPredicate(MCInst &Inst,
166 const OperandVector &Operands) override;
167 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
169 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
170 OperandVector &Operands, MCStreamer &Out,
172 bool MatchingInlineAsm) override;
174 /// Parse a register as used in CFI directives
175 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
177 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
179 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
181 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
183 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
184 SMLoc NameLoc, OperandVector &Operands) override;
186 bool ParseDirective(AsmToken DirectiveID) override;
188 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
190 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
191 StringRef Identifier, SMLoc S);
192 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
193 const AsmToken &Token,
195 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
197 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
198 OperandMatchResultTy parseImm(OperandVector &Operands);
199 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
200 OperandMatchResultTy parseInvNum(OperandVector &Operands);
201 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
203 bool searchSymbolAlias(OperandVector &Operands);
205 bool parseOperand(OperandVector &, StringRef Mnemonic);
207 enum MacroExpanderResultTy {
213 // Expands assembly pseudo instructions.
214 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
216 const MCSubtargetInfo *STI);
218 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
219 const MCSubtargetInfo *STI);
221 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
222 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
223 MCStreamer &Out, const MCSubtargetInfo *STI);
225 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
226 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
227 MCStreamer &Out, const MCSubtargetInfo *STI);
229 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
231 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
232 MCStreamer &Out, const MCSubtargetInfo *STI);
234 bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
235 SMLoc IDLoc, MCStreamer &Out,
236 const MCSubtargetInfo *STI);
238 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
239 const MCOperand &Offset, bool Is32BitAddress,
240 SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI);
243 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
246 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI, bool IsLoad);
249 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
250 const MCSubtargetInfo *STI);
252 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
255 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
258 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI);
261 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI, const bool IsMips64,
265 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
266 MCStreamer &Out, const MCSubtargetInfo *STI);
268 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
271 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
274 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI);
277 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
278 MCStreamer &Out, const MCSubtargetInfo *STI);
279 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
281 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
282 const MCSubtargetInfo *STI);
283 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
284 const MCSubtargetInfo *STI);
286 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
287 const MCSubtargetInfo *STI);
289 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
290 const MCSubtargetInfo *STI);
292 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
295 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
298 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
301 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI, bool IsLoad);
304 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI);
307 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308 const MCSubtargetInfo *STI);
310 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
313 bool reportParseError(Twine ErrorMsg);
314 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
316 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
318 bool isEvaluated(const MCExpr *Expr);
319 bool parseSetMips0Directive();
320 bool parseSetArchDirective();
321 bool parseSetFeature(uint64_t Feature);
322 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
323 bool parseDirectiveCpLoad(SMLoc Loc);
324 bool parseDirectiveCpRestore(SMLoc Loc);
325 bool parseDirectiveCPSetup();
326 bool parseDirectiveCPReturn();
327 bool parseDirectiveNaN();
328 bool parseDirectiveSet();
329 bool parseDirectiveOption();
330 bool parseInsnDirective();
331 bool parseRSectionDirective(StringRef Section);
332 bool parseSSectionDirective(StringRef Section, unsigned Type);
334 bool parseSetAtDirective();
335 bool parseSetNoAtDirective();
336 bool parseSetMacroDirective();
337 bool parseSetNoMacroDirective();
338 bool parseSetMsaDirective();
339 bool parseSetNoMsaDirective();
340 bool parseSetNoDspDirective();
341 bool parseSetReorderDirective();
342 bool parseSetNoReorderDirective();
343 bool parseSetMips16Directive();
344 bool parseSetNoMips16Directive();
345 bool parseSetFpDirective();
346 bool parseSetOddSPRegDirective();
347 bool parseSetNoOddSPRegDirective();
348 bool parseSetPopDirective();
349 bool parseSetPushDirective();
350 bool parseSetSoftFloatDirective();
351 bool parseSetHardFloatDirective();
352 bool parseSetMtDirective();
353 bool parseSetNoMtDirective();
354 bool parseSetNoCRCDirective();
355 bool parseSetNoVirtDirective();
356 bool parseSetNoGINVDirective();
358 bool parseSetAssignment();
360 bool parseDirectiveGpWord();
361 bool parseDirectiveGpDWord();
362 bool parseDirectiveDtpRelWord();
363 bool parseDirectiveDtpRelDWord();
364 bool parseDirectiveTpRelWord();
365 bool parseDirectiveTpRelDWord();
366 bool parseDirectiveModule();
367 bool parseDirectiveModuleFP();
368 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
369 StringRef Directive);
371 bool parseInternalDirectiveReallowModule();
373 bool eatComma(StringRef ErrorStr);
375 int matchCPURegisterName(StringRef Symbol);
377 int matchHWRegsRegisterName(StringRef Symbol);
379 int matchFPURegisterName(StringRef Name);
381 int matchFCCRegisterName(StringRef Name);
383 int matchACRegisterName(StringRef Name);
385 int matchMSA128RegisterName(StringRef Name);
387 int matchMSA128CtrlRegisterName(StringRef Name);
389 unsigned getReg(int RC, int RegNo);
391 /// Returns the internal register number for the current AT. Also checks if
392 /// the current AT is unavailable (set to $0) and gives an error if it is.
393 /// This should be used in pseudo-instruction expansions which need AT.
394 unsigned getATReg(SMLoc Loc);
398 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
399 const MCSubtargetInfo *STI);
401 // Helper function that checks if the value of a vector index is within the
402 // boundaries of accepted values for each RegisterKind
403 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
404 bool validateMSAIndex(int Val, int RegKind);
406 // Selects a new architecture by updating the FeatureBits with the necessary
407 // info including implied dependencies.
408 // Internally, it clears all the feature bits related to *any* architecture
409 // and selects the new one using the ToggleFeature functionality of the
410 // MCSubtargetInfo object that handles implied dependencies. The reason we
411 // clear all the arch related bits manually is because ToggleFeature only
412 // clears the features that imply the feature being cleared and not the
413 // features implied by the feature being cleared. This is easier to see
415 // --------------------------------------------------
416 // | Feature | Implies |
417 // | -------------------------------------------------|
418 // | FeatureMips1 | None |
419 // | FeatureMips2 | FeatureMips1 |
420 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
421 // | FeatureMips4 | FeatureMips3 |
423 // --------------------------------------------------
425 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
426 // FeatureMipsGP64 | FeatureMips1)
427 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
428 void selectArch(StringRef ArchFeature) {
429 MCSubtargetInfo &STI = copySTI();
430 FeatureBitset FeatureBits = STI.getFeatureBits();
431 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
432 STI.setFeatureBits(FeatureBits);
433 setAvailableFeatures(
434 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
435 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
438 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
439 if (!(getSTI().getFeatureBits()[Feature])) {
440 MCSubtargetInfo &STI = copySTI();
441 setAvailableFeatures(
442 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
443 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
447 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
448 if (getSTI().getFeatureBits()[Feature]) {
449 MCSubtargetInfo &STI = copySTI();
450 setAvailableFeatures(
451 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
452 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
456 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
457 setFeatureBits(Feature, FeatureString);
458 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
461 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
462 clearFeatureBits(Feature, FeatureString);
463 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
467 enum MipsMatchResultTy {
468 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
469 Match_RequiresDifferentOperands,
470 Match_RequiresNoZeroRegister,
471 Match_RequiresSameSrcAndDst,
472 Match_NoFCCRegisterForCurrentISA,
473 Match_NonZeroOperandForSync,
474 Match_NonZeroOperandForMTCX,
475 Match_RequiresPosSizeRange0_32,
476 Match_RequiresPosSizeRange33_64,
477 Match_RequiresPosSizeUImm6,
478 #define GET_OPERAND_DIAGNOSTIC_TYPES
479 #include "MipsGenAsmMatcher.inc"
480 #undef GET_OPERAND_DIAGNOSTIC_TYPES
483 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
484 const MCInstrInfo &MII, const MCTargetOptions &Options)
485 : MCTargetAsmParser(Options, sti, MII),
486 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
487 sti.getCPU(), Options)) {
488 MCAsmParserExtension::Initialize(parser);
490 parser.addAliasForDirective(".asciiz", ".asciz");
491 parser.addAliasForDirective(".hword", ".2byte");
492 parser.addAliasForDirective(".word", ".4byte");
493 parser.addAliasForDirective(".dword", ".8byte");
495 // Initialize the set of available features.
496 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
498 // Remember the initial assembler options. The user can not modify these.
499 AssemblerOptions.push_back(
500 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
502 // Create an assembler options environment for the user to modify.
503 AssemblerOptions.push_back(
504 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
506 getTargetStreamer().updateABIInfo(*this);
508 if (!isABI_O32() && !useOddSPReg() != 0)
509 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
513 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
515 IsCpRestoreSet = false;
516 CpRestoreOffset = -1;
518 const Triple &TheTriple = sti.getTargetTriple();
519 IsLittleEndian = TheTriple.isLittleEndian();
521 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
522 report_fatal_error("microMIPS64R6 is not supported", false);
524 if (!isABI_O32() && inMicroMipsMode())
525 report_fatal_error("microMIPS64 is not supported", false);
528 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
529 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
531 bool isGP64bit() const {
532 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
535 bool isFP64bit() const {
536 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
539 const MipsABIInfo &getABI() const { return ABI; }
540 bool isABI_N32() const { return ABI.IsN32(); }
541 bool isABI_N64() const { return ABI.IsN64(); }
542 bool isABI_O32() const { return ABI.IsO32(); }
543 bool isABI_FPXX() const {
544 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
547 bool useOddSPReg() const {
548 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
551 bool inMicroMipsMode() const {
552 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
555 bool hasMips1() const {
556 return getSTI().getFeatureBits()[Mips::FeatureMips1];
559 bool hasMips2() const {
560 return getSTI().getFeatureBits()[Mips::FeatureMips2];
563 bool hasMips3() const {
564 return getSTI().getFeatureBits()[Mips::FeatureMips3];
567 bool hasMips4() const {
568 return getSTI().getFeatureBits()[Mips::FeatureMips4];
571 bool hasMips5() const {
572 return getSTI().getFeatureBits()[Mips::FeatureMips5];
575 bool hasMips32() const {
576 return getSTI().getFeatureBits()[Mips::FeatureMips32];
579 bool hasMips64() const {
580 return getSTI().getFeatureBits()[Mips::FeatureMips64];
583 bool hasMips32r2() const {
584 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
587 bool hasMips64r2() const {
588 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
591 bool hasMips32r3() const {
592 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
595 bool hasMips64r3() const {
596 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
599 bool hasMips32r5() const {
600 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
603 bool hasMips64r5() const {
604 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
607 bool hasMips32r6() const {
608 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
611 bool hasMips64r6() const {
612 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
615 bool hasDSP() const {
616 return getSTI().getFeatureBits()[Mips::FeatureDSP];
619 bool hasDSPR2() const {
620 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
623 bool hasDSPR3() const {
624 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
627 bool hasMSA() const {
628 return getSTI().getFeatureBits()[Mips::FeatureMSA];
631 bool hasCnMips() const {
632 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
639 bool inMips16Mode() const {
640 return getSTI().getFeatureBits()[Mips::FeatureMips16];
643 bool useTraps() const {
644 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
647 bool useSoftFloat() const {
648 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
651 return getSTI().getFeatureBits()[Mips::FeatureMT];
654 bool hasCRC() const {
655 return getSTI().getFeatureBits()[Mips::FeatureCRC];
658 bool hasVirt() const {
659 return getSTI().getFeatureBits()[Mips::FeatureVirt];
662 bool hasGINV() const {
663 return getSTI().getFeatureBits()[Mips::FeatureGINV];
666 /// Warn if RegIndex is the same as the current AT.
667 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
669 void warnIfNoMacro(SMLoc Loc);
671 bool isLittle() const { return IsLittleEndian; }
673 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
674 AsmToken::TokenKind OperatorToken,
675 MCContext &Ctx) override {
676 switch(OperatorToken) {
678 llvm_unreachable("Unknown token");
680 case AsmToken::PercentCall16:
681 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
682 case AsmToken::PercentCall_Hi:
683 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
684 case AsmToken::PercentCall_Lo:
685 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
686 case AsmToken::PercentDtprel_Hi:
687 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
688 case AsmToken::PercentDtprel_Lo:
689 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
690 case AsmToken::PercentGot:
691 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
692 case AsmToken::PercentGot_Disp:
693 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
694 case AsmToken::PercentGot_Hi:
695 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
696 case AsmToken::PercentGot_Lo:
697 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
698 case AsmToken::PercentGot_Ofst:
699 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
700 case AsmToken::PercentGot_Page:
701 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
702 case AsmToken::PercentGottprel:
703 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
704 case AsmToken::PercentGp_Rel:
705 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
706 case AsmToken::PercentHi:
707 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
708 case AsmToken::PercentHigher:
709 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
710 case AsmToken::PercentHighest:
711 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
712 case AsmToken::PercentLo:
713 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
714 case AsmToken::PercentNeg:
715 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
716 case AsmToken::PercentPcrel_Hi:
717 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
718 case AsmToken::PercentPcrel_Lo:
719 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
720 case AsmToken::PercentTlsgd:
721 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
722 case AsmToken::PercentTlsldm:
723 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
724 case AsmToken::PercentTprel_Hi:
725 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
726 case AsmToken::PercentTprel_Lo:
727 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
732 /// MipsOperand - Instances of this class represent a parsed Mips machine
734 class MipsOperand : public MCParsedAsmOperand {
736 /// Broad categories of register classes
737 /// The exact class is finalized by the render method.
739 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
740 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
742 RegKind_FCC = 4, /// FCC
743 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
744 RegKind_MSACtrl = 16, /// MSA control registers
745 RegKind_COP2 = 32, /// COP2
746 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
748 RegKind_CCR = 128, /// CCR
749 RegKind_HWRegs = 256, /// HWRegs
750 RegKind_COP3 = 512, /// COP3
751 RegKind_COP0 = 1024, /// COP0
752 /// Potentially any (e.g. $1)
753 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
754 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
755 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
760 k_Immediate, /// An immediate (possibly involving symbol references)
761 k_Memory, /// Base + Offset Memory Address
762 k_RegisterIndex, /// A register index in one or more RegKind.
763 k_Token, /// A simple token
764 k_RegList, /// A physical register list
768 MipsOperand(KindTy K, MipsAsmParser &Parser)
769 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
771 ~MipsOperand() override {
780 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 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1042 assert(N == 1 && "Invalid number of operands!");
1043 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1046 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1048 assert(N == 1 && "Invalid number of operands!");
1049 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1052 /// Render the operand to an MCInst as a GPR64
1053 /// Asserts if the wrong number of operands are requested, or the operand
1054 /// is not a k_RegisterIndex compatible with RegKind_GPR
1055 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1056 assert(N == 1 && "Invalid number of operands!");
1057 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1060 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1061 assert(N == 1 && "Invalid number of operands!");
1062 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1065 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1066 assert(N == 1 && "Invalid number of operands!");
1067 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1070 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1071 assert(N == 1 && "Invalid number of operands!");
1072 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1075 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1076 assert(N == 1 && "Invalid number of operands!");
1077 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1080 void addFGR32AsmRegOperands(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 // FIXME: This should propagate failure up to parseStatement.
1085 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1086 AsmParser.getParser().printError(
1087 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1091 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1094 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1095 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1096 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1100 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
1101 assert(N == 1 && "Invalid number of operands!");
1102 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
1105 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1106 assert(N == 1 && "Invalid number of operands!");
1107 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1110 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1111 assert(N == 1 && "Invalid number of operands!");
1112 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1115 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1116 assert(N == 1 && "Invalid number of operands!");
1117 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1120 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1121 assert(N == 1 && "Invalid number of operands!");
1122 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1125 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1126 assert(N == 1 && "Invalid number of operands!");
1127 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1130 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1131 assert(N == 1 && "Invalid number of operands!");
1132 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1135 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1136 assert(N == 1 && "Invalid number of operands!");
1137 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1140 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1141 assert(N == 1 && "Invalid number of operands!");
1142 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1145 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1146 assert(N == 1 && "Invalid number of operands!");
1147 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1150 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1151 assert(N == 1 && "Invalid number of operands!");
1152 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1155 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1156 assert(N == 1 && "Invalid number of operands!");
1157 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1160 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1161 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1162 assert(N == 1 && "Invalid number of operands!");
1163 uint64_t Imm = getConstantImm() - Offset;
1164 Imm &= (1ULL << Bits) - 1;
1166 Imm += AdjustOffset;
1167 Inst.addOperand(MCOperand::createImm(Imm));
1170 template <unsigned Bits>
1171 void addSImmOperands(MCInst &Inst, unsigned N) const {
1172 if (isImm() && !isConstantImm()) {
1173 addExpr(Inst, getImm());
1176 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1179 template <unsigned Bits>
1180 void addUImmOperands(MCInst &Inst, unsigned N) const {
1181 if (isImm() && !isConstantImm()) {
1182 addExpr(Inst, getImm());
1185 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1188 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1189 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1190 assert(N == 1 && "Invalid number of operands!");
1191 int64_t Imm = getConstantImm() - Offset;
1192 Imm = SignExtend64<Bits>(Imm);
1194 Imm += AdjustOffset;
1195 Inst.addOperand(MCOperand::createImm(Imm));
1198 void addImmOperands(MCInst &Inst, unsigned N) const {
1199 assert(N == 1 && "Invalid number of operands!");
1200 const MCExpr *Expr = getImm();
1201 addExpr(Inst, Expr);
1204 void addMemOperands(MCInst &Inst, unsigned N) const {
1205 assert(N == 2 && "Invalid number of operands!");
1207 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1208 ? getMemBase()->getGPR64Reg()
1209 : getMemBase()->getGPR32Reg()));
1211 const MCExpr *Expr = getMemOff();
1212 addExpr(Inst, Expr);
1215 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1216 assert(N == 2 && "Invalid number of operands!");
1218 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1220 const MCExpr *Expr = getMemOff();
1221 addExpr(Inst, Expr);
1224 void addRegListOperands(MCInst &Inst, unsigned N) const {
1225 assert(N == 1 && "Invalid number of operands!");
1227 for (auto RegNo : getRegList())
1228 Inst.addOperand(MCOperand::createReg(RegNo));
1231 bool isReg() const override {
1232 // As a special case until we sort out the definition of div/divu, accept
1233 // $0/$zero here so that MCK_ZERO works correctly.
1234 return isGPRAsmReg() && RegIdx.Index == 0;
1237 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1238 bool isImm() const override { return Kind == k_Immediate; }
1240 bool isConstantImm() const {
1242 return isImm() && getImm()->evaluateAsAbsolute(Res);
1245 bool isConstantImmz() const {
1246 return isConstantImm() && getConstantImm() == 0;
1249 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1250 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1253 template <unsigned Bits> bool isSImm() const {
1254 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1257 template <unsigned Bits> bool isUImm() const {
1258 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1261 template <unsigned Bits> bool isAnyImm() const {
1262 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1263 isUInt<Bits>(getConstantImm()))
1267 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1268 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1271 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1272 return isConstantImm() && getConstantImm() >= Bottom &&
1273 getConstantImm() <= Top;
1276 bool isToken() const override {
1277 // Note: It's not possible to pretend that other operand kinds are tokens.
1278 // The matcher emitter checks tokens first.
1279 return Kind == k_Token;
1282 bool isMem() const override { return Kind == k_Memory; }
1284 bool isConstantMemOff() const {
1285 return isMem() && isa<MCConstantExpr>(getMemOff());
1288 // Allow relocation operators.
1289 // FIXME: This predicate and others need to look through binary expressions
1290 // and determine whether a Value is a constant or not.
1291 template <unsigned Bits, unsigned ShiftAmount = 0>
1292 bool isMemWithSimmOffset() const {
1295 if (!getMemBase()->isGPRAsmReg())
1297 if (isa<MCTargetExpr>(getMemOff()) ||
1298 (isConstantMemOff() &&
1299 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1302 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1303 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1306 bool isMemWithPtrSizeOffset() const {
1309 if (!getMemBase()->isGPRAsmReg())
1311 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1312 if (isa<MCTargetExpr>(getMemOff()) ||
1313 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1316 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1317 return IsReloc && isIntN(PtrBits, Res.getConstant());
1320 bool isMemWithGRPMM16Base() const {
1321 return isMem() && getMemBase()->isMM16AsmReg();
1324 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1325 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1326 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1329 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1330 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1331 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1332 && (getMemBase()->getGPR32Reg() == Mips::SP);
1335 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1336 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1337 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1338 && (getMemBase()->getGPR32Reg() == Mips::GP);
1341 template <unsigned Bits, unsigned ShiftLeftAmount>
1342 bool isScaledUImm() const {
1343 return isConstantImm() &&
1344 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1347 template <unsigned Bits, unsigned ShiftLeftAmount>
1348 bool isScaledSImm() const {
1349 if (isConstantImm() &&
1350 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1352 // Operand can also be a symbol or symbol plus
1353 // offset in case of relocations.
1354 if (Kind != k_Immediate)
1357 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1358 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1361 bool isRegList16() const {
1365 int Size = RegList.List->size();
1366 if (Size < 2 || Size > 5)
1369 unsigned R0 = RegList.List->front();
1370 unsigned R1 = RegList.List->back();
1371 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1372 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1375 int PrevReg = *RegList.List->begin();
1376 for (int i = 1; i < Size - 1; i++) {
1377 int Reg = (*(RegList.List))[i];
1378 if ( Reg != PrevReg + 1)
1386 bool isInvNum() const { return Kind == k_Immediate; }
1388 bool isLSAImm() const {
1389 if (!isConstantImm())
1391 int64_t Val = getConstantImm();
1392 return 1 <= Val && Val <= 4;
1395 bool isRegList() const { return Kind == k_RegList; }
1397 StringRef getToken() const {
1398 assert(Kind == k_Token && "Invalid access!");
1399 return StringRef(Tok.Data, Tok.Length);
1402 unsigned getReg() const override {
1403 // As a special case until we sort out the definition of div/divu, accept
1404 // $0/$zero here so that MCK_ZERO works correctly.
1405 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1406 RegIdx.Kind & RegKind_GPR)
1407 return getGPR32Reg(); // FIXME: GPR64 too
1409 llvm_unreachable("Invalid access!");
1413 const MCExpr *getImm() const {
1414 assert((Kind == k_Immediate) && "Invalid access!");
1418 int64_t getConstantImm() const {
1419 const MCExpr *Val = getImm();
1421 (void)Val->evaluateAsAbsolute(Value);
1425 MipsOperand *getMemBase() const {
1426 assert((Kind == k_Memory) && "Invalid access!");
1430 const MCExpr *getMemOff() const {
1431 assert((Kind == k_Memory) && "Invalid access!");
1435 int64_t getConstantMemOff() const {
1436 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1439 const SmallVectorImpl<unsigned> &getRegList() const {
1440 assert((Kind == k_RegList) && "Invalid access!");
1441 return *(RegList.List);
1444 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1445 MipsAsmParser &Parser) {
1446 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1447 Op->Tok.Data = Str.data();
1448 Op->Tok.Length = Str.size();
1454 /// Create a numeric register (e.g. $1). The exact register remains
1455 /// unresolved until an instruction successfully matches
1456 static std::unique_ptr<MipsOperand>
1457 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1458 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1459 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1460 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1463 /// Create a register that is definitely a GPR.
1464 /// This is typically only used for named registers such as $gp.
1465 static std::unique_ptr<MipsOperand>
1466 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1467 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1468 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1471 /// Create a register that is definitely a FGR.
1472 /// This is typically only used for named registers such as $f0.
1473 static std::unique_ptr<MipsOperand>
1474 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1475 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1476 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1479 /// Create a register that is definitely a HWReg.
1480 /// This is typically only used for named registers such as $hwr_cpunum.
1481 static std::unique_ptr<MipsOperand>
1482 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1483 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1484 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1487 /// Create a register that is definitely an FCC.
1488 /// This is typically only used for named registers such as $fcc0.
1489 static std::unique_ptr<MipsOperand>
1490 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1491 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1492 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1495 /// Create a register that is definitely an ACC.
1496 /// This is typically only used for named registers such as $ac0.
1497 static std::unique_ptr<MipsOperand>
1498 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1499 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1500 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1503 /// Create a register that is definitely an MSA128.
1504 /// This is typically only used for named registers such as $w0.
1505 static std::unique_ptr<MipsOperand>
1506 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1507 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1508 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1511 /// Create a register that is definitely an MSACtrl.
1512 /// This is typically only used for named registers such as $msaaccess.
1513 static std::unique_ptr<MipsOperand>
1514 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1515 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1516 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1519 static std::unique_ptr<MipsOperand>
1520 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1521 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1528 static std::unique_ptr<MipsOperand>
1529 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1530 SMLoc E, MipsAsmParser &Parser) {
1531 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1532 Op->Mem.Base = Base.release();
1539 static std::unique_ptr<MipsOperand>
1540 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1541 MipsAsmParser &Parser) {
1542 assert(Regs.size() > 0 && "Empty list not allowed");
1544 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1545 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1546 Op->StartLoc = StartLoc;
1547 Op->EndLoc = EndLoc;
1551 bool isGPRZeroAsmReg() const {
1552 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1555 bool isGPRNonZeroAsmReg() const {
1556 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1560 bool isGPRAsmReg() const {
1561 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1564 bool isMM16AsmReg() const {
1565 if (!(isRegIdx() && RegIdx.Kind))
1567 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1568 || RegIdx.Index == 16 || RegIdx.Index == 17);
1571 bool isMM16AsmRegZero() const {
1572 if (!(isRegIdx() && RegIdx.Kind))
1574 return (RegIdx.Index == 0 ||
1575 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1576 RegIdx.Index == 17);
1579 bool isMM16AsmRegMoveP() const {
1580 if (!(isRegIdx() && RegIdx.Kind))
1582 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1583 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1586 bool isMM16AsmRegMovePPairFirst() const {
1587 if (!(isRegIdx() && RegIdx.Kind))
1589 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1592 bool isMM16AsmRegMovePPairSecond() const {
1593 if (!(isRegIdx() && RegIdx.Kind))
1595 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1596 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1599 bool isFGRAsmReg() const {
1600 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1601 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1604 bool isStrictlyFGRAsmReg() const {
1605 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1606 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1609 bool isHWRegsAsmReg() const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1613 bool isCCRAsmReg() const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1617 bool isFCCAsmReg() const {
1618 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1620 return RegIdx.Index <= 7;
1623 bool isACCAsmReg() const {
1624 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1627 bool isCOP0AsmReg() const {
1628 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1631 bool isCOP2AsmReg() const {
1632 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1635 bool isCOP3AsmReg() const {
1636 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1639 bool isMSA128AsmReg() const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1643 bool isMSACtrlAsmReg() const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1647 /// getStartLoc - Get the location of the first token of this operand.
1648 SMLoc getStartLoc() const override { return StartLoc; }
1649 /// getEndLoc - Get the location of the last token of this operand.
1650 SMLoc getEndLoc() const override { return EndLoc; }
1652 void print(raw_ostream &OS) const override {
1661 Mem.Base->print(OS);
1666 case k_RegisterIndex:
1667 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1668 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1675 for (auto Reg : (*RegList.List))
1682 bool isValidForTie(const MipsOperand &Other) const {
1683 if (Kind != Other.Kind)
1688 llvm_unreachable("Unexpected kind");
1690 case k_RegisterIndex: {
1691 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1692 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1693 return Token == OtherToken;
1697 }; // class MipsOperand
1699 } // end anonymous namespace
1703 extern const MCInstrDesc MipsInsts[];
1705 } // end namespace llvm
1707 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1708 return MipsInsts[Opcode];
1711 static bool hasShortDelaySlot(MCInst &Inst) {
1712 switch (Inst.getOpcode()) {
1719 case Mips::JRC16_MM:
1721 case Mips::JALRS_MM:
1722 case Mips::JALRS16_MM:
1723 case Mips::BGEZALS_MM:
1724 case Mips::BLTZALS_MM:
1727 return !Inst.getOperand(0).isReg();
1733 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1734 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1735 return &SRExpr->getSymbol();
1738 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1739 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1740 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1751 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1752 return getSingleMCSymbol(UExpr->getSubExpr());
1757 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1758 if (isa<MCSymbolRefExpr>(Expr))
1761 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1762 return countMCSymbolRefExpr(BExpr->getLHS()) +
1763 countMCSymbolRefExpr(BExpr->getRHS());
1765 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1766 return countMCSymbolRefExpr(UExpr->getSubExpr());
1771 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1773 const MCSubtargetInfo *STI) {
1774 MipsTargetStreamer &TOut = getTargetStreamer();
1775 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1776 bool ExpandedJalSym = false;
1780 if (MCID.isBranch() || MCID.isCall()) {
1781 const unsigned Opcode = Inst.getOpcode();
1791 assert(hasCnMips() && "instruction only valid for octeon cpus");
1798 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1799 Offset = Inst.getOperand(2);
1800 if (!Offset.isImm())
1801 break; // We'll deal with this situation later on when applying fixups.
1802 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1803 return Error(IDLoc, "branch target out of range");
1804 if (OffsetToAlignment(Offset.getImm(),
1805 1LL << (inMicroMipsMode() ? 1 : 2)))
1806 return Error(IDLoc, "branch to misaligned address");
1820 case Mips::BGEZAL_MM:
1821 case Mips::BLTZAL_MM:
1824 case Mips::BC1EQZC_MMR6:
1825 case Mips::BC1NEZC_MMR6:
1826 case Mips::BC2EQZC_MMR6:
1827 case Mips::BC2NEZC_MMR6:
1828 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1829 Offset = Inst.getOperand(1);
1830 if (!Offset.isImm())
1831 break; // We'll deal with this situation later on when applying fixups.
1832 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1833 return Error(IDLoc, "branch target out of range");
1834 if (OffsetToAlignment(Offset.getImm(),
1835 1LL << (inMicroMipsMode() ? 1 : 2)))
1836 return Error(IDLoc, "branch to misaligned address");
1838 case Mips::BGEC: case Mips::BGEC_MMR6:
1839 case Mips::BLTC: case Mips::BLTC_MMR6:
1840 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1841 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1842 case Mips::BEQC: case Mips::BEQC_MMR6:
1843 case Mips::BNEC: case Mips::BNEC_MMR6:
1844 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1845 Offset = Inst.getOperand(2);
1846 if (!Offset.isImm())
1847 break; // We'll deal with this situation later on when applying fixups.
1848 if (!isIntN(18, Offset.getImm()))
1849 return Error(IDLoc, "branch target out of range");
1850 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1851 return Error(IDLoc, "branch to misaligned address");
1853 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1854 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1855 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1856 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1857 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1858 Offset = Inst.getOperand(1);
1859 if (!Offset.isImm())
1860 break; // We'll deal with this situation later on when applying fixups.
1861 if (!isIntN(18, Offset.getImm()))
1862 return Error(IDLoc, "branch target out of range");
1863 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1864 return Error(IDLoc, "branch to misaligned address");
1866 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1867 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1868 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1869 Offset = Inst.getOperand(1);
1870 if (!Offset.isImm())
1871 break; // We'll deal with this situation later on when applying fixups.
1872 if (!isIntN(23, Offset.getImm()))
1873 return Error(IDLoc, "branch target out of range");
1874 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1875 return Error(IDLoc, "branch to misaligned address");
1877 case Mips::BEQZ16_MM:
1878 case Mips::BEQZC16_MMR6:
1879 case Mips::BNEZ16_MM:
1880 case Mips::BNEZC16_MMR6:
1881 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1882 Offset = Inst.getOperand(1);
1883 if (!Offset.isImm())
1884 break; // We'll deal with this situation later on when applying fixups.
1885 if (!isInt<8>(Offset.getImm()))
1886 return Error(IDLoc, "branch target out of range");
1887 if (OffsetToAlignment(Offset.getImm(), 2LL))
1888 return Error(IDLoc, "branch to misaligned address");
1893 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1894 // We still accept it but it is a normal nop.
1895 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1896 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1897 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1902 const unsigned Opcode = Inst.getOpcode();
1914 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1915 // The offset is handled above
1916 Opnd = Inst.getOperand(1);
1918 return Error(IDLoc, "expected immediate operand kind");
1919 Imm = Opnd.getImm();
1920 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1921 Opcode == Mips::BBIT1 ? 63 : 31))
1922 return Error(IDLoc, "immediate operand value out of range");
1924 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1926 Inst.getOperand(1).setImm(Imm - 32);
1932 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1933 Opnd = Inst.getOperand(2);
1935 return Error(IDLoc, "expected immediate operand kind");
1936 Imm = Opnd.getImm();
1937 if (!isInt<10>(Imm))
1938 return Error(IDLoc, "immediate operand value out of range");
1943 // Warn on division by zero. We're checking here as all instructions get
1944 // processed here, not just the macros that need expansion.
1946 // The MIPS backend models most of the divison instructions and macros as
1947 // three operand instructions. The pre-R6 divide instructions however have
1948 // two operands and explicitly define HI/LO as part of the instruction,
1949 // not in the operands.
1950 unsigned FirstOp = 1;
1951 unsigned SecondOp = 2;
1952 switch (Inst.getOpcode()) {
1955 case Mips::SDivIMacro:
1956 case Mips::UDivIMacro:
1957 case Mips::DSDivIMacro:
1958 case Mips::DUDivIMacro:
1959 if (Inst.getOperand(2).getImm() == 0) {
1960 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1961 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1962 Warning(IDLoc, "dividing zero by zero");
1964 Warning(IDLoc, "division by zero");
1976 case Mips::SDivMacro:
1977 case Mips::DSDivMacro:
1978 case Mips::UDivMacro:
1979 case Mips::DUDivMacro:
1984 case Mips::DIVU_MMR6:
1985 case Mips::DIV_MMR6:
1986 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1987 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1988 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1989 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1990 Warning(IDLoc, "dividing zero by zero");
1992 Warning(IDLoc, "division by zero");
1997 // For PIC code convert unconditional jump to unconditional branch.
1998 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2001 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2002 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2003 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2004 BInst.addOperand(Inst.getOperand(0));
2008 // This expansion is not in a function called by tryExpandInstruction()
2009 // because the pseudo-instruction doesn't have a distinct opcode.
2010 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2012 warnIfNoMacro(IDLoc);
2014 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2016 // We can do this expansion if there's only 1 symbol in the argument
2018 if (countMCSymbolRefExpr(JalExpr) > 1)
2019 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2021 // FIXME: This is checking the expression can be handled by the later stages
2022 // of the assembler. We ought to leave it to those later stages.
2023 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2025 // FIXME: Add support for label+offset operands (currently causes an error).
2026 // FIXME: Add support for forward-declared local symbols.
2027 // FIXME: Add expansion for when the LargeGOT option is enabled.
2028 if (JalSym->isInSection() || JalSym->isTemporary() ||
2030 cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2032 // If it's a local symbol and the O32 ABI is being used, we expand to:
2034 // R_(MICRO)MIPS_GOT16 label
2035 // addiu $25, $25, 0
2036 // R_(MICRO)MIPS_LO16 label
2038 const MCExpr *Got16RelocExpr =
2039 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2040 const MCExpr *Lo16RelocExpr =
2041 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2043 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
2044 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2045 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2046 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2047 } else if (isABI_N32() || isABI_N64()) {
2048 // If it's a local symbol and the N32/N64 ABIs are being used,
2050 // lw/ld $25, 0($gp)
2051 // R_(MICRO)MIPS_GOT_DISP label
2053 const MCExpr *GotDispRelocExpr =
2054 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2056 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2057 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2061 // If it's an external/weak symbol, we expand to:
2062 // lw/ld $25, 0($gp)
2063 // R_(MICRO)MIPS_CALL16 label
2065 const MCExpr *Call16RelocExpr =
2066 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2068 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
2069 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2073 if (IsCpRestoreSet && inMicroMipsMode())
2074 JalrInst.setOpcode(Mips::JALRS_MM);
2076 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2077 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2078 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2080 if (EmitJalrReloc) {
2081 // As an optimization hint for the linker, before the JALR we add:
2082 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2084 MCSymbol *TmpLabel = getContext().createTempSymbol();
2085 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2086 const MCExpr *RelocJalrExpr =
2087 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2088 getContext(), IDLoc);
2090 TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2091 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2092 RelocJalrExpr, IDLoc, *STI);
2093 TOut.getStreamer().EmitLabel(TmpLabel);
2097 ExpandedJalSym = true;
2100 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2101 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2102 // Check the offset of memory operand, if it is a symbol
2103 // reference or immediate we may have to expand instructions.
2104 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2105 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2106 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2107 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2108 MCOperand &Op = Inst.getOperand(i);
2110 int64_t MemOffset = Op.getImm();
2111 if (MemOffset < -32768 || MemOffset > 32767) {
2112 // Offset can't exceed 16bit value.
2113 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2114 return getParser().hasPendingError();
2116 } else if (Op.isExpr()) {
2117 const MCExpr *Expr = Op.getExpr();
2118 if (Expr->getKind() == MCExpr::SymbolRef) {
2119 const MCSymbolRefExpr *SR =
2120 static_cast<const MCSymbolRefExpr *>(Expr);
2121 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2123 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2124 return getParser().hasPendingError();
2126 } else if (!isEvaluated(Expr)) {
2127 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2128 return getParser().hasPendingError();
2135 if (inMicroMipsMode()) {
2136 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2137 // Try to create 16-bit GP relative load instruction.
2138 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2139 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2140 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2141 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2142 MCOperand &Op = Inst.getOperand(i);
2144 int MemOffset = Op.getImm();
2145 MCOperand &DstReg = Inst.getOperand(0);
2146 MCOperand &BaseReg = Inst.getOperand(1);
2147 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2148 getContext().getRegisterInfo()->getRegClass(
2149 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2150 (BaseReg.getReg() == Mips::GP ||
2151 BaseReg.getReg() == Mips::GP_64)) {
2153 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2162 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2167 switch (Inst.getOpcode()) {
2170 case Mips::ADDIUSP_MM:
2171 Opnd = Inst.getOperand(0);
2173 return Error(IDLoc, "expected immediate operand kind");
2174 Imm = Opnd.getImm();
2175 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2177 return Error(IDLoc, "immediate operand value out of range");
2179 case Mips::SLL16_MM:
2180 case Mips::SRL16_MM:
2181 Opnd = Inst.getOperand(2);
2183 return Error(IDLoc, "expected immediate operand kind");
2184 Imm = Opnd.getImm();
2185 if (Imm < 1 || Imm > 8)
2186 return Error(IDLoc, "immediate operand value out of range");
2189 Opnd = Inst.getOperand(1);
2191 return Error(IDLoc, "expected immediate operand kind");
2192 Imm = Opnd.getImm();
2193 if (Imm < -1 || Imm > 126)
2194 return Error(IDLoc, "immediate operand value out of range");
2196 case Mips::ADDIUR2_MM:
2197 Opnd = Inst.getOperand(2);
2199 return Error(IDLoc, "expected immediate operand kind");
2200 Imm = Opnd.getImm();
2201 if (!(Imm == 1 || Imm == -1 ||
2202 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2203 return Error(IDLoc, "immediate operand value out of range");
2205 case Mips::ANDI16_MM:
2206 Opnd = Inst.getOperand(2);
2208 return Error(IDLoc, "expected immediate operand kind");
2209 Imm = Opnd.getImm();
2210 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2211 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2212 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2213 return Error(IDLoc, "immediate operand value out of range");
2215 case Mips::LBU16_MM:
2216 Opnd = Inst.getOperand(2);
2218 return Error(IDLoc, "expected immediate operand kind");
2219 Imm = Opnd.getImm();
2220 if (Imm < -1 || Imm > 14)
2221 return Error(IDLoc, "immediate operand value out of range");
2224 case Mips::SB16_MMR6:
2225 Opnd = Inst.getOperand(2);
2227 return Error(IDLoc, "expected immediate operand kind");
2228 Imm = Opnd.getImm();
2229 if (Imm < 0 || Imm > 15)
2230 return Error(IDLoc, "immediate operand value out of range");
2232 case Mips::LHU16_MM:
2234 case Mips::SH16_MMR6:
2235 Opnd = Inst.getOperand(2);
2237 return Error(IDLoc, "expected immediate operand kind");
2238 Imm = Opnd.getImm();
2239 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2240 return Error(IDLoc, "immediate operand value out of range");
2244 case Mips::SW16_MMR6:
2245 Opnd = Inst.getOperand(2);
2247 return Error(IDLoc, "expected immediate operand kind");
2248 Imm = Opnd.getImm();
2249 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2250 return Error(IDLoc, "immediate operand value out of range");
2252 case Mips::ADDIUPC_MM:
2253 Opnd = Inst.getOperand(1);
2255 return Error(IDLoc, "expected immediate operand kind");
2256 Imm = Opnd.getImm();
2257 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2258 return Error(IDLoc, "immediate operand value out of range");
2262 if (Inst.getOperand(0).getReg() == Mips::RA)
2263 return Error(IDLoc, "invalid operand for instruction");
2265 case Mips::MOVEP_MM:
2266 case Mips::MOVEP_MMR6: {
2267 unsigned R0 = Inst.getOperand(0).getReg();
2268 unsigned R1 = Inst.getOperand(1).getReg();
2269 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2270 (R0 == Mips::A1 && R1 == Mips::A3) ||
2271 (R0 == Mips::A2 && R1 == Mips::A3) ||
2272 (R0 == Mips::A0 && R1 == Mips::S5) ||
2273 (R0 == Mips::A0 && R1 == Mips::S6) ||
2274 (R0 == Mips::A0 && R1 == Mips::A1) ||
2275 (R0 == Mips::A0 && R1 == Mips::A2) ||
2276 (R0 == Mips::A0 && R1 == Mips::A3));
2278 return Error(IDLoc, "invalid operand for instruction");
2284 bool FillDelaySlot =
2285 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2287 TOut.emitDirectiveSetNoReorder();
2289 MacroExpanderResultTy ExpandResult =
2290 tryExpandInstruction(Inst, IDLoc, Out, STI);
2291 switch (ExpandResult) {
2293 Out.EmitInstruction(Inst, *STI);
2301 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2302 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2303 if (inMicroMipsMode()) {
2304 TOut.setUsesMicroMips();
2305 TOut.updateABIInfo(*this);
2308 // If this instruction has a delay slot and .set reorder is active,
2309 // emit a NOP after it.
2310 if (FillDelaySlot) {
2311 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2312 TOut.emitDirectiveSetReorder();
2315 if ((Inst.getOpcode() == Mips::JalOneReg ||
2316 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2317 isPicAndNotNxxAbi()) {
2318 if (IsCpRestoreSet) {
2319 // We need a NOP between the JALR and the LW:
2320 // If .set reorder has been used, we've already emitted a NOP.
2321 // If .set noreorder has been used, we need to emit a NOP at this point.
2322 if (!AssemblerOptions.back()->isReorder())
2323 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2326 // Load the $gp from the stack.
2327 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2329 Warning(IDLoc, "no .cprestore used in PIC mode");
2335 MipsAsmParser::MacroExpanderResultTy
2336 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2337 const MCSubtargetInfo *STI) {
2338 switch (Inst.getOpcode()) {
2340 return MER_NotAMacro;
2341 case Mips::LoadImm32:
2342 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2343 case Mips::LoadImm64:
2344 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2345 case Mips::LoadAddrImm32:
2346 case Mips::LoadAddrImm64:
2347 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2348 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2349 "expected immediate operand kind");
2351 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2353 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2357 case Mips::LoadAddrReg32:
2358 case Mips::LoadAddrReg64:
2359 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2360 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2361 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2362 "expected immediate operand kind");
2364 return expandLoadAddress(Inst.getOperand(0).getReg(),
2365 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2366 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2370 case Mips::B_MM_Pseudo:
2371 case Mips::B_MMR6_Pseudo:
2372 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2376 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2378 case Mips::JalOneReg:
2379 case Mips::JalTwoReg:
2380 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2383 case Mips::BEQLImmMacro:
2384 case Mips::BNELImmMacro:
2385 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2402 case Mips::BLTImmMacro:
2403 case Mips::BLEImmMacro:
2404 case Mips::BGEImmMacro:
2405 case Mips::BGTImmMacro:
2406 case Mips::BLTUImmMacro:
2407 case Mips::BLEUImmMacro:
2408 case Mips::BGEUImmMacro:
2409 case Mips::BGTUImmMacro:
2410 case Mips::BLTLImmMacro:
2411 case Mips::BLELImmMacro:
2412 case Mips::BGELImmMacro:
2413 case Mips::BGTLImmMacro:
2414 case Mips::BLTULImmMacro:
2415 case Mips::BLEULImmMacro:
2416 case Mips::BGEULImmMacro:
2417 case Mips::BGTULImmMacro:
2418 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2419 case Mips::SDivMacro:
2420 case Mips::SDivIMacro:
2421 case Mips::SRemMacro:
2422 case Mips::SRemIMacro:
2423 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2425 case Mips::DSDivMacro:
2426 case Mips::DSDivIMacro:
2427 case Mips::DSRemMacro:
2428 case Mips::DSRemIMacro:
2429 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2431 case Mips::UDivMacro:
2432 case Mips::UDivIMacro:
2433 case Mips::URemMacro:
2434 case Mips::URemIMacro:
2435 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2437 case Mips::DUDivMacro:
2438 case Mips::DUDivIMacro:
2439 case Mips::DURemMacro:
2440 case Mips::DURemIMacro:
2441 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2443 case Mips::PseudoTRUNC_W_S:
2444 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2446 case Mips::PseudoTRUNC_W_D32:
2447 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2449 case Mips::PseudoTRUNC_W_D:
2450 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2453 case Mips::LoadImmSingleGPR:
2454 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2457 case Mips::LoadImmSingleFGR:
2458 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2461 case Mips::LoadImmDoubleGPR:
2462 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2465 case Mips::LoadImmDoubleFGR:
2466 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2469 case Mips::LoadImmDoubleFGR_32:
2470 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2474 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2476 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2478 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2481 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2483 case Mips::NORImm64:
2484 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2485 case Mips::SLTImm64:
2486 if (isInt<16>(Inst.getOperand(2).getImm())) {
2487 Inst.setOpcode(Mips::SLTi64);
2488 return MER_NotAMacro;
2490 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2491 case Mips::SLTUImm64:
2492 if (isInt<16>(Inst.getOperand(2).getImm())) {
2493 Inst.setOpcode(Mips::SLTiu64);
2494 return MER_NotAMacro;
2496 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2497 case Mips::ADDi: case Mips::ADDi_MM:
2498 case Mips::ADDiu: case Mips::ADDiu_MM:
2499 case Mips::SLTi: case Mips::SLTi_MM:
2500 case Mips::SLTiu: case Mips::SLTiu_MM:
2501 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2502 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2503 int64_t ImmValue = Inst.getOperand(2).getImm();
2504 if (isInt<16>(ImmValue))
2505 return MER_NotAMacro;
2506 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2509 return MER_NotAMacro;
2510 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2511 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2512 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2513 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2514 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2515 int64_t ImmValue = Inst.getOperand(2).getImm();
2516 if (isUInt<16>(ImmValue))
2517 return MER_NotAMacro;
2518 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2521 return MER_NotAMacro;
2524 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2527 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2530 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2533 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534 case Mips::ABSMacro:
2535 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::MULImmMacro:
2537 case Mips::DMULImmMacro:
2538 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 case Mips::MULOMacro:
2540 case Mips::DMULOMacro:
2541 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 case Mips::MULOUMacro:
2543 case Mips::DMULOUMacro:
2544 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545 case Mips::DMULMacro:
2546 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2550 Inst.getOpcode() == Mips::LDMacro)
2553 case Mips::SEQMacro:
2554 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::SEQIMacro:
2556 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 case Mips::MFTC0: case Mips::MTTC0:
2558 case Mips::MFTGPR: case Mips::MTTGPR:
2559 case Mips::MFTLO: case Mips::MTTLO:
2560 case Mips::MFTHI: case Mips::MTTHI:
2561 case Mips::MFTACX: case Mips::MTTACX:
2562 case Mips::MFTDSP: case Mips::MTTDSP:
2563 case Mips::MFTC1: case Mips::MTTC1:
2564 case Mips::MFTHC1: case Mips::MTTHC1:
2565 case Mips::CFTC1: case Mips::CTTC1:
2566 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2570 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2572 const MCSubtargetInfo *STI) {
2573 MipsTargetStreamer &TOut = getTargetStreamer();
2575 // Create a JALR instruction which is going to replace the pseudo-JAL.
2577 JalrInst.setLoc(IDLoc);
2578 const MCOperand FirstRegOp = Inst.getOperand(0);
2579 const unsigned Opcode = Inst.getOpcode();
2581 if (Opcode == Mips::JalOneReg) {
2582 // jal $rs => jalr $rs
2583 if (IsCpRestoreSet && inMicroMipsMode()) {
2584 JalrInst.setOpcode(Mips::JALRS16_MM);
2585 JalrInst.addOperand(FirstRegOp);
2586 } else if (inMicroMipsMode()) {
2587 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2588 JalrInst.addOperand(FirstRegOp);
2590 JalrInst.setOpcode(Mips::JALR);
2591 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2592 JalrInst.addOperand(FirstRegOp);
2594 } else if (Opcode == Mips::JalTwoReg) {
2595 // jal $rd, $rs => jalr $rd, $rs
2596 if (IsCpRestoreSet && inMicroMipsMode())
2597 JalrInst.setOpcode(Mips::JALRS_MM);
2599 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2600 JalrInst.addOperand(FirstRegOp);
2601 const MCOperand SecondRegOp = Inst.getOperand(1);
2602 JalrInst.addOperand(SecondRegOp);
2604 Out.EmitInstruction(JalrInst, *STI);
2606 // If .set reorder is active and branch instruction has a delay slot,
2607 // emit a NOP after it.
2608 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2609 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2610 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2616 /// Can the value be represented by a unsigned N-bit value and a shift left?
2617 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2618 unsigned BitNum = findFirstSet(x);
2620 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2623 /// Load (or add) an immediate into a register.
2625 /// @param ImmValue The immediate to load.
2626 /// @param DstReg The register that will hold the immediate.
2627 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2628 /// for a simple initialization.
2629 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2630 /// @param IsAddress True if the immediate represents an address. False if it
2632 /// @param IDLoc Location of the immediate in the source file.
2633 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2634 unsigned SrcReg, bool Is32BitImm,
2635 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2636 const MCSubtargetInfo *STI) {
2637 MipsTargetStreamer &TOut = getTargetStreamer();
2639 if (!Is32BitImm && !isGP64bit()) {
2640 Error(IDLoc, "instruction requires a 64-bit architecture");
2645 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2646 // Sign extend up to 64-bit so that the predicates match the hardware
2647 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2649 ImmValue = SignExtend64<32>(ImmValue);
2651 Error(IDLoc, "instruction requires a 32-bit immediate");
2656 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2657 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2659 bool UseSrcReg = false;
2660 if (SrcReg != Mips::NoRegister)
2663 unsigned TmpReg = DstReg;
2665 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2666 // At this point we need AT to perform the expansions and we exit if it is
2668 unsigned ATReg = getATReg(IDLoc);
2674 if (isInt<16>(ImmValue)) {
2678 // This doesn't quite follow the usual ABI expectations for N32 but matches
2679 // traditional assembler behaviour. N32 would normally use addiu for both
2680 // integers and addresses.
2681 if (IsAddress && !Is32BitImm) {
2682 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2686 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2690 if (isUInt<16>(ImmValue)) {
2691 unsigned TmpReg = DstReg;
2692 if (SrcReg == DstReg) {
2693 TmpReg = getATReg(IDLoc);
2698 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2700 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2704 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2705 warnIfNoMacro(IDLoc);
2707 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2708 uint16_t Bits15To0 = ImmValue & 0xffff;
2709 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2710 // Traditional behaviour seems to special case this particular value. It's
2711 // not clear why other masks are handled differently.
2712 if (ImmValue == 0xffffffff) {
2713 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2714 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2716 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2720 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2722 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2723 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2725 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2727 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2731 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2733 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2735 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2739 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2741 Error(IDLoc, "instruction requires a 32-bit immediate");
2745 // Traditionally, these immediates are shifted as little as possible and as
2746 // such we align the most significant bit to bit 15 of our temporary.
2747 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2748 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2749 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2750 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2751 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2752 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2755 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2760 warnIfNoMacro(IDLoc);
2762 // The remaining case is packed with a sequence of dsll and ori with zeros
2763 // being omitted and any neighbouring dsll's being coalesced.
2764 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2766 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2767 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2771 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2772 // skip it and defer the shift to the next chunk.
2773 unsigned ShiftCarriedForwards = 16;
2774 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2775 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2777 if (ImmChunk != 0) {
2778 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2779 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2780 ShiftCarriedForwards = 0;
2783 ShiftCarriedForwards += 16;
2785 ShiftCarriedForwards -= 16;
2787 // Finish any remaining shifts left by trailing zeros.
2788 if (ShiftCarriedForwards)
2789 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2792 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2797 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2798 MCStreamer &Out, const MCSubtargetInfo *STI) {
2799 const MCOperand &ImmOp = Inst.getOperand(1);
2800 assert(ImmOp.isImm() && "expected immediate operand kind");
2801 const MCOperand &DstRegOp = Inst.getOperand(0);
2802 assert(DstRegOp.isReg() && "expected register operand kind");
2804 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2805 Is32BitImm, false, IDLoc, Out, STI))
2811 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2812 const MCOperand &Offset,
2813 bool Is32BitAddress, SMLoc IDLoc,
2815 const MCSubtargetInfo *STI) {
2816 // la can't produce a usable address when addresses are 64-bit.
2817 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2818 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2819 // We currently can't do this because we depend on the equality
2820 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2821 Error(IDLoc, "la used to load 64-bit address");
2822 // Continue as if we had 'dla' instead.
2823 Is32BitAddress = false;
2827 // dla requires 64-bit addresses.
2828 if (!Is32BitAddress && !hasMips3()) {
2829 Error(IDLoc, "instruction requires a 64-bit architecture");
2833 if (!Offset.isImm())
2834 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2835 Is32BitAddress, IDLoc, Out, STI);
2837 if (!ABI.ArePtrs64bit()) {
2838 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2839 Is32BitAddress = true;
2842 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2846 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2847 unsigned DstReg, unsigned SrcReg,
2848 bool Is32BitSym, SMLoc IDLoc,
2850 const MCSubtargetInfo *STI) {
2851 // FIXME: These expansions do not respect -mxgot.
2852 MipsTargetStreamer &TOut = getTargetStreamer();
2853 bool UseSrcReg = SrcReg != Mips::NoRegister;
2854 warnIfNoMacro(IDLoc);
2856 if (inPicMode() && ABI.IsO32()) {
2858 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2859 Error(IDLoc, "expected relocatable expression");
2862 if (Res.getSymB() != nullptr) {
2863 Error(IDLoc, "expected relocatable expression with only one symbol");
2867 // The case where the result register is $25 is somewhat special. If the
2868 // symbol in the final relocation is external and not modified with a
2869 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2870 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2871 Res.getConstant() == 0 &&
2872 !(Res.getSymA()->getSymbol().isInSection() ||
2873 Res.getSymA()->getSymbol().isTemporary() ||
2874 (Res.getSymA()->getSymbol().isELF() &&
2875 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2877 const MCExpr *CallExpr =
2878 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2879 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2880 MCOperand::createExpr(CallExpr), IDLoc, STI);
2884 // The remaining cases are:
2885 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2886 // >addiu $tmp, $tmp, %lo(offset)
2887 // >addiu $rd, $tmp, $rs
2888 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2889 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2890 // >addiu $rd, $tmp, $rs
2891 // The addiu's marked with a '>' may be omitted if they are redundant. If
2892 // this happens then the last instruction must use $rd as the result
2894 const MipsMCExpr *GotExpr =
2895 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2896 const MCExpr *LoExpr = nullptr;
2897 if (Res.getSymA()->getSymbol().isInSection() ||
2898 Res.getSymA()->getSymbol().isTemporary())
2899 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2900 else if (Res.getConstant() != 0) {
2901 // External symbols fully resolve the symbol with just the %got(symbol)
2902 // but we must still account for any offset to the symbol for expressions
2904 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2907 unsigned TmpReg = DstReg;
2909 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2911 // If $rs is the same as $rd, we need to use AT.
2912 // If it is not available we exit.
2913 unsigned ATReg = getATReg(IDLoc);
2919 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2920 MCOperand::createExpr(GotExpr), IDLoc, STI);
2923 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2927 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2932 if (inPicMode() && ABI.ArePtrs64bit()) {
2934 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2935 Error(IDLoc, "expected relocatable expression");
2938 if (Res.getSymB() != nullptr) {
2939 Error(IDLoc, "expected relocatable expression with only one symbol");
2943 // The case where the result register is $25 is somewhat special. If the
2944 // symbol in the final relocation is external and not modified with a
2945 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2946 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2947 Res.getConstant() == 0 &&
2948 !(Res.getSymA()->getSymbol().isInSection() ||
2949 Res.getSymA()->getSymbol().isTemporary() ||
2950 (Res.getSymA()->getSymbol().isELF() &&
2951 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2953 const MCExpr *CallExpr =
2954 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2955 TOut.emitRRX(Mips::LD, DstReg, ABI.GetGlobalPtr(),
2956 MCOperand::createExpr(CallExpr), IDLoc, STI);
2960 // The remaining cases are:
2961 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2962 // >daddiu $tmp, $tmp, offset
2963 // >daddu $rd, $tmp, $rs
2964 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2965 // this happens then the last instruction must use $rd as the result
2967 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2970 const MCExpr *LoExpr = nullptr;
2971 if (Res.getConstant() != 0) {
2972 // Symbols fully resolve with just the %got_disp(symbol) but we
2973 // must still account for any offset to the symbol for
2974 // expressions like symbol+8.
2975 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2977 // FIXME: Offsets greater than 16 bits are not yet implemented.
2978 // FIXME: The correct range is a 32-bit sign-extended number.
2979 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2980 Error(IDLoc, "macro instruction uses large offset, which is not "
2981 "currently supported");
2986 unsigned TmpReg = DstReg;
2988 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2990 // If $rs is the same as $rd, we need to use AT.
2991 // If it is not available we exit.
2992 unsigned ATReg = getATReg(IDLoc);
2998 TOut.emitRRX(Mips::LD, TmpReg, ABI.GetGlobalPtr(),
2999 MCOperand::createExpr(GotExpr), IDLoc, STI);
3002 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3006 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3011 const MipsMCExpr *HiExpr =
3012 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3013 const MipsMCExpr *LoExpr =
3014 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3016 // This is the 64-bit symbol address expansion.
3017 if (ABI.ArePtrs64bit() && isGP64bit()) {
3018 // We need AT for the 64-bit expansion in the cases where the optional
3019 // source register is the destination register and for the superscalar
3022 // If it is not available we exit if the destination is the same as the
3025 const MipsMCExpr *HighestExpr =
3026 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3027 const MipsMCExpr *HigherExpr =
3028 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3031 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3033 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3034 unsigned ATReg = getATReg(IDLoc);
3036 // If $rs is the same as $rd:
3037 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3038 // daddiu $at, $at, %higher(sym)
3039 // dsll $at, $at, 16
3040 // daddiu $at, $at, %hi(sym)
3041 // dsll $at, $at, 16
3042 // daddiu $at, $at, %lo(sym)
3043 // daddu $rd, $at, $rd
3044 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3046 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3047 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3048 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3049 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3051 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3052 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3054 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3057 } else if (canUseATReg() && !RdRegIsRsReg) {
3058 unsigned ATReg = getATReg(IDLoc);
3060 // If the $rs is different from $rd or if $rs isn't specified and we
3061 // have $at available:
3062 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3063 // lui $at, %hi(sym)
3064 // daddiu $rd, $rd, %higher(sym)
3065 // daddiu $at, $at, %lo(sym)
3066 // dsll32 $rd, $rd, 0
3067 // daddu $rd, $rd, $at
3068 // (daddu $rd, $rd, $rs)
3070 // Which is preferred for superscalar issue.
3071 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3073 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3074 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3075 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3076 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3078 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3079 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3081 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3084 } else if (!canUseATReg() && !RdRegIsRsReg) {
3085 // Otherwise, synthesize the address in the destination register
3087 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3088 // daddiu $rd, $rd, %higher(sym)
3089 // dsll $rd, $rd, 16
3090 // daddiu $rd, $rd, %hi(sym)
3091 // dsll $rd, $rd, 16
3092 // daddiu $rd, $rd, %lo(sym)
3093 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3095 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3096 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3097 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3098 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3099 MCOperand::createExpr(HiExpr), IDLoc, STI);
3100 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3101 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3102 MCOperand::createExpr(LoExpr), IDLoc, STI);
3104 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3108 // We have a case where SrcReg == DstReg and we don't have $at
3109 // available. We can't expand this case, so error out appropriately.
3110 assert(SrcReg == DstReg && !canUseATReg() &&
3111 "Could have expanded dla but didn't?");
3112 reportParseError(IDLoc,
3113 "pseudo-instruction requires $at, which is not available");
3118 // And now, the 32-bit symbol address expansion:
3119 // If $rs is the same as $rd:
3120 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3121 // ori $at, $at, %lo(sym)
3122 // addu $rd, $at, $rd
3123 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3124 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3125 // ori $rd, $rd, %lo(sym)
3126 // (addu $rd, $rd, $rs)
3127 unsigned TmpReg = DstReg;
3129 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3130 // If $rs is the same as $rd, we need to use AT.
3131 // If it is not available we exit.
3132 unsigned ATReg = getATReg(IDLoc);
3138 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3139 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3143 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3146 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3151 // Each double-precision register DO-D15 overlaps with two of the single
3152 // precision registers F0-F31. As an example, all of the following hold true:
3153 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3154 static unsigned nextReg(unsigned Reg) {
3155 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3156 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3158 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3159 case Mips::ZERO: return Mips::AT;
3160 case Mips::AT: return Mips::V0;
3161 case Mips::V0: return Mips::V1;
3162 case Mips::V1: return Mips::A0;
3163 case Mips::A0: return Mips::A1;
3164 case Mips::A1: return Mips::A2;
3165 case Mips::A2: return Mips::A3;
3166 case Mips::A3: return Mips::T0;
3167 case Mips::T0: return Mips::T1;
3168 case Mips::T1: return Mips::T2;
3169 case Mips::T2: return Mips::T3;
3170 case Mips::T3: return Mips::T4;
3171 case Mips::T4: return Mips::T5;
3172 case Mips::T5: return Mips::T6;
3173 case Mips::T6: return Mips::T7;
3174 case Mips::T7: return Mips::S0;
3175 case Mips::S0: return Mips::S1;
3176 case Mips::S1: return Mips::S2;
3177 case Mips::S2: return Mips::S3;
3178 case Mips::S3: return Mips::S4;
3179 case Mips::S4: return Mips::S5;
3180 case Mips::S5: return Mips::S6;
3181 case Mips::S6: return Mips::S7;
3182 case Mips::S7: return Mips::T8;
3183 case Mips::T8: return Mips::T9;
3184 case Mips::T9: return Mips::K0;
3185 case Mips::K0: return Mips::K1;
3186 case Mips::K1: return Mips::GP;
3187 case Mips::GP: return Mips::SP;
3188 case Mips::SP: return Mips::FP;
3189 case Mips::FP: return Mips::RA;
3190 case Mips::RA: return Mips::ZERO;
3191 case Mips::D0: return Mips::F1;
3192 case Mips::D1: return Mips::F3;
3193 case Mips::D2: return Mips::F5;
3194 case Mips::D3: return Mips::F7;
3195 case Mips::D4: return Mips::F9;
3196 case Mips::D5: return Mips::F11;
3197 case Mips::D6: return Mips::F13;
3198 case Mips::D7: return Mips::F15;
3199 case Mips::D8: return Mips::F17;
3200 case Mips::D9: return Mips::F19;
3201 case Mips::D10: return Mips::F21;
3202 case Mips::D11: return Mips::F23;
3203 case Mips::D12: return Mips::F25;
3204 case Mips::D13: return Mips::F27;
3205 case Mips::D14: return Mips::F29;
3206 case Mips::D15: return Mips::F31;
3210 // FIXME: This method is too general. In principle we should compute the number
3211 // of instructions required to synthesize the immediate inline compared to
3212 // synthesizing the address inline and relying on non .text sections.
3213 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3214 // likely to yield a much larger benefit as we have to synthesize a 64bit
3215 // address to load a 64 bit value.
3216 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3218 unsigned ATReg = getATReg(IDLoc);
3223 const MCExpr *GotSym =
3224 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3225 const MipsMCExpr *GotExpr =
3226 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3228 if(isABI_O32() || isABI_N32()) {
3229 TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3231 } else { //isABI_N64()
3232 TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
3235 } else { //!IsPicEnabled
3236 const MCExpr *HiSym =
3237 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3238 const MipsMCExpr *HiExpr =
3239 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3241 // FIXME: This is technically correct but gives a different result to gas,
3242 // but gas is incomplete there (it has a fixme noting it doesn't work with
3243 // 64-bit addresses).
3244 // FIXME: With -msym32 option, the address expansion for N64 should probably
3245 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3246 // symbol's value is considered sign extended.
3247 if(isABI_O32() || isABI_N32()) {
3248 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3249 } else { //isABI_N64()
3250 const MCExpr *HighestSym =
3251 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3252 const MipsMCExpr *HighestExpr =
3253 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3254 const MCExpr *HigherSym =
3255 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3256 const MipsMCExpr *HigherExpr =
3257 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3259 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3261 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3262 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3263 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3264 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3266 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3272 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3273 bool Is64FPU, SMLoc IDLoc,
3275 const MCSubtargetInfo *STI) {
3276 MipsTargetStreamer &TOut = getTargetStreamer();
3277 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3278 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3279 "Invalid instruction operand.");
3281 unsigned FirstReg = Inst.getOperand(0).getReg();
3282 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3284 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3285 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3286 // exponent field), convert it to double (e.g. 1 to 1.0)
3287 if ((HiImmOp64 & 0x7ff00000) == 0) {
3288 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3289 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3292 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3293 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3296 // Conversion of a double in an uint64_t to a float in a uint32_t,
3297 // retaining the bit pattern of a float.
3299 double doubleImm = BitsToDouble(ImmOp64);
3300 float tmp_float = static_cast<float>(doubleImm);
3301 ImmOp32 = FloatToBits(tmp_float);
3304 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3309 unsigned ATReg = getATReg(IDLoc);
3312 if (LoImmOp64 == 0) {
3313 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3316 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3320 MCSection *CS = getStreamer().getCurrentSectionOnly();
3321 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3322 // where appropriate.
3323 MCSection *ReadOnlySection = getContext().getELFSection(
3324 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3326 MCSymbol *Sym = getContext().createTempSymbol();
3327 const MCExpr *LoSym =
3328 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3329 const MipsMCExpr *LoExpr =
3330 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3332 getStreamer().SwitchSection(ReadOnlySection);
3333 getStreamer().EmitLabel(Sym, IDLoc);
3334 getStreamer().EmitIntValue(ImmOp32, 4);
3335 getStreamer().SwitchSection(CS);
3337 if(emitPartialAddress(TOut, IDLoc, Sym))
3339 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3340 MCOperand::createExpr(LoExpr), IDLoc, STI);
3346 unsigned ATReg = getATReg(IDLoc);
3351 if (LoImmOp64 == 0) {
3352 if(isABI_N32() || isABI_N64()) {
3353 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3358 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3362 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3369 MCSection *CS = getStreamer().getCurrentSectionOnly();
3370 MCSection *ReadOnlySection = getContext().getELFSection(
3371 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3373 MCSymbol *Sym = getContext().createTempSymbol();
3374 const MCExpr *LoSym =
3375 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3376 const MipsMCExpr *LoExpr =
3377 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3379 getStreamer().SwitchSection(ReadOnlySection);
3380 getStreamer().EmitLabel(Sym, IDLoc);
3381 getStreamer().EmitIntValue(HiImmOp64, 4);
3382 getStreamer().EmitIntValue(LoImmOp64, 4);
3383 getStreamer().SwitchSection(CS);
3385 if(emitPartialAddress(TOut, IDLoc, Sym))
3388 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3389 MCOperand::createExpr(LoExpr), IDLoc, STI);
3391 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3392 MCOperand::createExpr(LoExpr), IDLoc, STI);
3394 if(isABI_N32() || isABI_N64())
3395 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3397 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3398 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3401 } else { // if(!IsGPR && !IsSingle)
3402 if ((LoImmOp64 == 0) &&
3403 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3404 // FIXME: In the case where the constant is zero, we can load the
3405 // register directly from the zero register.
3406 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3409 if (isABI_N32() || isABI_N64())
3410 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3411 else if (hasMips32r2()) {
3412 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3413 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3415 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3416 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3421 MCSection *CS = getStreamer().getCurrentSectionOnly();
3422 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3423 // where appropriate.
3424 MCSection *ReadOnlySection = getContext().getELFSection(
3425 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3427 MCSymbol *Sym = getContext().createTempSymbol();
3428 const MCExpr *LoSym =
3429 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3430 const MipsMCExpr *LoExpr =
3431 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3433 getStreamer().SwitchSection(ReadOnlySection);
3434 getStreamer().EmitLabel(Sym, IDLoc);
3435 getStreamer().EmitIntValue(HiImmOp64, 4);
3436 getStreamer().EmitIntValue(LoImmOp64, 4);
3437 getStreamer().SwitchSection(CS);
3439 if(emitPartialAddress(TOut, IDLoc, Sym))
3441 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3442 MCOperand::createExpr(LoExpr), IDLoc, STI);
3447 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3449 const MCSubtargetInfo *STI) {
3450 MipsTargetStreamer &TOut = getTargetStreamer();
3452 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3453 "unexpected number of operands");
3455 MCOperand Offset = Inst.getOperand(0);
3456 if (Offset.isExpr()) {
3458 Inst.setOpcode(Mips::BEQ_MM);
3459 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3460 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3461 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3463 assert(Offset.isImm() && "expected immediate operand kind");
3464 if (isInt<11>(Offset.getImm())) {
3465 // If offset fits into 11 bits then this instruction becomes microMIPS
3466 // 16-bit unconditional branch instruction.
3467 if (inMicroMipsMode())
3468 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3470 if (!isInt<17>(Offset.getImm()))
3471 return Error(IDLoc, "branch target out of range");
3472 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3473 return Error(IDLoc, "branch to misaligned address");
3475 Inst.setOpcode(Mips::BEQ_MM);
3476 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3477 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3478 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3481 Out.EmitInstruction(Inst, *STI);
3483 // If .set reorder is active and branch instruction has a delay slot,
3484 // emit a NOP after it.
3485 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3486 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3487 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3492 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3493 const MCSubtargetInfo *STI) {
3494 MipsTargetStreamer &TOut = getTargetStreamer();
3495 const MCOperand &DstRegOp = Inst.getOperand(0);
3496 assert(DstRegOp.isReg() && "expected register operand kind");
3498 const MCOperand &ImmOp = Inst.getOperand(1);
3499 assert(ImmOp.isImm() && "expected immediate operand kind");
3501 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3502 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3503 "expected immediate or expression operand");
3505 bool IsLikely = false;
3507 unsigned OpCode = 0;
3508 switch(Inst.getOpcode()) {
3515 case Mips::BEQLImmMacro:
3516 OpCode = Mips::BEQL;
3519 case Mips::BNELImmMacro:
3520 OpCode = Mips::BNEL;
3524 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3528 int64_t ImmValue = ImmOp.getImm();
3529 if (ImmValue == 0) {
3531 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3532 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3533 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3535 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3538 warnIfNoMacro(IDLoc);
3540 unsigned ATReg = getATReg(IDLoc);
3544 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3549 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3550 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3551 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3553 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3558 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3559 const MCSubtargetInfo *STI, bool IsLoad) {
3560 const MCOperand &DstRegOp = Inst.getOperand(0);
3561 assert(DstRegOp.isReg() && "expected register operand kind");
3562 const MCOperand &BaseRegOp = Inst.getOperand(1);
3563 assert(BaseRegOp.isReg() && "expected register operand kind");
3564 const MCOperand &OffsetOp = Inst.getOperand(2);
3566 MipsTargetStreamer &TOut = getTargetStreamer();
3567 unsigned DstReg = DstRegOp.getReg();
3568 unsigned BaseReg = BaseRegOp.getReg();
3569 unsigned TmpReg = DstReg;
3571 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3572 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3573 unsigned DstRegClassID =
3574 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3575 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3576 (DstRegClassID == Mips::GPR64RegClassID);
3578 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3579 // At this point we need AT to perform the expansions
3580 // and we exit if it is not available.
3581 TmpReg = getATReg(IDLoc);
3586 if (OffsetOp.isImm()) {
3587 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3588 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3590 // If msb of LoOffset is 1(negative number) we must increment
3591 // HiOffset to account for the sign-extension of the low part.
3592 if (LoOffset & 0x8000)
3593 HiOffset += 0x10000;
3595 bool IsLargeOffset = HiOffset != 0;
3597 if (IsLargeOffset) {
3598 bool Is32BitImm = (HiOffset >> 32) == 0;
3599 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3604 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3605 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3606 BaseReg, IDLoc, STI);
3607 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3609 assert(OffsetOp.isExpr() && "expected expression operand kind");
3610 const MCExpr *ExprOffset = OffsetOp.getExpr();
3611 MCOperand LoOperand = MCOperand::createExpr(
3612 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3613 MCOperand HiOperand = MCOperand::createExpr(
3614 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3617 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3618 LoOperand, TmpReg, IDLoc, STI);
3620 TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3621 LoOperand, TmpReg, IDLoc, STI);
3625 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3627 const MCSubtargetInfo *STI) {
3628 unsigned OpNum = Inst.getNumOperands();
3629 unsigned Opcode = Inst.getOpcode();
3630 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3632 assert(Inst.getOperand(OpNum - 1).isImm() &&
3633 Inst.getOperand(OpNum - 2).isReg() &&
3634 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3636 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3637 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3638 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3639 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3640 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3641 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3642 // It can be implemented as SWM16 or LWM16 instruction.
3643 if (inMicroMipsMode() && hasMips32r6())
3644 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3646 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3649 Inst.setOpcode(NewOpcode);
3650 Out.EmitInstruction(Inst, *STI);
3654 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3656 const MCSubtargetInfo *STI) {
3657 MipsTargetStreamer &TOut = getTargetStreamer();
3658 bool EmittedNoMacroWarning = false;
3659 unsigned PseudoOpcode = Inst.getOpcode();
3660 unsigned SrcReg = Inst.getOperand(0).getReg();
3661 const MCOperand &TrgOp = Inst.getOperand(1);
3662 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3664 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3665 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3669 TrgReg = TrgOp.getReg();
3670 else if (TrgOp.isImm()) {
3671 warnIfNoMacro(IDLoc);
3672 EmittedNoMacroWarning = true;
3674 TrgReg = getATReg(IDLoc);
3678 switch(PseudoOpcode) {
3680 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3681 case Mips::BLTImmMacro:
3682 PseudoOpcode = Mips::BLT;
3684 case Mips::BLEImmMacro:
3685 PseudoOpcode = Mips::BLE;
3687 case Mips::BGEImmMacro:
3688 PseudoOpcode = Mips::BGE;
3690 case Mips::BGTImmMacro:
3691 PseudoOpcode = Mips::BGT;
3693 case Mips::BLTUImmMacro:
3694 PseudoOpcode = Mips::BLTU;
3696 case Mips::BLEUImmMacro:
3697 PseudoOpcode = Mips::BLEU;
3699 case Mips::BGEUImmMacro:
3700 PseudoOpcode = Mips::BGEU;
3702 case Mips::BGTUImmMacro:
3703 PseudoOpcode = Mips::BGTU;
3705 case Mips::BLTLImmMacro:
3706 PseudoOpcode = Mips::BLTL;
3708 case Mips::BLELImmMacro:
3709 PseudoOpcode = Mips::BLEL;
3711 case Mips::BGELImmMacro:
3712 PseudoOpcode = Mips::BGEL;
3714 case Mips::BGTLImmMacro:
3715 PseudoOpcode = Mips::BGTL;
3717 case Mips::BLTULImmMacro:
3718 PseudoOpcode = Mips::BLTUL;
3720 case Mips::BLEULImmMacro:
3721 PseudoOpcode = Mips::BLEUL;
3723 case Mips::BGEULImmMacro:
3724 PseudoOpcode = Mips::BGEUL;
3726 case Mips::BGTULImmMacro:
3727 PseudoOpcode = Mips::BGTUL;
3731 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3732 false, IDLoc, Out, STI))
3736 switch (PseudoOpcode) {
3741 AcceptsEquality = false;
3742 ReverseOrderSLT = false;
3744 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3745 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3746 ZeroSrcOpcode = Mips::BGTZ;
3747 ZeroTrgOpcode = Mips::BLTZ;
3753 AcceptsEquality = true;
3754 ReverseOrderSLT = true;
3756 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3757 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3758 ZeroSrcOpcode = Mips::BGEZ;
3759 ZeroTrgOpcode = Mips::BLEZ;
3765 AcceptsEquality = true;
3766 ReverseOrderSLT = false;
3768 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3769 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3770 ZeroSrcOpcode = Mips::BLEZ;
3771 ZeroTrgOpcode = Mips::BGEZ;
3777 AcceptsEquality = false;
3778 ReverseOrderSLT = true;
3780 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3781 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3782 ZeroSrcOpcode = Mips::BLTZ;
3783 ZeroTrgOpcode = Mips::BGTZ;
3786 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3789 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3790 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3791 if (IsSrcRegZero && IsTrgRegZero) {
3792 // FIXME: All of these Opcode-specific if's are needed for compatibility
3793 // with GAS' behaviour. However, they may not generate the most efficient
3794 // code in some circumstances.
3795 if (PseudoOpcode == Mips::BLT) {
3796 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3800 if (PseudoOpcode == Mips::BLE) {
3801 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3803 Warning(IDLoc, "branch is always taken");
3806 if (PseudoOpcode == Mips::BGE) {
3807 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3809 Warning(IDLoc, "branch is always taken");
3812 if (PseudoOpcode == Mips::BGT) {
3813 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3817 if (PseudoOpcode == Mips::BGTU) {
3818 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3819 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3822 if (AcceptsEquality) {
3823 // If both registers are $0 and the pseudo-branch accepts equality, it
3824 // will always be taken, so we emit an unconditional branch.
3825 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3826 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3827 Warning(IDLoc, "branch is always taken");
3830 // If both registers are $0 and the pseudo-branch does not accept
3831 // equality, it will never be taken, so we don't have to emit anything.
3834 if (IsSrcRegZero || IsTrgRegZero) {
3835 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3836 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3837 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3838 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3839 // the pseudo-branch will never be taken, so we don't emit anything.
3840 // This only applies to unsigned pseudo-branches.
3843 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3844 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3845 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3846 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3847 // the pseudo-branch will always be taken, so we emit an unconditional
3849 // This only applies to unsigned pseudo-branches.
3850 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3851 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3852 Warning(IDLoc, "branch is always taken");
3856 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3857 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3858 // the pseudo-branch will be taken only when the non-zero register is
3859 // different from 0, so we emit a BNEZ.
3861 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3862 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3863 // the pseudo-branch will be taken only when the non-zero register is
3864 // equal to 0, so we emit a BEQZ.
3866 // Because only BLEU and BGEU branch on equality, we can use the
3867 // AcceptsEquality variable to decide when to emit the BEQZ.
3868 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3869 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3870 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3873 // If we have a signed pseudo-branch and one of the registers is $0,
3874 // we can use an appropriate compare-to-zero branch. We select which one
3875 // to use in the switch statement above.
3876 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3877 IsSrcRegZero ? TrgReg : SrcReg,
3878 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3882 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3883 // expansions. If it is not available, we return.
3884 unsigned ATRegNum = getATReg(IDLoc);
3888 if (!EmittedNoMacroWarning)
3889 warnIfNoMacro(IDLoc);
3891 // SLT fits well with 2 of our 4 pseudo-branches:
3892 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3893 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3894 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3895 // This is accomplished by using a BNEZ with the result of the SLT.
3897 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3898 // and BLE with BGT), so we change the BNEZ into a BEQZ.
3899 // Because only BGE and BLE branch on equality, we can use the
3900 // AcceptsEquality variable to decide when to emit the BEQZ.
3901 // Note that the order of the SLT arguments doesn't change between
3904 // The same applies to the unsigned variants, except that SLTu is used
3906 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3907 ReverseOrderSLT ? TrgReg : SrcReg,
3908 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3910 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3911 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3912 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3917 // Expand a integer division macro.
3919 // Notably we don't have to emit a warning when encountering $rt as the $zero
3920 // register, or 0 as an immediate. processInstruction() has already done that.
3922 // The destination register can only be $zero when expanding (S)DivIMacro or
3925 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3926 const MCSubtargetInfo *STI, const bool IsMips64,
3927 const bool Signed) {
3928 MipsTargetStreamer &TOut = getTargetStreamer();
3930 warnIfNoMacro(IDLoc);
3932 const MCOperand &RdRegOp = Inst.getOperand(0);
3933 assert(RdRegOp.isReg() && "expected register operand kind");
3934 unsigned RdReg = RdRegOp.getReg();
3936 const MCOperand &RsRegOp = Inst.getOperand(1);
3937 assert(RsRegOp.isReg() && "expected register operand kind");
3938 unsigned RsReg = RsRegOp.getReg();
3943 const MCOperand &RtOp = Inst.getOperand(2);
3944 assert((RtOp.isReg() || RtOp.isImm()) &&
3945 "expected register or immediate operand kind");
3947 RtReg = RtOp.getReg();
3949 ImmValue = RtOp.getImm();
3956 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3957 ZeroReg = Mips::ZERO_64;
3960 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3961 ZeroReg = Mips::ZERO;
3965 bool UseTraps = useTraps();
3967 unsigned Opcode = Inst.getOpcode();
3968 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
3969 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
3970 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
3971 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
3973 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
3974 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
3975 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
3976 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
3979 unsigned ATReg = getATReg(IDLoc);
3983 if (ImmValue == 0) {
3985 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3987 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3991 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
3992 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
3994 } else if (isDiv && ImmValue == 1) {
3995 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
3997 } else if (isDiv && Signed && ImmValue == -1) {
3998 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4001 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4002 false, Inst.getLoc(), Out, STI))
4004 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4005 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4011 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4012 // break, insert the trap/break and exit. This gives a different result to
4013 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4014 // are handled equivalently. As the observed behaviour is the same, we're ok.
4015 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4017 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4020 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4024 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4025 // not expand to macro sequence.
4026 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4027 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4031 // Temporary label for first branch traget
4032 MCContext &Context = TOut.getStreamer().getContext();
4037 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4039 // Branch to the li instruction.
4040 BrTarget = Context.createTempSymbol();
4041 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4042 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4045 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4048 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4052 TOut.getStreamer().EmitLabel(BrTarget);
4054 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4058 unsigned ATReg = getATReg(IDLoc);
4063 TOut.getStreamer().EmitLabel(BrTarget);
4065 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4067 // Temporary label for the second branch target.
4068 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4069 MCOperand LabelOpEnd =
4070 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4072 // Branch to the mflo instruction.
4073 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4076 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4077 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4079 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4083 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4085 // Branch to the mflo instruction.
4086 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4087 TOut.emitNop(IDLoc, STI);
4088 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4091 TOut.getStreamer().EmitLabel(BrTargetEnd);
4092 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4096 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4097 SMLoc IDLoc, MCStreamer &Out,
4098 const MCSubtargetInfo *STI) {
4099 MipsTargetStreamer &TOut = getTargetStreamer();
4101 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4102 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4103 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4105 unsigned FirstReg = Inst.getOperand(0).getReg();
4106 unsigned SecondReg = Inst.getOperand(1).getReg();
4107 unsigned ThirdReg = Inst.getOperand(2).getReg();
4109 if (hasMips1() && !hasMips2()) {
4110 unsigned ATReg = getATReg(IDLoc);
4113 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4114 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4115 TOut.emitNop(IDLoc, STI);
4116 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4117 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4118 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4119 TOut.emitNop(IDLoc, STI);
4120 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4122 FirstReg, SecondReg, IDLoc, STI);
4123 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4124 TOut.emitNop(IDLoc, STI);
4128 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4130 FirstReg, SecondReg, IDLoc, STI);
4135 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4136 MCStreamer &Out, const MCSubtargetInfo *STI) {
4137 if (hasMips32r6() || hasMips64r6()) {
4138 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4141 const MCOperand &DstRegOp = Inst.getOperand(0);
4142 assert(DstRegOp.isReg() && "expected register operand kind");
4143 const MCOperand &SrcRegOp = Inst.getOperand(1);
4144 assert(SrcRegOp.isReg() && "expected register operand kind");
4145 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4146 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4148 MipsTargetStreamer &TOut = getTargetStreamer();
4149 unsigned DstReg = DstRegOp.getReg();
4150 unsigned SrcReg = SrcRegOp.getReg();
4151 int64_t OffsetValue = OffsetImmOp.getImm();
4153 // NOTE: We always need AT for ULHU, as it is always used as the source
4154 // register for one of the LBu's.
4155 warnIfNoMacro(IDLoc);
4156 unsigned ATReg = getATReg(IDLoc);
4160 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4161 if (IsLargeOffset) {
4162 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4167 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4168 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4170 std::swap(FirstOffset, SecondOffset);
4172 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4173 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4175 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4176 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4178 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4179 FirstOffset, IDLoc, STI);
4180 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4181 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4182 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4187 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4188 const MCSubtargetInfo *STI) {
4189 if (hasMips32r6() || hasMips64r6()) {
4190 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4193 const MCOperand &DstRegOp = Inst.getOperand(0);
4194 assert(DstRegOp.isReg() && "expected register operand kind");
4195 const MCOperand &SrcRegOp = Inst.getOperand(1);
4196 assert(SrcRegOp.isReg() && "expected register operand kind");
4197 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4198 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4200 MipsTargetStreamer &TOut = getTargetStreamer();
4201 unsigned DstReg = DstRegOp.getReg();
4202 unsigned SrcReg = SrcRegOp.getReg();
4203 int64_t OffsetValue = OffsetImmOp.getImm();
4205 warnIfNoMacro(IDLoc);
4206 unsigned ATReg = getATReg(IDLoc);
4210 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4211 if (IsLargeOffset) {
4212 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4217 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4218 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4220 std::swap(FirstOffset, SecondOffset);
4222 if (IsLargeOffset) {
4223 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4224 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4225 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4226 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4227 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4228 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4230 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4231 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4232 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4238 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4239 const MCSubtargetInfo *STI) {
4240 if (hasMips32r6() || hasMips64r6()) {
4241 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4244 const MCOperand &DstRegOp = Inst.getOperand(0);
4245 assert(DstRegOp.isReg() && "expected register operand kind");
4246 const MCOperand &SrcRegOp = Inst.getOperand(1);
4247 assert(SrcRegOp.isReg() && "expected register operand kind");
4248 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4249 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4251 MipsTargetStreamer &TOut = getTargetStreamer();
4252 unsigned DstReg = DstRegOp.getReg();
4253 unsigned SrcReg = SrcRegOp.getReg();
4254 int64_t OffsetValue = OffsetImmOp.getImm();
4256 // Compute left/right load/store offsets.
4257 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4258 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4259 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4261 std::swap(LxlOffset, LxrOffset);
4263 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4264 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4265 unsigned TmpReg = SrcReg;
4266 if (IsLargeOffset || DoMove) {
4267 warnIfNoMacro(IDLoc);
4268 TmpReg = getATReg(IDLoc);
4273 if (IsLargeOffset) {
4274 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4280 std::swap(DstReg, TmpReg);
4282 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4283 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4284 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4285 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4288 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4293 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4295 const MCSubtargetInfo *STI) {
4296 MipsTargetStreamer &TOut = getTargetStreamer();
4298 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4299 assert(Inst.getOperand(0).isReg() &&
4300 Inst.getOperand(1).isReg() &&
4301 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4303 unsigned ATReg = Mips::NoRegister;
4304 unsigned FinalDstReg = Mips::NoRegister;
4305 unsigned DstReg = Inst.getOperand(0).getReg();
4306 unsigned SrcReg = Inst.getOperand(1).getReg();
4307 int64_t ImmValue = Inst.getOperand(2).getImm();
4309 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4311 unsigned FinalOpcode = Inst.getOpcode();
4313 if (DstReg == SrcReg) {
4314 ATReg = getATReg(Inst.getLoc());
4317 FinalDstReg = DstReg;
4321 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4322 Inst.getLoc(), Out, STI)) {
4323 switch (FinalOpcode) {
4325 llvm_unreachable("unimplemented expansion");
4327 FinalOpcode = Mips::ADD;
4330 FinalOpcode = Mips::ADDu;
4333 FinalOpcode = Mips::AND;
4336 FinalOpcode = Mips::NOR;
4339 FinalOpcode = Mips::OR;
4342 FinalOpcode = Mips::SLT;
4345 FinalOpcode = Mips::SLTu;
4348 FinalOpcode = Mips::XOR;
4351 FinalOpcode = Mips::ADD_MM;
4353 case Mips::ADDiu_MM:
4354 FinalOpcode = Mips::ADDu_MM;
4357 FinalOpcode = Mips::AND_MM;
4360 FinalOpcode = Mips::OR_MM;
4363 FinalOpcode = Mips::SLT_MM;
4365 case Mips::SLTiu_MM:
4366 FinalOpcode = Mips::SLTu_MM;
4369 FinalOpcode = Mips::XOR_MM;
4372 FinalOpcode = Mips::AND64;
4374 case Mips::NORImm64:
4375 FinalOpcode = Mips::NOR64;
4378 FinalOpcode = Mips::OR64;
4380 case Mips::SLTImm64:
4381 FinalOpcode = Mips::SLT64;
4383 case Mips::SLTUImm64:
4384 FinalOpcode = Mips::SLTu64;
4387 FinalOpcode = Mips::XOR64;
4391 if (FinalDstReg == Mips::NoRegister)
4392 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4394 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4400 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4401 const MCSubtargetInfo *STI) {
4402 MipsTargetStreamer &TOut = getTargetStreamer();
4403 unsigned ATReg = Mips::NoRegister;
4404 unsigned DReg = Inst.getOperand(0).getReg();
4405 unsigned SReg = Inst.getOperand(1).getReg();
4406 unsigned TReg = Inst.getOperand(2).getReg();
4407 unsigned TmpReg = DReg;
4409 unsigned FirstShift = Mips::NOP;
4410 unsigned SecondShift = Mips::NOP;
4412 if (hasMips32r2()) {
4414 TmpReg = getATReg(Inst.getLoc());
4419 if (Inst.getOpcode() == Mips::ROL) {
4420 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4421 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4425 if (Inst.getOpcode() == Mips::ROR) {
4426 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4434 switch (Inst.getOpcode()) {
4436 llvm_unreachable("unexpected instruction opcode");
4438 FirstShift = Mips::SRLV;
4439 SecondShift = Mips::SLLV;
4442 FirstShift = Mips::SLLV;
4443 SecondShift = Mips::SRLV;
4447 ATReg = getATReg(Inst.getLoc());
4451 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4452 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4453 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4454 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4462 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4464 const MCSubtargetInfo *STI) {
4465 MipsTargetStreamer &TOut = getTargetStreamer();
4466 unsigned ATReg = Mips::NoRegister;
4467 unsigned DReg = Inst.getOperand(0).getReg();
4468 unsigned SReg = Inst.getOperand(1).getReg();
4469 int64_t ImmValue = Inst.getOperand(2).getImm();
4471 unsigned FirstShift = Mips::NOP;
4472 unsigned SecondShift = Mips::NOP;
4474 if (hasMips32r2()) {
4475 if (Inst.getOpcode() == Mips::ROLImm) {
4476 uint64_t MaxShift = 32;
4477 uint64_t ShiftValue = ImmValue;
4479 ShiftValue = MaxShift - ImmValue;
4480 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4484 if (Inst.getOpcode() == Mips::RORImm) {
4485 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4493 if (ImmValue == 0) {
4494 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4498 switch (Inst.getOpcode()) {
4500 llvm_unreachable("unexpected instruction opcode");
4502 FirstShift = Mips::SLL;
4503 SecondShift = Mips::SRL;
4506 FirstShift = Mips::SRL;
4507 SecondShift = Mips::SLL;
4511 ATReg = getATReg(Inst.getLoc());
4515 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4516 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4517 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4525 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4526 const MCSubtargetInfo *STI) {
4527 MipsTargetStreamer &TOut = getTargetStreamer();
4528 unsigned ATReg = Mips::NoRegister;
4529 unsigned DReg = Inst.getOperand(0).getReg();
4530 unsigned SReg = Inst.getOperand(1).getReg();
4531 unsigned TReg = Inst.getOperand(2).getReg();
4532 unsigned TmpReg = DReg;
4534 unsigned FirstShift = Mips::NOP;
4535 unsigned SecondShift = Mips::NOP;
4537 if (hasMips64r2()) {
4538 if (TmpReg == SReg) {
4539 TmpReg = getATReg(Inst.getLoc());
4544 if (Inst.getOpcode() == Mips::DROL) {
4545 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4546 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4550 if (Inst.getOpcode() == Mips::DROR) {
4551 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4559 switch (Inst.getOpcode()) {
4561 llvm_unreachable("unexpected instruction opcode");
4563 FirstShift = Mips::DSRLV;
4564 SecondShift = Mips::DSLLV;
4567 FirstShift = Mips::DSLLV;
4568 SecondShift = Mips::DSRLV;
4572 ATReg = getATReg(Inst.getLoc());
4576 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4577 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4578 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4579 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4587 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4589 const MCSubtargetInfo *STI) {
4590 MipsTargetStreamer &TOut = getTargetStreamer();
4591 unsigned ATReg = Mips::NoRegister;
4592 unsigned DReg = Inst.getOperand(0).getReg();
4593 unsigned SReg = Inst.getOperand(1).getReg();
4594 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4596 unsigned FirstShift = Mips::NOP;
4597 unsigned SecondShift = Mips::NOP;
4601 if (hasMips64r2()) {
4602 unsigned FinalOpcode = Mips::NOP;
4604 FinalOpcode = Mips::DROTR;
4605 else if (ImmValue % 32 == 0)
4606 FinalOpcode = Mips::DROTR32;
4607 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4608 if (Inst.getOpcode() == Mips::DROLImm)
4609 FinalOpcode = Mips::DROTR32;
4611 FinalOpcode = Mips::DROTR;
4612 } else if (ImmValue >= 33) {
4613 if (Inst.getOpcode() == Mips::DROLImm)
4614 FinalOpcode = Mips::DROTR;
4616 FinalOpcode = Mips::DROTR32;
4619 uint64_t ShiftValue = ImmValue % 32;
4620 if (Inst.getOpcode() == Mips::DROLImm)
4621 ShiftValue = (32 - ImmValue % 32) % 32;
4623 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4629 if (ImmValue == 0) {
4630 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4634 switch (Inst.getOpcode()) {
4636 llvm_unreachable("unexpected instruction opcode");
4638 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4639 FirstShift = Mips::DSLL;
4640 SecondShift = Mips::DSRL32;
4642 if (ImmValue == 32) {
4643 FirstShift = Mips::DSLL32;
4644 SecondShift = Mips::DSRL32;
4646 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4647 FirstShift = Mips::DSLL32;
4648 SecondShift = Mips::DSRL;
4652 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4653 FirstShift = Mips::DSRL;
4654 SecondShift = Mips::DSLL32;
4656 if (ImmValue == 32) {
4657 FirstShift = Mips::DSRL32;
4658 SecondShift = Mips::DSLL32;
4660 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4661 FirstShift = Mips::DSRL32;
4662 SecondShift = Mips::DSLL;
4667 ATReg = getATReg(Inst.getLoc());
4671 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4672 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4673 Inst.getLoc(), STI);
4674 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4682 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4683 const MCSubtargetInfo *STI) {
4684 MipsTargetStreamer &TOut = getTargetStreamer();
4685 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4686 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4688 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4689 if (FirstRegOp != SecondRegOp)
4690 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4692 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4693 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4698 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4699 const MCSubtargetInfo *STI) {
4700 MipsTargetStreamer &TOut = getTargetStreamer();
4701 unsigned ATReg = Mips::NoRegister;
4702 unsigned DstReg = Inst.getOperand(0).getReg();
4703 unsigned SrcReg = Inst.getOperand(1).getReg();
4704 int32_t ImmValue = Inst.getOperand(2).getImm();
4706 ATReg = getATReg(IDLoc);
4710 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4713 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4714 SrcReg, ATReg, IDLoc, STI);
4716 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4721 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4722 const MCSubtargetInfo *STI) {
4723 MipsTargetStreamer &TOut = getTargetStreamer();
4724 unsigned ATReg = Mips::NoRegister;
4725 unsigned DstReg = Inst.getOperand(0).getReg();
4726 unsigned SrcReg = Inst.getOperand(1).getReg();
4727 unsigned TmpReg = Inst.getOperand(2).getReg();
4729 ATReg = getATReg(Inst.getLoc());
4733 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4734 SrcReg, TmpReg, IDLoc, STI);
4736 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4738 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4739 DstReg, DstReg, 0x1F, IDLoc, STI);
4741 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4744 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4746 MCContext & Context = TOut.getStreamer().getContext();
4747 MCSymbol * BrTarget = Context.createTempSymbol();
4749 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4751 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4752 if (AssemblerOptions.back()->isReorder())
4753 TOut.emitNop(IDLoc, STI);
4754 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4756 TOut.getStreamer().EmitLabel(BrTarget);
4758 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4763 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4764 const MCSubtargetInfo *STI) {
4765 MipsTargetStreamer &TOut = getTargetStreamer();
4766 unsigned ATReg = Mips::NoRegister;
4767 unsigned DstReg = Inst.getOperand(0).getReg();
4768 unsigned SrcReg = Inst.getOperand(1).getReg();
4769 unsigned TmpReg = Inst.getOperand(2).getReg();
4771 ATReg = getATReg(IDLoc);
4775 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4776 SrcReg, TmpReg, IDLoc, STI);
4778 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4779 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4781 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4783 MCContext & Context = TOut.getStreamer().getContext();
4784 MCSymbol * BrTarget = Context.createTempSymbol();
4786 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4788 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4789 if (AssemblerOptions.back()->isReorder())
4790 TOut.emitNop(IDLoc, STI);
4791 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4793 TOut.getStreamer().EmitLabel(BrTarget);
4799 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4800 const MCSubtargetInfo *STI) {
4801 MipsTargetStreamer &TOut = getTargetStreamer();
4802 unsigned DstReg = Inst.getOperand(0).getReg();
4803 unsigned SrcReg = Inst.getOperand(1).getReg();
4804 unsigned TmpReg = Inst.getOperand(2).getReg();
4806 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4807 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4812 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4813 // lw $<reg+1>>, offset+4($reg2)'
4814 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4815 // sw $<reg+1>>, offset+4($reg2)'
4817 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4819 const MCSubtargetInfo *STI,
4824 warnIfNoMacro(IDLoc);
4826 MipsTargetStreamer &TOut = getTargetStreamer();
4827 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4828 unsigned FirstReg = Inst.getOperand(0).getReg();
4829 unsigned SecondReg = nextReg(FirstReg);
4830 unsigned BaseReg = Inst.getOperand(1).getReg();
4834 warnIfRegIndexIsAT(FirstReg, IDLoc);
4836 assert(Inst.getOperand(2).isImm() &&
4837 "Offset for load macro is not immediate!");
4839 MCOperand &FirstOffset = Inst.getOperand(2);
4840 signed NextOffset = FirstOffset.getImm() + 4;
4841 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
4843 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
4846 // For loads, clobber the base register with the second load instead of the
4847 // first if the BaseReg == FirstReg.
4848 if (FirstReg != BaseReg || !IsLoad) {
4849 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4850 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4852 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4853 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4859 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4860 const MCSubtargetInfo *STI) {
4862 warnIfNoMacro(IDLoc);
4863 MipsTargetStreamer &TOut = getTargetStreamer();
4865 if (Inst.getOperand(1).getReg() != Mips::ZERO &&
4866 Inst.getOperand(2).getReg() != Mips::ZERO) {
4867 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4868 Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
4870 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4871 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4876 if (Inst.getOperand(1).getReg() == Mips::ZERO) {
4877 Reg = Inst.getOperand(2).getReg();
4879 Reg = Inst.getOperand(1).getReg();
4881 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
4885 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4886 const MCSubtargetInfo *STI) {
4887 warnIfNoMacro(IDLoc);
4888 MipsTargetStreamer &TOut = getTargetStreamer();
4891 int64_t Imm = Inst.getOperand(2).getImm();
4892 unsigned Reg = Inst.getOperand(1).getReg();
4895 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4896 Inst.getOperand(1).getReg(), 1, IDLoc, STI);
4900 if (Reg == Mips::ZERO) {
4901 Warning(IDLoc, "comparison is always false");
4902 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4903 Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4907 if (Imm > -0x8000 && Imm < 0) {
4909 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4914 if (!isUInt<16>(Imm)) {
4915 unsigned ATReg = getATReg(IDLoc);
4919 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4923 TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4924 Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4925 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4926 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4930 TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4932 TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4933 Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4937 // Map the DSP accumulator and control register to the corresponding gpr
4938 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
4939 // do not map the DSP registers contigously to gpr registers.
4940 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
4941 switch (Inst.getOpcode()) {
4944 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4954 llvm_unreachable("Unknown register for 'mttr' alias!");
4958 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4968 llvm_unreachable("Unknown register for 'mttr' alias!");
4972 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4982 llvm_unreachable("Unknown register for 'mttr' alias!");
4988 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
4992 // Map the floating point register operand to the corresponding register
4994 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
4995 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
4996 case Mips::F0: return Mips::ZERO;
4997 case Mips::F1: return Mips::AT;
4998 case Mips::F2: return Mips::V0;
4999 case Mips::F3: return Mips::V1;
5000 case Mips::F4: return Mips::A0;
5001 case Mips::F5: return Mips::A1;
5002 case Mips::F6: return Mips::A2;
5003 case Mips::F7: return Mips::A3;
5004 case Mips::F8: return Mips::T0;
5005 case Mips::F9: return Mips::T1;
5006 case Mips::F10: return Mips::T2;
5007 case Mips::F11: return Mips::T3;
5008 case Mips::F12: return Mips::T4;
5009 case Mips::F13: return Mips::T5;
5010 case Mips::F14: return Mips::T6;
5011 case Mips::F15: return Mips::T7;
5012 case Mips::F16: return Mips::S0;
5013 case Mips::F17: return Mips::S1;
5014 case Mips::F18: return Mips::S2;
5015 case Mips::F19: return Mips::S3;
5016 case Mips::F20: return Mips::S4;
5017 case Mips::F21: return Mips::S5;
5018 case Mips::F22: return Mips::S6;
5019 case Mips::F23: return Mips::S7;
5020 case Mips::F24: return Mips::T8;
5021 case Mips::F25: return Mips::T9;
5022 case Mips::F26: return Mips::K0;
5023 case Mips::F27: return Mips::K1;
5024 case Mips::F28: return Mips::GP;
5025 case Mips::F29: return Mips::SP;
5026 case Mips::F30: return Mips::FP;
5027 case Mips::F31: return Mips::RA;
5028 default: llvm_unreachable("Unknown register for mttc1 alias!");
5032 // Map the coprocessor operand the corresponding gpr register operand.
5033 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5034 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5035 case Mips::COP00: return Mips::ZERO;
5036 case Mips::COP01: return Mips::AT;
5037 case Mips::COP02: return Mips::V0;
5038 case Mips::COP03: return Mips::V1;
5039 case Mips::COP04: return Mips::A0;
5040 case Mips::COP05: return Mips::A1;
5041 case Mips::COP06: return Mips::A2;
5042 case Mips::COP07: return Mips::A3;
5043 case Mips::COP08: return Mips::T0;
5044 case Mips::COP09: return Mips::T1;
5045 case Mips::COP010: return Mips::T2;
5046 case Mips::COP011: return Mips::T3;
5047 case Mips::COP012: return Mips::T4;
5048 case Mips::COP013: return Mips::T5;
5049 case Mips::COP014: return Mips::T6;
5050 case Mips::COP015: return Mips::T7;
5051 case Mips::COP016: return Mips::S0;
5052 case Mips::COP017: return Mips::S1;
5053 case Mips::COP018: return Mips::S2;
5054 case Mips::COP019: return Mips::S3;
5055 case Mips::COP020: return Mips::S4;
5056 case Mips::COP021: return Mips::S5;
5057 case Mips::COP022: return Mips::S6;
5058 case Mips::COP023: return Mips::S7;
5059 case Mips::COP024: return Mips::T8;
5060 case Mips::COP025: return Mips::T9;
5061 case Mips::COP026: return Mips::K0;
5062 case Mips::COP027: return Mips::K1;
5063 case Mips::COP028: return Mips::GP;
5064 case Mips::COP029: return Mips::SP;
5065 case Mips::COP030: return Mips::FP;
5066 case Mips::COP031: return Mips::RA;
5067 default: llvm_unreachable("Unknown register for mttc0 alias!");
5071 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5072 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5073 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5074 const MCSubtargetInfo *STI) {
5075 MipsTargetStreamer &TOut = getTargetStreamer();
5080 bool IsMFTR = false;
5081 switch (Inst.getOpcode()) {
5087 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5088 sel = Inst.getOperand(2).getImm();
5094 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5106 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5114 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5121 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5128 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5132 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5135 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5136 : Inst.getOperand(0).getReg());
5138 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5144 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5145 const OperandVector &Operands) {
5146 switch (Inst.getOpcode()) {
5148 return Match_Success;
5151 if (static_cast<MipsOperand &>(*Operands[1])
5152 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5153 return Match_Success;
5154 return Match_RequiresSameSrcAndDst;
5158 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5159 switch (Inst.getOpcode()) {
5160 // As described by the MIPSR6 spec, daui must not use the zero operand for
5161 // its source operand.
5163 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5164 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5165 return Match_RequiresNoZeroRegister;
5166 return Match_Success;
5167 // As described by the Mips32r2 spec, the registers Rd and Rs for
5168 // jalr.hb must be different.
5169 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5170 // and registers Rd and Base for microMIPS lwp instruction
5172 case Mips::JALR_HB64:
5173 case Mips::JALRC_HB_MMR6:
5174 case Mips::JALRC_MMR6:
5175 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5176 return Match_RequiresDifferentSrcAndDst;
5177 return Match_Success;
5179 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5180 return Match_RequiresDifferentSrcAndDst;
5181 return Match_Success;
5183 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5184 return Match_NonZeroOperandForSync;
5185 return Match_Success;
5190 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5191 return Match_NonZeroOperandForMTCX;
5192 return Match_Success;
5193 // As described the MIPSR6 spec, the compact branches that compare registers
5195 // a) Not use the zero register.
5196 // b) Not use the same register twice.
5197 // c) rs < rt for bnec, beqc.
5198 // NB: For this case, the encoding will swap the operands as their
5199 // ordering doesn't matter. GAS performs this transformation too.
5200 // Hence, that constraint does not have to be enforced.
5202 // The compact branches that branch iff the signed addition of two registers
5203 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5204 // operand swapping. They do not have restriction of using the zero register.
5205 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5206 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5207 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5208 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5209 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5210 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5217 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5218 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5219 return Match_RequiresNoZeroRegister;
5220 return Match_Success;
5221 case Mips::BGEC: case Mips::BGEC_MMR6:
5222 case Mips::BLTC: case Mips::BLTC_MMR6:
5223 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5224 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5225 case Mips::BEQC: case Mips::BEQC_MMR6:
5226 case Mips::BNEC: case Mips::BNEC_MMR6:
5233 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5234 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5235 return Match_RequiresNoZeroRegister;
5236 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5237 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5238 return Match_RequiresNoZeroRegister;
5239 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5240 return Match_RequiresDifferentOperands;
5241 return Match_Success;
5243 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5244 "Operands must be immediates for dins!");
5245 const signed Pos = Inst.getOperand(2).getImm();
5246 const signed Size = Inst.getOperand(3).getImm();
5247 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5248 return Match_RequiresPosSizeRange0_32;
5249 return Match_Success;
5253 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5254 "Operands must be immediates for dinsm/dinsu!");
5255 const signed Pos = Inst.getOperand(2).getImm();
5256 const signed Size = Inst.getOperand(3).getImm();
5257 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5258 return Match_RequiresPosSizeRange33_64;
5259 return Match_Success;
5262 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5263 "Operands must be immediates for DEXTM!");
5264 const signed Pos = Inst.getOperand(2).getImm();
5265 const signed Size = Inst.getOperand(3).getImm();
5266 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5267 return Match_RequiresPosSizeUImm6;
5268 return Match_Success;
5272 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5273 "Operands must be immediates for dextm/dextu!");
5274 const signed Pos = Inst.getOperand(2).getImm();
5275 const signed Size = Inst.getOperand(3).getImm();
5276 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5277 return Match_RequiresPosSizeRange33_64;
5278 return Match_Success;
5280 case Mips::CRC32B: case Mips::CRC32CB:
5281 case Mips::CRC32H: case Mips::CRC32CH:
5282 case Mips::CRC32W: case Mips::CRC32CW:
5283 case Mips::CRC32D: case Mips::CRC32CD:
5284 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5285 return Match_RequiresSameSrcAndDst;
5286 return Match_Success;
5289 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5290 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5291 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5292 return Match_NoFCCRegisterForCurrentISA;
5294 return Match_Success;
5298 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5299 uint64_t ErrorInfo) {
5300 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5301 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5302 if (ErrorLoc == SMLoc())
5309 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5310 OperandVector &Operands,
5312 uint64_t &ErrorInfo,
5313 bool MatchingInlineAsm) {
5315 unsigned MatchResult =
5316 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5318 switch (MatchResult) {
5320 if (processInstruction(Inst, IDLoc, Out, STI))
5323 case Match_MissingFeature:
5324 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5326 case Match_InvalidOperand: {
5327 SMLoc ErrorLoc = IDLoc;
5328 if (ErrorInfo != ~0ULL) {
5329 if (ErrorInfo >= Operands.size())
5330 return Error(IDLoc, "too few operands for instruction");
5332 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5333 if (ErrorLoc == SMLoc())
5337 return Error(ErrorLoc, "invalid operand for instruction");
5339 case Match_NonZeroOperandForSync:
5341 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5342 case Match_NonZeroOperandForMTCX:
5343 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5344 case Match_MnemonicFail:
5345 return Error(IDLoc, "invalid instruction");
5346 case Match_RequiresDifferentSrcAndDst:
5347 return Error(IDLoc, "source and destination must be different");
5348 case Match_RequiresDifferentOperands:
5349 return Error(IDLoc, "registers must be different");
5350 case Match_RequiresNoZeroRegister:
5351 return Error(IDLoc, "invalid operand ($zero) for instruction");
5352 case Match_RequiresSameSrcAndDst:
5353 return Error(IDLoc, "source and destination must match");
5354 case Match_NoFCCRegisterForCurrentISA:
5355 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5356 "non-zero fcc register doesn't exist in current ISA level");
5358 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5360 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5361 "expected 1-bit unsigned immediate");
5363 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5364 "expected 2-bit unsigned immediate");
5366 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5367 "expected immediate in range 1 .. 4");
5369 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5370 "expected 3-bit unsigned immediate");
5372 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5373 "expected 4-bit unsigned immediate");
5375 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5376 "expected 4-bit signed immediate");
5378 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5379 "expected 5-bit unsigned immediate");
5381 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5382 "expected 5-bit signed immediate");
5384 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5385 "expected immediate in range 1 .. 32");
5386 case Match_UImm5_32:
5387 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5388 "expected immediate in range 32 .. 63");
5389 case Match_UImm5_33:
5390 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5391 "expected immediate in range 33 .. 64");
5392 case Match_UImm5_0_Report_UImm6:
5393 // This is used on UImm5 operands that have a corresponding UImm5_32
5394 // operand to avoid confusing the user.
5395 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5396 "expected 6-bit unsigned immediate");
5397 case Match_UImm5_Lsl2:
5398 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5399 "expected both 7-bit unsigned immediate and multiple of 4");
5400 case Match_UImmRange2_64:
5401 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5402 "expected immediate in range 2 .. 64");
5404 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5405 "expected 6-bit unsigned immediate");
5406 case Match_UImm6_Lsl2:
5407 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5408 "expected both 8-bit unsigned immediate and multiple of 4");
5410 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5411 "expected 6-bit signed immediate");
5413 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5414 "expected 7-bit unsigned immediate");
5415 case Match_UImm7_N1:
5416 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5417 "expected immediate in range -1 .. 126");
5418 case Match_SImm7_Lsl2:
5419 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5420 "expected both 9-bit signed immediate and multiple of 4");
5422 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5423 "expected 8-bit unsigned immediate");
5424 case Match_UImm10_0:
5425 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5426 "expected 10-bit unsigned immediate");
5427 case Match_SImm10_0:
5428 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5429 "expected 10-bit signed immediate");
5430 case Match_SImm11_0:
5431 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5432 "expected 11-bit signed immediate");
5434 case Match_UImm16_Relaxed:
5435 case Match_UImm16_AltRelaxed:
5436 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5437 "expected 16-bit unsigned immediate");
5439 case Match_SImm16_Relaxed:
5440 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5441 "expected 16-bit signed immediate");
5442 case Match_SImm19_Lsl2:
5443 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5444 "expected both 19-bit signed immediate and multiple of 4");
5445 case Match_UImm20_0:
5446 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5447 "expected 20-bit unsigned immediate");
5448 case Match_UImm26_0:
5449 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5450 "expected 26-bit unsigned immediate");
5452 case Match_SImm32_Relaxed:
5453 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5454 "expected 32-bit signed immediate");
5455 case Match_UImm32_Coerced:
5456 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5457 "expected 32-bit immediate");
5458 case Match_MemSImm9:
5459 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5460 "expected memory with 9-bit signed offset");
5461 case Match_MemSImm10:
5462 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5463 "expected memory with 10-bit signed offset");
5464 case Match_MemSImm10Lsl1:
5465 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5466 "expected memory with 11-bit signed offset and multiple of 2");
5467 case Match_MemSImm10Lsl2:
5468 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5469 "expected memory with 12-bit signed offset and multiple of 4");
5470 case Match_MemSImm10Lsl3:
5471 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5472 "expected memory with 13-bit signed offset and multiple of 8");
5473 case Match_MemSImm11:
5474 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5475 "expected memory with 11-bit signed offset");
5476 case Match_MemSImm12:
5477 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5478 "expected memory with 12-bit signed offset");
5479 case Match_MemSImm16:
5480 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5481 "expected memory with 16-bit signed offset");
5482 case Match_MemSImmPtr:
5483 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5484 "expected memory with 32-bit signed offset");
5485 case Match_RequiresPosSizeRange0_32: {
5486 SMLoc ErrorStart = Operands[3]->getStartLoc();
5487 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5488 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5489 SMRange(ErrorStart, ErrorEnd));
5491 case Match_RequiresPosSizeUImm6: {
5492 SMLoc ErrorStart = Operands[3]->getStartLoc();
5493 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5494 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5495 SMRange(ErrorStart, ErrorEnd));
5497 case Match_RequiresPosSizeRange33_64: {
5498 SMLoc ErrorStart = Operands[3]->getStartLoc();
5499 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5500 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5501 SMRange(ErrorStart, ErrorEnd));
5505 llvm_unreachable("Implement any new match types added!");
5508 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5509 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5510 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5511 ") without \".set noat\"");
5514 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5515 if (!AssemblerOptions.back()->isMacro())
5516 Warning(Loc, "macro instruction expanded into multiple instructions");
5519 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5520 const OperandVector &Operands) {
5522 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
5523 "Unexpected instruction!");
5524 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5525 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5526 Inst.addOperand(MCOperand::createReg(NextReg));
5527 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5531 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5532 SMRange Range, bool ShowColors) {
5533 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5534 Range, SMFixIt(Range, FixMsg),
5538 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5541 CC = StringSwitch<unsigned>(Name)
5543 .Cases("at", "AT", 1)
5577 if (!(isABI_N32() || isABI_N64()))
5580 if (12 <= CC && CC <= 15) {
5581 // Name is one of t4-t7
5582 AsmToken RegTok = getLexer().peekTok();
5583 SMRange RegRange = RegTok.getLocRange();
5585 StringRef FixedName = StringSwitch<StringRef>(Name)
5591 assert(FixedName != "" && "Register name is not one of t4-t7.");
5593 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5594 "Did you mean $" + FixedName + "?", RegRange);
5597 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5598 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5599 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5600 if (8 <= CC && CC <= 11)
5604 CC = StringSwitch<unsigned>(Name)
5616 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5619 CC = StringSwitch<unsigned>(Name)
5620 .Case("hwr_cpunum", 0)
5621 .Case("hwr_synci_step", 1)
5623 .Case("hwr_ccres", 3)
5624 .Case("hwr_ulr", 29)
5630 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5631 if (Name[0] == 'f') {
5632 StringRef NumString = Name.substr(1);
5634 if (NumString.getAsInteger(10, IntVal))
5635 return -1; // This is not an integer.
5636 if (IntVal > 31) // Maximum index for fpu register.
5643 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5644 if (Name.startswith("fcc")) {
5645 StringRef NumString = Name.substr(3);
5647 if (NumString.getAsInteger(10, IntVal))
5648 return -1; // This is not an integer.
5649 if (IntVal > 7) // There are only 8 fcc registers.
5656 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5657 if (Name.startswith("ac")) {
5658 StringRef NumString = Name.substr(2);
5660 if (NumString.getAsInteger(10, IntVal))
5661 return -1; // This is not an integer.
5662 if (IntVal > 3) // There are only 3 acc registers.
5669 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5672 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5681 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5684 CC = StringSwitch<unsigned>(Name)
5687 .Case("msaaccess", 2)
5689 .Case("msamodify", 4)
5690 .Case("msarequest", 5)
5692 .Case("msaunmap", 7)
5698 bool MipsAsmParser::canUseATReg() {
5699 return AssemblerOptions.back()->getATRegIndex() != 0;
5702 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5703 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5705 reportParseError(Loc,
5706 "pseudo-instruction requires $at, which is not available");
5709 unsigned AT = getReg(
5710 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5714 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5715 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5718 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5719 MCAsmParser &Parser = getParser();
5720 LLVM_DEBUG(dbgs() << "parseOperand\n");
5722 // Check if the current operand has a custom associated parser, if so, try to
5723 // custom parse the operand, or fallback to the general approach.
5724 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5725 if (ResTy == MatchOperand_Success)
5727 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5728 // there was a match, but an error occurred, in which case, just return that
5729 // the operand parsing failed.
5730 if (ResTy == MatchOperand_ParseFail)
5733 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
5735 switch (getLexer().getKind()) {
5736 case AsmToken::Dollar: {
5737 // Parse the register.
5738 SMLoc S = Parser.getTok().getLoc();
5740 // Almost all registers have been parsed by custom parsers. There is only
5741 // one exception to this. $zero (and it's alias $0) will reach this point
5742 // for div, divu, and similar instructions because it is not an operand
5743 // to the instruction definition but an explicit register. Special case
5744 // this situation for now.
5745 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5748 // Maybe it is a symbol reference.
5749 StringRef Identifier;
5750 if (Parser.parseIdentifier(Identifier))
5753 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5754 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5755 // Otherwise create a symbol reference.
5757 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5759 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5763 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
5766 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5767 if (getParser().parseExpression(Expr))
5770 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5772 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5775 } // switch(getLexer().getKind())
5779 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5780 switch (Expr->getKind()) {
5781 case MCExpr::Constant:
5783 case MCExpr::SymbolRef:
5784 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
5785 case MCExpr::Binary: {
5786 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
5787 if (!isEvaluated(BE->getLHS()))
5789 return isEvaluated(BE->getRHS());
5792 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5793 case MCExpr::Target:
5799 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
5801 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
5802 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
5803 if (ResTy == MatchOperand_Success) {
5804 assert(Operands.size() == 1);
5805 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
5806 StartLoc = Operand.getStartLoc();
5807 EndLoc = Operand.getEndLoc();
5809 // AFAIK, we only support numeric registers and named GPR's in CFI
5811 // Don't worry about eating tokens before failing. Using an unrecognised
5812 // register is a parse error.
5813 if (Operand.isGPRAsmReg()) {
5814 // Resolve to GPR32 or GPR64 appropriately.
5815 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5818 return (RegNo == (unsigned)-1);
5821 assert(Operands.size() == 0);
5822 return (RegNo == (unsigned)-1);
5825 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
5829 return getParser().parseParenExprOfDepth(0, Res, S);
5830 return getParser().parseExpression(Res);
5833 OperandMatchResultTy
5834 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
5835 MCAsmParser &Parser = getParser();
5836 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
5837 const MCExpr *IdVal = nullptr;
5839 bool isParenExpr = false;
5840 OperandMatchResultTy Res = MatchOperand_NoMatch;
5841 // First operand is the offset.
5842 S = Parser.getTok().getLoc();
5844 if (getLexer().getKind() == AsmToken::LParen) {
5849 if (getLexer().getKind() != AsmToken::Dollar) {
5850 if (parseMemOffset(IdVal, isParenExpr))
5851 return MatchOperand_ParseFail;
5853 const AsmToken &Tok = Parser.getTok(); // Get the next token.
5854 if (Tok.isNot(AsmToken::LParen)) {
5855 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
5856 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
5858 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5859 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
5860 return MatchOperand_Success;
5862 if (Tok.is(AsmToken::EndOfStatement)) {
5864 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5866 // Zero register assumed, add a memory operand with ZERO as its base.
5867 // "Base" will be managed by k_Memory.
5868 auto Base = MipsOperand::createGPRReg(
5869 0, "0", getContext().getRegisterInfo(), S, E, *this);
5871 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
5872 return MatchOperand_Success;
5874 MCBinaryExpr::Opcode Opcode;
5875 // GAS and LLVM treat comparison operators different. GAS will generate -1
5876 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
5877 // highly unlikely to be found in a memory offset expression, we don't
5879 switch (Tok.getKind()) {
5880 case AsmToken::Plus:
5881 Opcode = MCBinaryExpr::Add;
5884 case AsmToken::Minus:
5885 Opcode = MCBinaryExpr::Sub;
5888 case AsmToken::Star:
5889 Opcode = MCBinaryExpr::Mul;
5892 case AsmToken::Pipe:
5893 Opcode = MCBinaryExpr::Or;
5897 Opcode = MCBinaryExpr::And;
5900 case AsmToken::LessLess:
5901 Opcode = MCBinaryExpr::Shl;
5904 case AsmToken::GreaterGreater:
5905 Opcode = MCBinaryExpr::LShr;
5908 case AsmToken::Caret:
5909 Opcode = MCBinaryExpr::Xor;
5912 case AsmToken::Slash:
5913 Opcode = MCBinaryExpr::Div;
5916 case AsmToken::Percent:
5917 Opcode = MCBinaryExpr::Mod;
5921 Error(Parser.getTok().getLoc(), "'(' or expression expected");
5922 return MatchOperand_ParseFail;
5924 const MCExpr * NextExpr;
5925 if (getParser().parseExpression(NextExpr))
5926 return MatchOperand_ParseFail;
5927 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
5930 Parser.Lex(); // Eat the '(' token.
5933 Res = parseAnyRegister(Operands);
5934 if (Res != MatchOperand_Success)
5937 if (Parser.getTok().isNot(AsmToken::RParen)) {
5938 Error(Parser.getTok().getLoc(), "')' expected");
5939 return MatchOperand_ParseFail;
5942 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5944 Parser.Lex(); // Eat the ')' token.
5947 IdVal = MCConstantExpr::create(0, getContext());
5949 // Replace the register operand with the memory operand.
5950 std::unique_ptr<MipsOperand> op(
5951 static_cast<MipsOperand *>(Operands.back().release()));
5952 // Remove the register from the operands.
5953 // "op" will be managed by k_Memory.
5954 Operands.pop_back();
5955 // Add the memory operand.
5956 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5958 if (IdVal->evaluateAsAbsolute(Imm))
5959 IdVal = MCConstantExpr::create(Imm, getContext());
5960 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
5961 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
5965 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
5966 return MatchOperand_Success;
5969 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
5970 MCAsmParser &Parser = getParser();
5971 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
5975 SMLoc S = Parser.getTok().getLoc();
5976 if (Sym->isVariable()) {
5977 const MCExpr *Expr = Sym->getVariableValue();
5978 if (Expr->getKind() == MCExpr::SymbolRef) {
5979 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5980 StringRef DefSymbol = Ref->getSymbol().getName();
5981 if (DefSymbol.startswith("$")) {
5982 OperandMatchResultTy ResTy =
5983 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
5984 if (ResTy == MatchOperand_Success) {
5988 if (ResTy == MatchOperand_ParseFail)
5989 llvm_unreachable("Should never ParseFail");
5992 } else if (Sym->isUnset()) {
5993 // If symbol is unset, it might be created in the `parseSetAssignment`
5994 // routine as an alias for a numeric register name.
5995 // Lookup in the aliases list.
5996 auto Entry = RegisterSets.find(Sym->getName());
5997 if (Entry != RegisterSets.end()) {
5998 OperandMatchResultTy ResTy =
5999 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6000 if (ResTy == MatchOperand_Success) {
6010 OperandMatchResultTy
6011 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6012 StringRef Identifier,
6014 int Index = matchCPURegisterName(Identifier);
6016 Operands.push_back(MipsOperand::createGPRReg(
6017 Index, Identifier, getContext().getRegisterInfo(), S,
6018 getLexer().getLoc(), *this));
6019 return MatchOperand_Success;
6022 Index = matchHWRegsRegisterName(Identifier);
6024 Operands.push_back(MipsOperand::createHWRegsReg(
6025 Index, Identifier, getContext().getRegisterInfo(), S,
6026 getLexer().getLoc(), *this));
6027 return MatchOperand_Success;
6030 Index = matchFPURegisterName(Identifier);
6032 Operands.push_back(MipsOperand::createFGRReg(
6033 Index, Identifier, getContext().getRegisterInfo(), S,
6034 getLexer().getLoc(), *this));
6035 return MatchOperand_Success;
6038 Index = matchFCCRegisterName(Identifier);
6040 Operands.push_back(MipsOperand::createFCCReg(
6041 Index, Identifier, getContext().getRegisterInfo(), S,
6042 getLexer().getLoc(), *this));
6043 return MatchOperand_Success;
6046 Index = matchACRegisterName(Identifier);
6048 Operands.push_back(MipsOperand::createACCReg(
6049 Index, Identifier, getContext().getRegisterInfo(), S,
6050 getLexer().getLoc(), *this));
6051 return MatchOperand_Success;
6054 Index = matchMSA128RegisterName(Identifier);
6056 Operands.push_back(MipsOperand::createMSA128Reg(
6057 Index, Identifier, getContext().getRegisterInfo(), S,
6058 getLexer().getLoc(), *this));
6059 return MatchOperand_Success;
6062 Index = matchMSA128CtrlRegisterName(Identifier);
6064 Operands.push_back(MipsOperand::createMSACtrlReg(
6065 Index, Identifier, getContext().getRegisterInfo(), S,
6066 getLexer().getLoc(), *this));
6067 return MatchOperand_Success;
6070 return MatchOperand_NoMatch;
6073 OperandMatchResultTy
6074 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6075 const AsmToken &Token, SMLoc S) {
6076 if (Token.is(AsmToken::Identifier)) {
6077 LLVM_DEBUG(dbgs() << ".. identifier\n");
6078 StringRef Identifier = Token.getIdentifier();
6079 OperandMatchResultTy ResTy =
6080 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6082 } else if (Token.is(AsmToken::Integer)) {
6083 LLVM_DEBUG(dbgs() << ".. integer\n");
6084 int64_t RegNum = Token.getIntVal();
6085 if (RegNum < 0 || RegNum > 31) {
6086 // Show the error, but treat invalid register
6087 // number as a normal one to continue parsing
6088 // and catch other possible errors.
6089 Error(getLexer().getLoc(), "invalid register number");
6091 Operands.push_back(MipsOperand::createNumericReg(
6092 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6093 Token.getLoc(), *this));
6094 return MatchOperand_Success;
6097 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6099 return MatchOperand_NoMatch;
6102 OperandMatchResultTy
6103 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6104 auto Token = getLexer().peekTok(false);
6105 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6108 OperandMatchResultTy
6109 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6110 MCAsmParser &Parser = getParser();
6111 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6113 auto Token = Parser.getTok();
6115 SMLoc S = Token.getLoc();
6117 if (Token.isNot(AsmToken::Dollar)) {
6118 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6119 if (Token.is(AsmToken::Identifier)) {
6120 if (searchSymbolAlias(Operands))
6121 return MatchOperand_Success;
6123 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6124 return MatchOperand_NoMatch;
6126 LLVM_DEBUG(dbgs() << ".. $\n");
6128 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6129 if (ResTy == MatchOperand_Success) {
6131 Parser.Lex(); // identifier
6136 OperandMatchResultTy
6137 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6138 MCAsmParser &Parser = getParser();
6139 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6141 SMLoc S = getLexer().getLoc();
6143 // Registers are a valid target and have priority over symbols.
6144 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6145 if (ResTy != MatchOperand_NoMatch)
6148 // Integers and expressions are acceptable
6149 const MCExpr *Expr = nullptr;
6150 if (Parser.parseExpression(Expr)) {
6151 // We have no way of knowing if a symbol was consumed so we must ParseFail
6152 return MatchOperand_ParseFail;
6155 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6156 return MatchOperand_Success;
6159 OperandMatchResultTy
6160 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6161 MCAsmParser &Parser = getParser();
6162 const MCExpr *IdVal;
6163 // If the first token is '$' we may have register operand. We have to reject
6164 // cases where it is not a register. Complicating the matter is that
6165 // register names are not reserved across all ABIs.
6166 // Peek past the dollar to see if it's a register name for this ABI.
6167 SMLoc S = Parser.getTok().getLoc();
6168 if (Parser.getTok().is(AsmToken::Dollar)) {
6169 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6170 ? MatchOperand_ParseFail
6171 : MatchOperand_NoMatch;
6173 if (getParser().parseExpression(IdVal))
6174 return MatchOperand_ParseFail;
6175 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6177 return MatchOperand_NoMatch;
6178 int64_t Val = MCE->getValue();
6179 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6180 Operands.push_back(MipsOperand::CreateImm(
6181 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6182 return MatchOperand_Success;
6185 OperandMatchResultTy
6186 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6187 MCAsmParser &Parser = getParser();
6188 SmallVector<unsigned, 10> Regs;
6190 unsigned PrevReg = Mips::NoRegister;
6191 bool RegRange = false;
6192 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6194 if (Parser.getTok().isNot(AsmToken::Dollar))
6195 return MatchOperand_ParseFail;
6197 SMLoc S = Parser.getTok().getLoc();
6198 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6199 SMLoc E = getLexer().getLoc();
6200 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6201 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6203 // Remove last register operand because registers from register range
6204 // should be inserted first.
6205 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6206 (!isGP64bit() && RegNo == Mips::RA)) {
6207 Regs.push_back(RegNo);
6209 unsigned TmpReg = PrevReg + 1;
6210 while (TmpReg <= RegNo) {
6211 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6212 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6214 Error(E, "invalid register operand");
6215 return MatchOperand_ParseFail;
6219 Regs.push_back(TmpReg++);
6225 if ((PrevReg == Mips::NoRegister) &&
6226 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6227 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6228 Error(E, "$16 or $31 expected");
6229 return MatchOperand_ParseFail;
6230 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6231 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6233 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6234 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6236 Error(E, "invalid register operand");
6237 return MatchOperand_ParseFail;
6238 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6239 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6240 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6242 Error(E, "consecutive register numbers expected");
6243 return MatchOperand_ParseFail;
6246 Regs.push_back(RegNo);
6249 if (Parser.getTok().is(AsmToken::Minus))
6252 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6253 !Parser.getTok().isNot(AsmToken::Comma)) {
6254 Error(E, "',' or '-' expected");
6255 return MatchOperand_ParseFail;
6258 Lex(); // Consume comma or minus
6259 if (Parser.getTok().isNot(AsmToken::Dollar))
6265 SMLoc E = Parser.getTok().getLoc();
6266 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6267 parseMemOperand(Operands);
6268 return MatchOperand_Success;
6271 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6273 /// ::= '(', register, ')'
6274 /// handle it before we iterate so we don't get tripped up by the lack of
6276 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6277 MCAsmParser &Parser = getParser();
6278 if (getLexer().is(AsmToken::LParen)) {
6280 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6282 if (parseOperand(Operands, Name)) {
6283 SMLoc Loc = getLexer().getLoc();
6284 return Error(Loc, "unexpected token in argument list");
6286 if (Parser.getTok().isNot(AsmToken::RParen)) {
6287 SMLoc Loc = getLexer().getLoc();
6288 return Error(Loc, "unexpected token, expected ')'");
6291 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6297 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6298 /// either one of these.
6299 /// ::= '[', register, ']'
6300 /// ::= '[', integer, ']'
6301 /// handle it before we iterate so we don't get tripped up by the lack of
6303 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6304 OperandVector &Operands) {
6305 MCAsmParser &Parser = getParser();
6306 if (getLexer().is(AsmToken::LBrac)) {
6308 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6310 if (parseOperand(Operands, Name)) {
6311 SMLoc Loc = getLexer().getLoc();
6312 return Error(Loc, "unexpected token in argument list");
6314 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6315 SMLoc Loc = getLexer().getLoc();
6316 return Error(Loc, "unexpected token, expected ']'");
6319 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6325 static std::string MipsMnemonicSpellCheck(StringRef S, uint64_t FBS,
6326 unsigned VariantID = 0);
6328 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6329 SMLoc NameLoc, OperandVector &Operands) {
6330 MCAsmParser &Parser = getParser();
6331 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6333 // We have reached first instruction, module directive are now forbidden.
6334 getTargetStreamer().forbidModuleDirective();
6336 // Check if we have valid mnemonic
6337 if (!mnemonicIsValid(Name, 0)) {
6338 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6339 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6340 return Error(NameLoc, "unknown instruction" + Suggestion);
6342 // First operand in MCInst is instruction mnemonic.
6343 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6345 // Read the remaining operands.
6346 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6347 // Read the first operand.
6348 if (parseOperand(Operands, Name)) {
6349 SMLoc Loc = getLexer().getLoc();
6350 return Error(Loc, "unexpected token in argument list");
6352 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6354 // AFAIK, parenthesis suffixes are never on the first operand
6356 while (getLexer().is(AsmToken::Comma)) {
6357 Parser.Lex(); // Eat the comma.
6358 // Parse and remember the operand.
6359 if (parseOperand(Operands, Name)) {
6360 SMLoc Loc = getLexer().getLoc();
6361 return Error(Loc, "unexpected token in argument list");
6363 // Parse bracket and parenthesis suffixes before we iterate
6364 if (getLexer().is(AsmToken::LBrac)) {
6365 if (parseBracketSuffix(Name, Operands))
6367 } else if (getLexer().is(AsmToken::LParen) &&
6368 parseParenSuffix(Name, Operands))
6372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6373 SMLoc Loc = getLexer().getLoc();
6374 return Error(Loc, "unexpected token in argument list");
6376 Parser.Lex(); // Consume the EndOfStatement.
6380 // FIXME: Given that these have the same name, these should both be
6381 // consistent on affecting the Parser.
6382 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6383 SMLoc Loc = getLexer().getLoc();
6384 return Error(Loc, ErrorMsg);
6387 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6388 return Error(Loc, ErrorMsg);
6391 bool MipsAsmParser::parseSetNoAtDirective() {
6392 MCAsmParser &Parser = getParser();
6393 // Line should look like: ".set noat".
6395 // Set the $at register to $0.
6396 AssemblerOptions.back()->setATRegIndex(0);
6398 Parser.Lex(); // Eat "noat".
6400 // If this is not the end of the statement, report an error.
6401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6402 reportParseError("unexpected token, expected end of statement");
6406 getTargetStreamer().emitDirectiveSetNoAt();
6407 Parser.Lex(); // Consume the EndOfStatement.
6411 bool MipsAsmParser::parseSetAtDirective() {
6412 // Line can be: ".set at", which sets $at to $1
6413 // or ".set at=$reg", which sets $at to $reg.
6414 MCAsmParser &Parser = getParser();
6415 Parser.Lex(); // Eat "at".
6417 if (getLexer().is(AsmToken::EndOfStatement)) {
6418 // No register was specified, so we set $at to $1.
6419 AssemblerOptions.back()->setATRegIndex(1);
6421 getTargetStreamer().emitDirectiveSetAt();
6422 Parser.Lex(); // Consume the EndOfStatement.
6426 if (getLexer().isNot(AsmToken::Equal)) {
6427 reportParseError("unexpected token, expected equals sign");
6430 Parser.Lex(); // Eat "=".
6432 if (getLexer().isNot(AsmToken::Dollar)) {
6433 if (getLexer().is(AsmToken::EndOfStatement)) {
6434 reportParseError("no register specified");
6437 reportParseError("unexpected token, expected dollar sign '$'");
6441 Parser.Lex(); // Eat "$".
6443 // Find out what "reg" is.
6445 const AsmToken &Reg = Parser.getTok();
6446 if (Reg.is(AsmToken::Identifier)) {
6447 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6448 } else if (Reg.is(AsmToken::Integer)) {
6449 AtRegNo = Reg.getIntVal();
6451 reportParseError("unexpected token, expected identifier or integer");
6455 // Check if $reg is a valid register. If it is, set $at to $reg.
6456 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6457 reportParseError("invalid register");
6460 Parser.Lex(); // Eat "reg".
6462 // If this is not the end of the statement, report an error.
6463 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6464 reportParseError("unexpected token, expected end of statement");
6468 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6470 Parser.Lex(); // Consume the EndOfStatement.
6474 bool MipsAsmParser::parseSetReorderDirective() {
6475 MCAsmParser &Parser = getParser();
6477 // If this is not the end of the statement, report an error.
6478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6479 reportParseError("unexpected token, expected end of statement");
6482 AssemblerOptions.back()->setReorder();
6483 getTargetStreamer().emitDirectiveSetReorder();
6484 Parser.Lex(); // Consume the EndOfStatement.
6488 bool MipsAsmParser::parseSetNoReorderDirective() {
6489 MCAsmParser &Parser = getParser();
6491 // If this is not the end of the statement, report an error.
6492 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6493 reportParseError("unexpected token, expected end of statement");
6496 AssemblerOptions.back()->setNoReorder();
6497 getTargetStreamer().emitDirectiveSetNoReorder();
6498 Parser.Lex(); // Consume the EndOfStatement.
6502 bool MipsAsmParser::parseSetMacroDirective() {
6503 MCAsmParser &Parser = getParser();
6505 // If this is not the end of the statement, report an error.
6506 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6507 reportParseError("unexpected token, expected end of statement");
6510 AssemblerOptions.back()->setMacro();
6511 getTargetStreamer().emitDirectiveSetMacro();
6512 Parser.Lex(); // Consume the EndOfStatement.
6516 bool MipsAsmParser::parseSetNoMacroDirective() {
6517 MCAsmParser &Parser = getParser();
6519 // If this is not the end of the statement, report an error.
6520 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6521 reportParseError("unexpected token, expected end of statement");
6524 if (AssemblerOptions.back()->isReorder()) {
6525 reportParseError("`noreorder' must be set before `nomacro'");
6528 AssemblerOptions.back()->setNoMacro();
6529 getTargetStreamer().emitDirectiveSetNoMacro();
6530 Parser.Lex(); // Consume the EndOfStatement.
6534 bool MipsAsmParser::parseSetMsaDirective() {
6535 MCAsmParser &Parser = getParser();
6538 // If this is not the end of the statement, report an error.
6539 if (getLexer().isNot(AsmToken::EndOfStatement))
6540 return reportParseError("unexpected token, expected end of statement");
6542 setFeatureBits(Mips::FeatureMSA, "msa");
6543 getTargetStreamer().emitDirectiveSetMsa();
6547 bool MipsAsmParser::parseSetNoMsaDirective() {
6548 MCAsmParser &Parser = getParser();
6551 // If this is not the end of the statement, report an error.
6552 if (getLexer().isNot(AsmToken::EndOfStatement))
6553 return reportParseError("unexpected token, expected end of statement");
6555 clearFeatureBits(Mips::FeatureMSA, "msa");
6556 getTargetStreamer().emitDirectiveSetNoMsa();
6560 bool MipsAsmParser::parseSetNoDspDirective() {
6561 MCAsmParser &Parser = getParser();
6562 Parser.Lex(); // Eat "nodsp".
6564 // If this is not the end of the statement, report an error.
6565 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6566 reportParseError("unexpected token, expected end of statement");
6570 clearFeatureBits(Mips::FeatureDSP, "dsp");
6571 getTargetStreamer().emitDirectiveSetNoDsp();
6575 bool MipsAsmParser::parseSetMips16Directive() {
6576 MCAsmParser &Parser = getParser();
6577 Parser.Lex(); // Eat "mips16".
6579 // If this is not the end of the statement, report an error.
6580 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6581 reportParseError("unexpected token, expected end of statement");
6585 setFeatureBits(Mips::FeatureMips16, "mips16");
6586 getTargetStreamer().emitDirectiveSetMips16();
6587 Parser.Lex(); // Consume the EndOfStatement.
6591 bool MipsAsmParser::parseSetNoMips16Directive() {
6592 MCAsmParser &Parser = getParser();
6593 Parser.Lex(); // Eat "nomips16".
6595 // If this is not the end of the statement, report an error.
6596 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6597 reportParseError("unexpected token, expected end of statement");
6601 clearFeatureBits(Mips::FeatureMips16, "mips16");
6602 getTargetStreamer().emitDirectiveSetNoMips16();
6603 Parser.Lex(); // Consume the EndOfStatement.
6607 bool MipsAsmParser::parseSetFpDirective() {
6608 MCAsmParser &Parser = getParser();
6609 MipsABIFlagsSection::FpABIKind FpAbiVal;
6610 // Line can be: .set fp=32
6613 Parser.Lex(); // Eat fp token
6614 AsmToken Tok = Parser.getTok();
6615 if (Tok.isNot(AsmToken::Equal)) {
6616 reportParseError("unexpected token, expected equals sign '='");
6619 Parser.Lex(); // Eat '=' token.
6620 Tok = Parser.getTok();
6622 if (!parseFpABIValue(FpAbiVal, ".set"))
6625 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6626 reportParseError("unexpected token, expected end of statement");
6629 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6630 Parser.Lex(); // Consume the EndOfStatement.
6634 bool MipsAsmParser::parseSetOddSPRegDirective() {
6635 MCAsmParser &Parser = getParser();
6637 Parser.Lex(); // Eat "oddspreg".
6638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6639 reportParseError("unexpected token, expected end of statement");
6643 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6644 getTargetStreamer().emitDirectiveSetOddSPReg();
6648 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6649 MCAsmParser &Parser = getParser();
6651 Parser.Lex(); // Eat "nooddspreg".
6652 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6653 reportParseError("unexpected token, expected end of statement");
6657 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6658 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6662 bool MipsAsmParser::parseSetMtDirective() {
6663 MCAsmParser &Parser = getParser();
6664 Parser.Lex(); // Eat "mt".
6666 // If this is not the end of the statement, report an error.
6667 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6668 reportParseError("unexpected token, expected end of statement");
6672 setFeatureBits(Mips::FeatureMT, "mt");
6673 getTargetStreamer().emitDirectiveSetMt();
6674 Parser.Lex(); // Consume the EndOfStatement.
6678 bool MipsAsmParser::parseSetNoMtDirective() {
6679 MCAsmParser &Parser = getParser();
6680 Parser.Lex(); // Eat "nomt".
6682 // If this is not the end of the statement, report an error.
6683 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6684 reportParseError("unexpected token, expected end of statement");
6688 clearFeatureBits(Mips::FeatureMT, "mt");
6690 getTargetStreamer().emitDirectiveSetNoMt();
6691 Parser.Lex(); // Consume the EndOfStatement.
6695 bool MipsAsmParser::parseSetNoCRCDirective() {
6696 MCAsmParser &Parser = getParser();
6697 Parser.Lex(); // Eat "nocrc".
6699 // If this is not the end of the statement, report an error.
6700 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6701 reportParseError("unexpected token, expected end of statement");
6705 clearFeatureBits(Mips::FeatureCRC, "crc");
6707 getTargetStreamer().emitDirectiveSetNoCRC();
6708 Parser.Lex(); // Consume the EndOfStatement.
6712 bool MipsAsmParser::parseSetNoVirtDirective() {
6713 MCAsmParser &Parser = getParser();
6714 Parser.Lex(); // Eat "novirt".
6716 // If this is not the end of the statement, report an error.
6717 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6718 reportParseError("unexpected token, expected end of statement");
6722 clearFeatureBits(Mips::FeatureVirt, "virt");
6724 getTargetStreamer().emitDirectiveSetNoVirt();
6725 Parser.Lex(); // Consume the EndOfStatement.
6729 bool MipsAsmParser::parseSetNoGINVDirective() {
6730 MCAsmParser &Parser = getParser();
6731 Parser.Lex(); // Eat "noginv".
6733 // If this is not the end of the statement, report an error.
6734 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6735 reportParseError("unexpected token, expected end of statement");
6739 clearFeatureBits(Mips::FeatureGINV, "ginv");
6741 getTargetStreamer().emitDirectiveSetNoGINV();
6742 Parser.Lex(); // Consume the EndOfStatement.
6746 bool MipsAsmParser::parseSetPopDirective() {
6747 MCAsmParser &Parser = getParser();
6748 SMLoc Loc = getLexer().getLoc();
6751 if (getLexer().isNot(AsmToken::EndOfStatement))
6752 return reportParseError("unexpected token, expected end of statement");
6754 // Always keep an element on the options "stack" to prevent the user
6755 // from changing the initial options. This is how we remember them.
6756 if (AssemblerOptions.size() == 2)
6757 return reportParseError(Loc, ".set pop with no .set push");
6759 MCSubtargetInfo &STI = copySTI();
6760 AssemblerOptions.pop_back();
6761 setAvailableFeatures(
6762 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6763 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6765 getTargetStreamer().emitDirectiveSetPop();
6769 bool MipsAsmParser::parseSetPushDirective() {
6770 MCAsmParser &Parser = getParser();
6772 if (getLexer().isNot(AsmToken::EndOfStatement))
6773 return reportParseError("unexpected token, expected end of statement");
6775 // Create a copy of the current assembler options environment and push it.
6776 AssemblerOptions.push_back(
6777 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6779 getTargetStreamer().emitDirectiveSetPush();
6783 bool MipsAsmParser::parseSetSoftFloatDirective() {
6784 MCAsmParser &Parser = getParser();
6786 if (getLexer().isNot(AsmToken::EndOfStatement))
6787 return reportParseError("unexpected token, expected end of statement");
6789 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6790 getTargetStreamer().emitDirectiveSetSoftFloat();
6794 bool MipsAsmParser::parseSetHardFloatDirective() {
6795 MCAsmParser &Parser = getParser();
6797 if (getLexer().isNot(AsmToken::EndOfStatement))
6798 return reportParseError("unexpected token, expected end of statement");
6800 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6801 getTargetStreamer().emitDirectiveSetHardFloat();
6805 bool MipsAsmParser::parseSetAssignment() {
6807 const MCExpr *Value;
6808 MCAsmParser &Parser = getParser();
6810 if (Parser.parseIdentifier(Name))
6811 return reportParseError("expected identifier after .set");
6813 if (getLexer().isNot(AsmToken::Comma))
6814 return reportParseError("unexpected token, expected comma");
6817 if (getLexer().is(AsmToken::Dollar) &&
6818 getLexer().peekTok().is(AsmToken::Integer)) {
6819 // Parse assignment of a numeric register:
6821 Parser.Lex(); // Eat $.
6822 RegisterSets[Name] = Parser.getTok();
6823 Parser.Lex(); // Eat identifier.
6824 getContext().getOrCreateSymbol(Name);
6825 } else if (!Parser.parseExpression(Value)) {
6826 // Parse assignment of an expression including
6827 // symbolic registers:
6828 // .set $tmp, $BB0-$BB1
6830 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6831 Sym->setVariableValue(Value);
6833 return reportParseError("expected valid expression after comma");
6839 bool MipsAsmParser::parseSetMips0Directive() {
6840 MCAsmParser &Parser = getParser();
6842 if (getLexer().isNot(AsmToken::EndOfStatement))
6843 return reportParseError("unexpected token, expected end of statement");
6845 // Reset assembler options to their initial values.
6846 MCSubtargetInfo &STI = copySTI();
6847 setAvailableFeatures(
6848 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
6849 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
6850 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
6852 getTargetStreamer().emitDirectiveSetMips0();
6856 bool MipsAsmParser::parseSetArchDirective() {
6857 MCAsmParser &Parser = getParser();
6859 if (getLexer().isNot(AsmToken::Equal))
6860 return reportParseError("unexpected token, expected equals sign");
6864 if (Parser.parseIdentifier(Arch))
6865 return reportParseError("expected arch identifier");
6867 StringRef ArchFeatureName =
6868 StringSwitch<StringRef>(Arch)
6869 .Case("mips1", "mips1")
6870 .Case("mips2", "mips2")
6871 .Case("mips3", "mips3")
6872 .Case("mips4", "mips4")
6873 .Case("mips5", "mips5")
6874 .Case("mips32", "mips32")
6875 .Case("mips32r2", "mips32r2")
6876 .Case("mips32r3", "mips32r3")
6877 .Case("mips32r5", "mips32r5")
6878 .Case("mips32r6", "mips32r6")
6879 .Case("mips64", "mips64")
6880 .Case("mips64r2", "mips64r2")
6881 .Case("mips64r3", "mips64r3")
6882 .Case("mips64r5", "mips64r5")
6883 .Case("mips64r6", "mips64r6")
6884 .Case("octeon", "cnmips")
6885 .Case("r4000", "mips3") // This is an implementation of Mips3.
6888 if (ArchFeatureName.empty())
6889 return reportParseError("unsupported architecture");
6891 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
6892 return reportParseError("mips64r6 does not support microMIPS");
6894 selectArch(ArchFeatureName);
6895 getTargetStreamer().emitDirectiveSetArch(Arch);
6899 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6900 MCAsmParser &Parser = getParser();
6902 if (getLexer().isNot(AsmToken::EndOfStatement))
6903 return reportParseError("unexpected token, expected end of statement");
6907 llvm_unreachable("Unimplemented feature");
6908 case Mips::FeatureDSP:
6909 setFeatureBits(Mips::FeatureDSP, "dsp");
6910 getTargetStreamer().emitDirectiveSetDsp();
6912 case Mips::FeatureDSPR2:
6913 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
6914 getTargetStreamer().emitDirectiveSetDspr2();
6916 case Mips::FeatureMicroMips:
6917 setFeatureBits(Mips::FeatureMicroMips, "micromips");
6918 getTargetStreamer().emitDirectiveSetMicroMips();
6920 case Mips::FeatureMips1:
6921 selectArch("mips1");
6922 getTargetStreamer().emitDirectiveSetMips1();
6924 case Mips::FeatureMips2:
6925 selectArch("mips2");
6926 getTargetStreamer().emitDirectiveSetMips2();
6928 case Mips::FeatureMips3:
6929 selectArch("mips3");
6930 getTargetStreamer().emitDirectiveSetMips3();
6932 case Mips::FeatureMips4:
6933 selectArch("mips4");
6934 getTargetStreamer().emitDirectiveSetMips4();
6936 case Mips::FeatureMips5:
6937 selectArch("mips5");
6938 getTargetStreamer().emitDirectiveSetMips5();
6940 case Mips::FeatureMips32:
6941 selectArch("mips32");
6942 getTargetStreamer().emitDirectiveSetMips32();
6944 case Mips::FeatureMips32r2:
6945 selectArch("mips32r2");
6946 getTargetStreamer().emitDirectiveSetMips32R2();
6948 case Mips::FeatureMips32r3:
6949 selectArch("mips32r3");
6950 getTargetStreamer().emitDirectiveSetMips32R3();
6952 case Mips::FeatureMips32r5:
6953 selectArch("mips32r5");
6954 getTargetStreamer().emitDirectiveSetMips32R5();
6956 case Mips::FeatureMips32r6:
6957 selectArch("mips32r6");
6958 getTargetStreamer().emitDirectiveSetMips32R6();
6960 case Mips::FeatureMips64:
6961 selectArch("mips64");
6962 getTargetStreamer().emitDirectiveSetMips64();
6964 case Mips::FeatureMips64r2:
6965 selectArch("mips64r2");
6966 getTargetStreamer().emitDirectiveSetMips64R2();
6968 case Mips::FeatureMips64r3:
6969 selectArch("mips64r3");
6970 getTargetStreamer().emitDirectiveSetMips64R3();
6972 case Mips::FeatureMips64r5:
6973 selectArch("mips64r5");
6974 getTargetStreamer().emitDirectiveSetMips64R5();
6976 case Mips::FeatureMips64r6:
6977 selectArch("mips64r6");
6978 getTargetStreamer().emitDirectiveSetMips64R6();
6980 case Mips::FeatureCRC:
6981 setFeatureBits(Mips::FeatureCRC, "crc");
6982 getTargetStreamer().emitDirectiveSetCRC();
6984 case Mips::FeatureVirt:
6985 setFeatureBits(Mips::FeatureVirt, "virt");
6986 getTargetStreamer().emitDirectiveSetVirt();
6988 case Mips::FeatureGINV:
6989 setFeatureBits(Mips::FeatureGINV, "ginv");
6990 getTargetStreamer().emitDirectiveSetGINV();
6996 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
6997 MCAsmParser &Parser = getParser();
6998 if (getLexer().isNot(AsmToken::Comma)) {
6999 SMLoc Loc = getLexer().getLoc();
7000 return Error(Loc, ErrorStr);
7003 Parser.Lex(); // Eat the comma.
7007 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7008 // In this class, it is only used for .cprestore.
7009 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7010 // MipsTargetELFStreamer and MipsAsmParser.
7011 bool MipsAsmParser::isPicAndNotNxxAbi() {
7012 return inPicMode() && !(isABI_N32() || isABI_N64());
7015 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7016 if (AssemblerOptions.back()->isReorder())
7017 Warning(Loc, ".cpload should be inside a noreorder section");
7019 if (inMips16Mode()) {
7020 reportParseError(".cpload is not supported in Mips16 mode");
7024 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7025 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7026 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7027 reportParseError("expected register containing function address");
7031 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7032 if (!RegOpnd.isGPRAsmReg()) {
7033 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7037 // If this is not the end of the statement, report an error.
7038 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7039 reportParseError("unexpected token, expected end of statement");
7043 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7047 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7048 MCAsmParser &Parser = getParser();
7050 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7051 // is used in non-PIC mode.
7053 if (inMips16Mode()) {
7054 reportParseError(".cprestore is not supported in Mips16 mode");
7058 // Get the stack offset value.
7059 const MCExpr *StackOffset;
7060 int64_t StackOffsetVal;
7061 if (Parser.parseExpression(StackOffset)) {
7062 reportParseError("expected stack offset value");
7066 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7067 reportParseError("stack offset is not an absolute expression");
7071 if (StackOffsetVal < 0) {
7072 Warning(Loc, ".cprestore with negative stack offset has no effect");
7073 IsCpRestoreSet = false;
7075 IsCpRestoreSet = true;
7076 CpRestoreOffset = StackOffsetVal;
7079 // If this is not the end of the statement, report an error.
7080 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7081 reportParseError("unexpected token, expected end of statement");
7085 if (!getTargetStreamer().emitDirectiveCpRestore(
7086 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7088 Parser.Lex(); // Consume the EndOfStatement.
7092 bool MipsAsmParser::parseDirectiveCPSetup() {
7093 MCAsmParser &Parser = getParser();
7096 bool SaveIsReg = true;
7098 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7099 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7100 if (ResTy == MatchOperand_NoMatch) {
7101 reportParseError("expected register containing function address");
7105 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7106 if (!FuncRegOpnd.isGPRAsmReg()) {
7107 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7111 FuncReg = FuncRegOpnd.getGPR32Reg();
7114 if (!eatComma("unexpected token, expected comma"))
7117 ResTy = parseAnyRegister(TmpReg);
7118 if (ResTy == MatchOperand_NoMatch) {
7119 const MCExpr *OffsetExpr;
7121 SMLoc ExprLoc = getLexer().getLoc();
7123 if (Parser.parseExpression(OffsetExpr) ||
7124 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7125 reportParseError(ExprLoc, "expected save register or stack offset");
7132 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7133 if (!SaveOpnd.isGPRAsmReg()) {
7134 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7137 Save = SaveOpnd.getGPR32Reg();
7140 if (!eatComma("unexpected token, expected comma"))
7144 if (Parser.parseExpression(Expr)) {
7145 reportParseError("expected expression");
7149 if (Expr->getKind() != MCExpr::SymbolRef) {
7150 reportParseError("expected symbol");
7153 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7155 CpSaveLocation = Save;
7156 CpSaveLocationIsRegister = SaveIsReg;
7158 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7163 bool MipsAsmParser::parseDirectiveCPReturn() {
7164 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7165 CpSaveLocationIsRegister);
7169 bool MipsAsmParser::parseDirectiveNaN() {
7170 MCAsmParser &Parser = getParser();
7171 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7172 const AsmToken &Tok = Parser.getTok();
7174 if (Tok.getString() == "2008") {
7176 getTargetStreamer().emitDirectiveNaN2008();
7178 } else if (Tok.getString() == "legacy") {
7180 getTargetStreamer().emitDirectiveNaNLegacy();
7184 // If we don't recognize the option passed to the .nan
7185 // directive (e.g. no option or unknown option), emit an error.
7186 reportParseError("invalid option in .nan directive");
7190 bool MipsAsmParser::parseDirectiveSet() {
7191 const AsmToken &Tok = getParser().getTok();
7192 StringRef IdVal = Tok.getString();
7193 SMLoc Loc = Tok.getLoc();
7195 if (IdVal == "noat")
7196 return parseSetNoAtDirective();
7198 return parseSetAtDirective();
7199 if (IdVal == "arch")
7200 return parseSetArchDirective();
7201 if (IdVal == "bopt") {
7202 Warning(Loc, "'bopt' feature is unsupported");
7206 if (IdVal == "nobopt") {
7207 // We're already running in nobopt mode, so nothing to do.
7212 return parseSetFpDirective();
7213 if (IdVal == "oddspreg")
7214 return parseSetOddSPRegDirective();
7215 if (IdVal == "nooddspreg")
7216 return parseSetNoOddSPRegDirective();
7218 return parseSetPopDirective();
7219 if (IdVal == "push")
7220 return parseSetPushDirective();
7221 if (IdVal == "reorder")
7222 return parseSetReorderDirective();
7223 if (IdVal == "noreorder")
7224 return parseSetNoReorderDirective();
7225 if (IdVal == "macro")
7226 return parseSetMacroDirective();
7227 if (IdVal == "nomacro")
7228 return parseSetNoMacroDirective();
7229 if (IdVal == "mips16")
7230 return parseSetMips16Directive();
7231 if (IdVal == "nomips16")
7232 return parseSetNoMips16Directive();
7233 if (IdVal == "nomicromips") {
7234 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7235 getTargetStreamer().emitDirectiveSetNoMicroMips();
7236 getParser().eatToEndOfStatement();
7239 if (IdVal == "micromips") {
7240 if (hasMips64r6()) {
7241 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7244 return parseSetFeature(Mips::FeatureMicroMips);
7246 if (IdVal == "mips0")
7247 return parseSetMips0Directive();
7248 if (IdVal == "mips1")
7249 return parseSetFeature(Mips::FeatureMips1);
7250 if (IdVal == "mips2")
7251 return parseSetFeature(Mips::FeatureMips2);
7252 if (IdVal == "mips3")
7253 return parseSetFeature(Mips::FeatureMips3);
7254 if (IdVal == "mips4")
7255 return parseSetFeature(Mips::FeatureMips4);
7256 if (IdVal == "mips5")
7257 return parseSetFeature(Mips::FeatureMips5);
7258 if (IdVal == "mips32")
7259 return parseSetFeature(Mips::FeatureMips32);
7260 if (IdVal == "mips32r2")
7261 return parseSetFeature(Mips::FeatureMips32r2);
7262 if (IdVal == "mips32r3")
7263 return parseSetFeature(Mips::FeatureMips32r3);
7264 if (IdVal == "mips32r5")
7265 return parseSetFeature(Mips::FeatureMips32r5);
7266 if (IdVal == "mips32r6")
7267 return parseSetFeature(Mips::FeatureMips32r6);
7268 if (IdVal == "mips64")
7269 return parseSetFeature(Mips::FeatureMips64);
7270 if (IdVal == "mips64r2")
7271 return parseSetFeature(Mips::FeatureMips64r2);
7272 if (IdVal == "mips64r3")
7273 return parseSetFeature(Mips::FeatureMips64r3);
7274 if (IdVal == "mips64r5")
7275 return parseSetFeature(Mips::FeatureMips64r5);
7276 if (IdVal == "mips64r6") {
7277 if (inMicroMipsMode()) {
7278 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7281 return parseSetFeature(Mips::FeatureMips64r6);
7284 return parseSetFeature(Mips::FeatureDSP);
7285 if (IdVal == "dspr2")
7286 return parseSetFeature(Mips::FeatureDSPR2);
7287 if (IdVal == "nodsp")
7288 return parseSetNoDspDirective();
7290 return parseSetMsaDirective();
7291 if (IdVal == "nomsa")
7292 return parseSetNoMsaDirective();
7294 return parseSetMtDirective();
7295 if (IdVal == "nomt")
7296 return parseSetNoMtDirective();
7297 if (IdVal == "softfloat")
7298 return parseSetSoftFloatDirective();
7299 if (IdVal == "hardfloat")
7300 return parseSetHardFloatDirective();
7302 return parseSetFeature(Mips::FeatureCRC);
7303 if (IdVal == "nocrc")
7304 return parseSetNoCRCDirective();
7305 if (IdVal == "virt")
7306 return parseSetFeature(Mips::FeatureVirt);
7307 if (IdVal == "novirt")
7308 return parseSetNoVirtDirective();
7309 if (IdVal == "ginv")
7310 return parseSetFeature(Mips::FeatureGINV);
7311 if (IdVal == "noginv")
7312 return parseSetNoGINVDirective();
7314 // It is just an identifier, look for an assignment.
7315 return parseSetAssignment();
7318 /// parseDirectiveGpWord
7319 /// ::= .gpword local_sym
7320 bool MipsAsmParser::parseDirectiveGpWord() {
7321 MCAsmParser &Parser = getParser();
7322 const MCExpr *Value;
7323 // EmitGPRel32Value requires an expression, so we are using base class
7324 // method to evaluate the expression.
7325 if (getParser().parseExpression(Value))
7327 getParser().getStreamer().EmitGPRel32Value(Value);
7329 if (getLexer().isNot(AsmToken::EndOfStatement))
7330 return Error(getLexer().getLoc(),
7331 "unexpected token, expected end of statement");
7332 Parser.Lex(); // Eat EndOfStatement token.
7336 /// parseDirectiveGpDWord
7337 /// ::= .gpdword local_sym
7338 bool MipsAsmParser::parseDirectiveGpDWord() {
7339 MCAsmParser &Parser = getParser();
7340 const MCExpr *Value;
7341 // EmitGPRel64Value requires an expression, so we are using base class
7342 // method to evaluate the expression.
7343 if (getParser().parseExpression(Value))
7345 getParser().getStreamer().EmitGPRel64Value(Value);
7347 if (getLexer().isNot(AsmToken::EndOfStatement))
7348 return Error(getLexer().getLoc(),
7349 "unexpected token, expected end of statement");
7350 Parser.Lex(); // Eat EndOfStatement token.
7354 /// parseDirectiveDtpRelWord
7355 /// ::= .dtprelword tls_sym
7356 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7357 MCAsmParser &Parser = getParser();
7358 const MCExpr *Value;
7359 // EmitDTPRel32Value requires an expression, so we are using base class
7360 // method to evaluate the expression.
7361 if (getParser().parseExpression(Value))
7363 getParser().getStreamer().EmitDTPRel32Value(Value);
7365 if (getLexer().isNot(AsmToken::EndOfStatement))
7366 return Error(getLexer().getLoc(),
7367 "unexpected token, expected end of statement");
7368 Parser.Lex(); // Eat EndOfStatement token.
7372 /// parseDirectiveDtpRelDWord
7373 /// ::= .dtpreldword tls_sym
7374 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7375 MCAsmParser &Parser = getParser();
7376 const MCExpr *Value;
7377 // EmitDTPRel64Value requires an expression, so we are using base class
7378 // method to evaluate the expression.
7379 if (getParser().parseExpression(Value))
7381 getParser().getStreamer().EmitDTPRel64Value(Value);
7383 if (getLexer().isNot(AsmToken::EndOfStatement))
7384 return Error(getLexer().getLoc(),
7385 "unexpected token, expected end of statement");
7386 Parser.Lex(); // Eat EndOfStatement token.
7390 /// parseDirectiveTpRelWord
7391 /// ::= .tprelword tls_sym
7392 bool MipsAsmParser::parseDirectiveTpRelWord() {
7393 MCAsmParser &Parser = getParser();
7394 const MCExpr *Value;
7395 // EmitTPRel32Value requires an expression, so we are using base class
7396 // method to evaluate the expression.
7397 if (getParser().parseExpression(Value))
7399 getParser().getStreamer().EmitTPRel32Value(Value);
7401 if (getLexer().isNot(AsmToken::EndOfStatement))
7402 return Error(getLexer().getLoc(),
7403 "unexpected token, expected end of statement");
7404 Parser.Lex(); // Eat EndOfStatement token.
7408 /// parseDirectiveTpRelDWord
7409 /// ::= .tpreldword tls_sym
7410 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7411 MCAsmParser &Parser = getParser();
7412 const MCExpr *Value;
7413 // EmitTPRel64Value requires an expression, so we are using base class
7414 // method to evaluate the expression.
7415 if (getParser().parseExpression(Value))
7417 getParser().getStreamer().EmitTPRel64Value(Value);
7419 if (getLexer().isNot(AsmToken::EndOfStatement))
7420 return Error(getLexer().getLoc(),
7421 "unexpected token, expected end of statement");
7422 Parser.Lex(); // Eat EndOfStatement token.
7426 bool MipsAsmParser::parseDirectiveOption() {
7427 MCAsmParser &Parser = getParser();
7428 // Get the option token.
7429 AsmToken Tok = Parser.getTok();
7430 // At the moment only identifiers are supported.
7431 if (Tok.isNot(AsmToken::Identifier)) {
7432 return Error(Parser.getTok().getLoc(),
7433 "unexpected token, expected identifier");
7436 StringRef Option = Tok.getIdentifier();
7438 if (Option == "pic0") {
7439 // MipsAsmParser needs to know if the current PIC mode changes.
7440 IsPicEnabled = false;
7442 getTargetStreamer().emitDirectiveOptionPic0();
7444 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7445 return Error(Parser.getTok().getLoc(),
7446 "unexpected token, expected end of statement");
7451 if (Option == "pic2") {
7452 // MipsAsmParser needs to know if the current PIC mode changes.
7453 IsPicEnabled = true;
7455 getTargetStreamer().emitDirectiveOptionPic2();
7457 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7458 return Error(Parser.getTok().getLoc(),
7459 "unexpected token, expected end of statement");
7465 Warning(Parser.getTok().getLoc(),
7466 "unknown option, expected 'pic0' or 'pic2'");
7467 Parser.eatToEndOfStatement();
7471 /// parseInsnDirective
7473 bool MipsAsmParser::parseInsnDirective() {
7474 // If this is not the end of the statement, report an error.
7475 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7476 reportParseError("unexpected token, expected end of statement");
7480 // The actual label marking happens in
7481 // MipsELFStreamer::createPendingLabelRelocs().
7482 getTargetStreamer().emitDirectiveInsn();
7484 getParser().Lex(); // Eat EndOfStatement token.
7488 /// parseRSectionDirective
7490 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7491 // If this is not the end of the statement, report an error.
7492 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7493 reportParseError("unexpected token, expected end of statement");
7497 MCSection *ELFSection = getContext().getELFSection(
7498 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7499 getParser().getStreamer().SwitchSection(ELFSection);
7501 getParser().Lex(); // Eat EndOfStatement token.
7505 /// parseSSectionDirective
7508 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7509 // If this is not the end of the statement, report an error.
7510 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7511 reportParseError("unexpected token, expected end of statement");
7515 MCSection *ELFSection = getContext().getELFSection(
7516 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7517 getParser().getStreamer().SwitchSection(ELFSection);
7519 getParser().Lex(); // Eat EndOfStatement token.
7523 /// parseDirectiveModule
7524 /// ::= .module oddspreg
7525 /// ::= .module nooddspreg
7526 /// ::= .module fp=value
7527 /// ::= .module softfloat
7528 /// ::= .module hardfloat
7531 /// ::= .module nocrc
7532 /// ::= .module virt
7533 /// ::= .module novirt
7534 /// ::= .module ginv
7535 /// ::= .module noginv
7536 bool MipsAsmParser::parseDirectiveModule() {
7537 MCAsmParser &Parser = getParser();
7538 MCAsmLexer &Lexer = getLexer();
7539 SMLoc L = Lexer.getLoc();
7541 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7542 // TODO : get a better message.
7543 reportParseError(".module directive must appear before any code");
7548 if (Parser.parseIdentifier(Option)) {
7549 reportParseError("expected .module option identifier");
7553 if (Option == "oddspreg") {
7554 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7556 // Synchronize the abiflags information with the FeatureBits information we
7558 getTargetStreamer().updateABIInfo(*this);
7560 // If printing assembly, use the recently updated abiflags information.
7561 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7562 // emitted at the end).
7563 getTargetStreamer().emitDirectiveModuleOddSPReg();
7565 // If this is not the end of the statement, report an error.
7566 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7567 reportParseError("unexpected token, expected end of statement");
7571 return false; // parseDirectiveModule has finished successfully.
7572 } else if (Option == "nooddspreg") {
7574 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7577 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7579 // Synchronize the abiflags information with the FeatureBits information we
7581 getTargetStreamer().updateABIInfo(*this);
7583 // If printing assembly, use the recently updated abiflags information.
7584 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7585 // emitted at the end).
7586 getTargetStreamer().emitDirectiveModuleOddSPReg();
7588 // If this is not the end of the statement, report an error.
7589 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7590 reportParseError("unexpected token, expected end of statement");
7594 return false; // parseDirectiveModule has finished successfully.
7595 } else if (Option == "fp") {
7596 return parseDirectiveModuleFP();
7597 } else if (Option == "softfloat") {
7598 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7600 // Synchronize the ABI Flags information with the FeatureBits information we
7602 getTargetStreamer().updateABIInfo(*this);
7604 // If printing assembly, use the recently updated ABI Flags information.
7605 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7607 getTargetStreamer().emitDirectiveModuleSoftFloat();
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 == "hardfloat") {
7617 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7619 // Synchronize the ABI Flags information with the FeatureBits information we
7621 getTargetStreamer().updateABIInfo(*this);
7623 // If printing assembly, use the recently updated ABI Flags information.
7624 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7626 getTargetStreamer().emitDirectiveModuleHardFloat();
7628 // If this is not the end of the statement, report an error.
7629 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7630 reportParseError("unexpected token, expected end of statement");
7634 return false; // parseDirectiveModule has finished successfully.
7635 } else if (Option == "mt") {
7636 setModuleFeatureBits(Mips::FeatureMT, "mt");
7638 // Synchronize the ABI Flags information with the FeatureBits information we
7640 getTargetStreamer().updateABIInfo(*this);
7642 // If printing assembly, use the recently updated ABI Flags information.
7643 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7645 getTargetStreamer().emitDirectiveModuleMT();
7647 // If this is not the end of the statement, report an error.
7648 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7649 reportParseError("unexpected token, expected end of statement");
7653 return false; // parseDirectiveModule has finished successfully.
7654 } else if (Option == "crc") {
7655 setModuleFeatureBits(Mips::FeatureCRC, "crc");
7657 // Synchronize the ABI Flags information with the FeatureBits information we
7659 getTargetStreamer().updateABIInfo(*this);
7661 // If printing assembly, use the recently updated ABI Flags information.
7662 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7664 getTargetStreamer().emitDirectiveModuleCRC();
7666 // If this is not the end of the statement, report an error.
7667 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7668 reportParseError("unexpected token, expected end of statement");
7672 return false; // parseDirectiveModule has finished successfully.
7673 } else if (Option == "nocrc") {
7674 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
7676 // Synchronize the ABI Flags information with the FeatureBits information we
7678 getTargetStreamer().updateABIInfo(*this);
7680 // If printing assembly, use the recently updated ABI Flags information.
7681 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7683 getTargetStreamer().emitDirectiveModuleNoCRC();
7685 // If this is not the end of the statement, report an error.
7686 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7687 reportParseError("unexpected token, expected end of statement");
7691 return false; // parseDirectiveModule has finished successfully.
7692 } else if (Option == "virt") {
7693 setModuleFeatureBits(Mips::FeatureVirt, "virt");
7695 // Synchronize the ABI Flags information with the FeatureBits information we
7697 getTargetStreamer().updateABIInfo(*this);
7699 // If printing assembly, use the recently updated ABI Flags information.
7700 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7702 getTargetStreamer().emitDirectiveModuleVirt();
7704 // If this is not the end of the statement, report an error.
7705 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7706 reportParseError("unexpected token, expected end of statement");
7710 return false; // parseDirectiveModule has finished successfully.
7711 } else if (Option == "novirt") {
7712 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
7714 // Synchronize the ABI Flags information with the FeatureBits information we
7716 getTargetStreamer().updateABIInfo(*this);
7718 // If printing assembly, use the recently updated ABI Flags information.
7719 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7721 getTargetStreamer().emitDirectiveModuleNoVirt();
7723 // If this is not the end of the statement, report an error.
7724 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7725 reportParseError("unexpected token, expected end of statement");
7729 return false; // parseDirectiveModule has finished successfully.
7730 } else if (Option == "ginv") {
7731 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
7733 // Synchronize the ABI Flags information with the FeatureBits information we
7735 getTargetStreamer().updateABIInfo(*this);
7737 // If printing assembly, use the recently updated ABI Flags information.
7738 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7740 getTargetStreamer().emitDirectiveModuleGINV();
7742 // If this is not the end of the statement, report an error.
7743 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7744 reportParseError("unexpected token, expected end of statement");
7748 return false; // parseDirectiveModule has finished successfully.
7749 } else if (Option == "noginv") {
7750 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
7752 // Synchronize the ABI Flags information with the FeatureBits information we
7754 getTargetStreamer().updateABIInfo(*this);
7756 // If printing assembly, use the recently updated ABI Flags information.
7757 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7759 getTargetStreamer().emitDirectiveModuleNoGINV();
7761 // If this is not the end of the statement, report an error.
7762 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7763 reportParseError("unexpected token, expected end of statement");
7767 return false; // parseDirectiveModule has finished successfully.
7769 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
7773 /// parseDirectiveModuleFP
7777 bool MipsAsmParser::parseDirectiveModuleFP() {
7778 MCAsmParser &Parser = getParser();
7779 MCAsmLexer &Lexer = getLexer();
7781 if (Lexer.isNot(AsmToken::Equal)) {
7782 reportParseError("unexpected token, expected equals sign '='");
7785 Parser.Lex(); // Eat '=' token.
7787 MipsABIFlagsSection::FpABIKind FpABI;
7788 if (!parseFpABIValue(FpABI, ".module"))
7791 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7792 reportParseError("unexpected token, expected end of statement");
7796 // Synchronize the abiflags information with the FeatureBits information we
7798 getTargetStreamer().updateABIInfo(*this);
7800 // If printing assembly, use the recently updated abiflags information.
7801 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7802 // emitted at the end).
7803 getTargetStreamer().emitDirectiveModuleFP();
7805 Parser.Lex(); // Consume the EndOfStatement.
7809 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
7810 StringRef Directive) {
7811 MCAsmParser &Parser = getParser();
7812 MCAsmLexer &Lexer = getLexer();
7813 bool ModuleLevelOptions = Directive == ".module";
7815 if (Lexer.is(AsmToken::Identifier)) {
7816 StringRef Value = Parser.getTok().getString();
7819 if (Value != "xx") {
7820 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7825 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
7829 FpABI = MipsABIFlagsSection::FpABIKind::XX;
7830 if (ModuleLevelOptions) {
7831 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7832 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7834 setFeatureBits(Mips::FeatureFPXX, "fpxx");
7835 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7840 if (Lexer.is(AsmToken::Integer)) {
7841 unsigned Value = Parser.getTok().getIntVal();
7844 if (Value != 32 && Value != 64) {
7845 reportParseError("unsupported value, expected 'xx', '32' or '64'");
7851 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
7855 FpABI = MipsABIFlagsSection::FpABIKind::S32;
7856 if (ModuleLevelOptions) {
7857 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7858 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7860 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7861 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
7864 FpABI = MipsABIFlagsSection::FpABIKind::S64;
7865 if (ModuleLevelOptions) {
7866 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
7867 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
7869 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
7870 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
7880 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
7881 // This returns false if this function recognizes the directive
7882 // regardless of whether it is successfully handles or reports an
7883 // error. Otherwise it returns true to give the generic parser a
7884 // chance at recognizing it.
7886 MCAsmParser &Parser = getParser();
7887 StringRef IDVal = DirectiveID.getString();
7889 if (IDVal == ".cpload") {
7890 parseDirectiveCpLoad(DirectiveID.getLoc());
7893 if (IDVal == ".cprestore") {
7894 parseDirectiveCpRestore(DirectiveID.getLoc());
7897 if (IDVal == ".ent") {
7898 StringRef SymbolName;
7900 if (Parser.parseIdentifier(SymbolName)) {
7901 reportParseError("expected identifier after .ent");
7905 // There's an undocumented extension that allows an integer to
7906 // follow the name of the procedure which AFAICS is ignored by GAS.
7907 // Example: .ent foo,2
7908 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7909 if (getLexer().isNot(AsmToken::Comma)) {
7910 // Even though we accept this undocumented extension for compatibility
7911 // reasons, the additional integer argument does not actually change
7912 // the behaviour of the '.ent' directive, so we would like to discourage
7913 // its use. We do this by not referring to the extended version in
7914 // error messages which are not directly related to its use.
7915 reportParseError("unexpected token, expected end of statement");
7918 Parser.Lex(); // Eat the comma.
7919 const MCExpr *DummyNumber;
7920 int64_t DummyNumberVal;
7921 // If the user was explicitly trying to use the extended version,
7922 // we still give helpful extension-related error messages.
7923 if (Parser.parseExpression(DummyNumber)) {
7924 reportParseError("expected number after comma");
7927 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7928 reportParseError("expected an absolute expression after comma");
7933 // If this is not the end of the statement, report an error.
7934 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7935 reportParseError("unexpected token, expected end of statement");
7939 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7941 getTargetStreamer().emitDirectiveEnt(*Sym);
7943 IsCpRestoreSet = false;
7947 if (IDVal == ".end") {
7948 StringRef SymbolName;
7950 if (Parser.parseIdentifier(SymbolName)) {
7951 reportParseError("expected identifier after .end");
7955 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7956 reportParseError("unexpected token, expected end of statement");
7960 if (CurrentFn == nullptr) {
7961 reportParseError(".end used without .ent");
7965 if ((SymbolName != CurrentFn->getName())) {
7966 reportParseError(".end symbol does not match .ent symbol");
7970 getTargetStreamer().emitDirectiveEnd(SymbolName);
7971 CurrentFn = nullptr;
7972 IsCpRestoreSet = false;
7976 if (IDVal == ".frame") {
7977 // .frame $stack_reg, frame_size_in_bytes, $return_reg
7978 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7979 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7980 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7981 reportParseError("expected stack register");
7985 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7986 if (!StackRegOpnd.isGPRAsmReg()) {
7987 reportParseError(StackRegOpnd.getStartLoc(),
7988 "expected general purpose register");
7991 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7993 if (Parser.getTok().is(AsmToken::Comma))
7996 reportParseError("unexpected token, expected comma");
8000 // Parse the frame size.
8001 const MCExpr *FrameSize;
8002 int64_t FrameSizeVal;
8004 if (Parser.parseExpression(FrameSize)) {
8005 reportParseError("expected frame size value");
8009 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8010 reportParseError("frame size not an absolute expression");
8014 if (Parser.getTok().is(AsmToken::Comma))
8017 reportParseError("unexpected token, expected comma");
8021 // Parse the return register.
8023 ResTy = parseAnyRegister(TmpReg);
8024 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8025 reportParseError("expected return register");
8029 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8030 if (!ReturnRegOpnd.isGPRAsmReg()) {
8031 reportParseError(ReturnRegOpnd.getStartLoc(),
8032 "expected general purpose register");
8036 // If this is not the end of the statement, report an error.
8037 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8038 reportParseError("unexpected token, expected end of statement");
8042 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8043 ReturnRegOpnd.getGPR32Reg());
8044 IsCpRestoreSet = false;
8048 if (IDVal == ".set") {
8049 parseDirectiveSet();
8053 if (IDVal == ".mask" || IDVal == ".fmask") {
8054 // .mask bitmask, frame_offset
8055 // bitmask: One bit for each register used.
8056 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8057 // first register is expected to be saved.
8059 // .mask 0x80000000, -4
8060 // .fmask 0x80000000, -4
8063 // Parse the bitmask
8064 const MCExpr *BitMask;
8067 if (Parser.parseExpression(BitMask)) {
8068 reportParseError("expected bitmask value");
8072 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8073 reportParseError("bitmask not an absolute expression");
8077 if (Parser.getTok().is(AsmToken::Comma))
8080 reportParseError("unexpected token, expected comma");
8084 // Parse the frame_offset
8085 const MCExpr *FrameOffset;
8086 int64_t FrameOffsetVal;
8088 if (Parser.parseExpression(FrameOffset)) {
8089 reportParseError("expected frame offset value");
8093 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8094 reportParseError("frame offset not an absolute expression");
8098 // If this is not the end of the statement, report an error.
8099 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8100 reportParseError("unexpected token, expected end of statement");
8104 if (IDVal == ".mask")
8105 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8107 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8111 if (IDVal == ".nan")
8112 return parseDirectiveNaN();
8114 if (IDVal == ".gpword") {
8115 parseDirectiveGpWord();
8119 if (IDVal == ".gpdword") {
8120 parseDirectiveGpDWord();
8124 if (IDVal == ".dtprelword") {
8125 parseDirectiveDtpRelWord();
8129 if (IDVal == ".dtpreldword") {
8130 parseDirectiveDtpRelDWord();
8134 if (IDVal == ".tprelword") {
8135 parseDirectiveTpRelWord();
8139 if (IDVal == ".tpreldword") {
8140 parseDirectiveTpRelDWord();
8144 if (IDVal == ".option") {
8145 parseDirectiveOption();
8149 if (IDVal == ".abicalls") {
8150 getTargetStreamer().emitDirectiveAbiCalls();
8151 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8152 Error(Parser.getTok().getLoc(),
8153 "unexpected token, expected end of statement");
8158 if (IDVal == ".cpsetup") {
8159 parseDirectiveCPSetup();
8162 if (IDVal == ".cpreturn") {
8163 parseDirectiveCPReturn();
8166 if (IDVal == ".module") {
8167 parseDirectiveModule();
8170 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8171 parseInternalDirectiveReallowModule();
8174 if (IDVal == ".insn") {
8175 parseInsnDirective();
8178 if (IDVal == ".rdata") {
8179 parseRSectionDirective(".rodata");
8182 if (IDVal == ".sbss") {
8183 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8186 if (IDVal == ".sdata") {
8187 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8194 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8195 // If this is not the end of the statement, report an error.
8196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8197 reportParseError("unexpected token, expected end of statement");
8201 getTargetStreamer().reallowModuleDirective();
8203 getParser().Lex(); // Eat EndOfStatement token.
8207 extern "C" void LLVMInitializeMipsAsmParser() {
8208 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8209 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8210 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8211 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8214 #define GET_REGISTER_MATCHER
8215 #define GET_MATCHER_IMPLEMENTATION
8216 #define GET_MNEMONIC_SPELL_CHECKER
8217 #include "MipsGenAsmMatcher.inc"
8219 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8220 // Find the appropriate table for this asm variant.
8221 const MatchEntry *Start, *End;
8222 switch (VariantID) {
8223 default: llvm_unreachable("invalid variant!");
8224 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8226 // Search the table.
8227 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8228 return MnemonicRange.first != MnemonicRange.second;