1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/MipsABIFlagsSection.h"
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsBaseInfo.h"
12 #include "MCTargetDesc/MipsMCExpr.h"
13 #include "MCTargetDesc/MipsMCTargetDesc.h"
14 #include "MipsTargetStreamer.h"
15 #include "TargetInfo/MipsTargetInfo.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/MCAsmParserUtils.h"
33 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
35 #include "llvm/MC/MCSectionELF.h"
36 #include "llvm/MC/MCStreamer.h"
37 #include "llvm/MC/MCSubtargetInfo.h"
38 #include "llvm/MC/MCSymbol.h"
39 #include "llvm/MC/MCSymbolELF.h"
40 #include "llvm/MC/MCValue.h"
41 #include "llvm/MC/SubtargetFeature.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Compiler.h"
45 #include "llvm/Support/Debug.h"
46 #include "llvm/Support/ErrorHandling.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/SMLoc.h"
49 #include "llvm/Support/SourceMgr.h"
50 #include "llvm/Support/TargetRegistry.h"
51 #include "llvm/Support/raw_ostream.h"
61 #define DEBUG_TYPE "mips-asm-parser"
67 } // end namespace llvm
69 extern cl::opt<bool> EmitJalrReloc;
73 class MipsAssemblerOptions {
75 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
77 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
78 ATReg = Opts->getATRegIndex();
79 Reorder = Opts->isReorder();
80 Macro = Opts->isMacro();
81 Features = Opts->getFeatures();
84 unsigned getATRegIndex() const { return ATReg; }
85 bool setATRegIndex(unsigned Reg) {
93 bool isReorder() const { return Reorder; }
94 void setReorder() { Reorder = true; }
95 void setNoReorder() { Reorder = false; }
97 bool isMacro() const { return Macro; }
98 void setMacro() { Macro = true; }
99 void setNoMacro() { Macro = false; }
101 const FeatureBitset &getFeatures() const { return Features; }
102 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
104 // Set of features that are either architecture features or referenced
105 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
106 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
107 // The reason we need this mask is explained in the selectArch function.
108 // FIXME: Ideally we would like TableGen to generate this information.
109 static const FeatureBitset AllArchRelatedMask;
115 FeatureBitset Features;
118 } // end anonymous namespace
120 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
121 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
122 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
123 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
124 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
125 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
126 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
127 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
128 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
133 class MipsAsmParser : public MCTargetAsmParser {
134 MipsTargetStreamer &getTargetStreamer() {
135 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
136 return static_cast<MipsTargetStreamer &>(TS);
140 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
141 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
142 // nullptr, which indicates that no function is currently
143 // selected. This usually happens after an '.end func'
150 unsigned CpSaveLocation;
151 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
152 bool CpSaveLocationIsRegister;
154 // Map of register aliases created via the .set directive.
155 StringMap<AsmToken> RegisterSets;
157 // Print a warning along with its fix-it message at the given range.
158 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
159 SMRange Range, bool ShowColors = true);
161 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
163 #define GET_ASSEMBLER_HEADER
164 #include "MipsGenAsmMatcher.inc"
167 checkEarlyTargetMatchPredicate(MCInst &Inst,
168 const OperandVector &Operands) override;
169 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
171 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
172 OperandVector &Operands, MCStreamer &Out,
174 bool MatchingInlineAsm) override;
176 /// Parse a register as used in CFI directives
177 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
179 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
181 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
183 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
185 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
186 SMLoc NameLoc, OperandVector &Operands) override;
188 bool ParseDirective(AsmToken DirectiveID) override;
190 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
192 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
193 StringRef Identifier, SMLoc S);
194 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
195 const AsmToken &Token,
197 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
199 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
200 OperandMatchResultTy parseImm(OperandVector &Operands);
201 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
202 OperandMatchResultTy parseInvNum(OperandVector &Operands);
203 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
205 bool searchSymbolAlias(OperandVector &Operands);
207 bool parseOperand(OperandVector &, StringRef Mnemonic);
209 enum MacroExpanderResultTy {
215 // Expands assembly pseudo instructions.
216 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
218 const MCSubtargetInfo *STI);
220 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
221 const MCSubtargetInfo *STI);
223 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
224 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
225 MCStreamer &Out, const MCSubtargetInfo *STI);
227 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
228 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
229 MCStreamer &Out, const MCSubtargetInfo *STI);
231 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
233 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
234 MCStreamer &Out, const MCSubtargetInfo *STI);
236 bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
237 SMLoc IDLoc, MCStreamer &Out,
238 const MCSubtargetInfo *STI);
240 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
241 const MCOperand &Offset, bool Is32BitAddress,
242 SMLoc IDLoc, MCStreamer &Out,
243 const MCSubtargetInfo *STI);
245 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
248 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
249 const MCSubtargetInfo *STI, bool IsLoad);
251 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
252 const MCSubtargetInfo *STI);
254 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI);
257 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI);
260 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI);
263 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264 const MCSubtargetInfo *STI, const bool IsMips64,
267 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
268 MCStreamer &Out, const MCSubtargetInfo *STI);
270 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
271 const MCSubtargetInfo *STI);
273 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
274 const MCSubtargetInfo *STI);
276 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI);
279 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
282 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
285 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
288 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
289 MCStreamer &Out, const MCSubtargetInfo *STI);
290 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291 const MCSubtargetInfo *STI);
292 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
294 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295 const MCSubtargetInfo *STI);
297 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298 const MCSubtargetInfo *STI);
300 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301 const MCSubtargetInfo *STI);
303 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304 const MCSubtargetInfo *STI);
306 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
307 const MCSubtargetInfo *STI);
309 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310 const MCSubtargetInfo *STI);
312 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI, bool IsLoad);
315 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316 const MCSubtargetInfo *STI);
318 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319 const MCSubtargetInfo *STI);
321 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322 const MCSubtargetInfo *STI);
324 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325 const MCSubtargetInfo *STI);
327 bool reportParseError(Twine ErrorMsg);
328 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
330 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
332 bool isEvaluated(const MCExpr *Expr);
333 bool parseSetMips0Directive();
334 bool parseSetArchDirective();
335 bool parseSetFeature(uint64_t Feature);
336 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
337 bool parseDirectiveCpLoad(SMLoc Loc);
338 bool parseDirectiveCpLocal(SMLoc Loc);
339 bool parseDirectiveCpRestore(SMLoc Loc);
340 bool parseDirectiveCPSetup();
341 bool parseDirectiveCPReturn();
342 bool parseDirectiveNaN();
343 bool parseDirectiveSet();
344 bool parseDirectiveOption();
345 bool parseInsnDirective();
346 bool parseRSectionDirective(StringRef Section);
347 bool parseSSectionDirective(StringRef Section, unsigned Type);
349 bool parseSetAtDirective();
350 bool parseSetNoAtDirective();
351 bool parseSetMacroDirective();
352 bool parseSetNoMacroDirective();
353 bool parseSetMsaDirective();
354 bool parseSetNoMsaDirective();
355 bool parseSetNoDspDirective();
356 bool parseSetReorderDirective();
357 bool parseSetNoReorderDirective();
358 bool parseSetMips16Directive();
359 bool parseSetNoMips16Directive();
360 bool parseSetFpDirective();
361 bool parseSetOddSPRegDirective();
362 bool parseSetNoOddSPRegDirective();
363 bool parseSetPopDirective();
364 bool parseSetPushDirective();
365 bool parseSetSoftFloatDirective();
366 bool parseSetHardFloatDirective();
367 bool parseSetMtDirective();
368 bool parseSetNoMtDirective();
369 bool parseSetNoCRCDirective();
370 bool parseSetNoVirtDirective();
371 bool parseSetNoGINVDirective();
373 bool parseSetAssignment();
375 bool parseDirectiveGpWord();
376 bool parseDirectiveGpDWord();
377 bool parseDirectiveDtpRelWord();
378 bool parseDirectiveDtpRelDWord();
379 bool parseDirectiveTpRelWord();
380 bool parseDirectiveTpRelDWord();
381 bool parseDirectiveModule();
382 bool parseDirectiveModuleFP();
383 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
384 StringRef Directive);
386 bool parseInternalDirectiveReallowModule();
388 bool eatComma(StringRef ErrorStr);
390 int matchCPURegisterName(StringRef Symbol);
392 int matchHWRegsRegisterName(StringRef Symbol);
394 int matchFPURegisterName(StringRef Name);
396 int matchFCCRegisterName(StringRef Name);
398 int matchACRegisterName(StringRef Name);
400 int matchMSA128RegisterName(StringRef Name);
402 int matchMSA128CtrlRegisterName(StringRef Name);
404 unsigned getReg(int RC, int RegNo);
406 /// Returns the internal register number for the current AT. Also checks if
407 /// the current AT is unavailable (set to $0) and gives an error if it is.
408 /// This should be used in pseudo-instruction expansions which need AT.
409 unsigned getATReg(SMLoc Loc);
413 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
414 const MCSubtargetInfo *STI);
416 // Helper function that checks if the value of a vector index is within the
417 // boundaries of accepted values for each RegisterKind
418 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
419 bool validateMSAIndex(int Val, int RegKind);
421 // Selects a new architecture by updating the FeatureBits with the necessary
422 // info including implied dependencies.
423 // Internally, it clears all the feature bits related to *any* architecture
424 // and selects the new one using the ToggleFeature functionality of the
425 // MCSubtargetInfo object that handles implied dependencies. The reason we
426 // clear all the arch related bits manually is because ToggleFeature only
427 // clears the features that imply the feature being cleared and not the
428 // features implied by the feature being cleared. This is easier to see
430 // --------------------------------------------------
431 // | Feature | Implies |
432 // | -------------------------------------------------|
433 // | FeatureMips1 | None |
434 // | FeatureMips2 | FeatureMips1 |
435 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
436 // | FeatureMips4 | FeatureMips3 |
438 // --------------------------------------------------
440 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
441 // FeatureMipsGP64 | FeatureMips1)
442 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
443 void selectArch(StringRef ArchFeature) {
444 MCSubtargetInfo &STI = copySTI();
445 FeatureBitset FeatureBits = STI.getFeatureBits();
446 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
447 STI.setFeatureBits(FeatureBits);
448 setAvailableFeatures(
449 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
450 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
453 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
454 if (!(getSTI().getFeatureBits()[Feature])) {
455 MCSubtargetInfo &STI = copySTI();
456 setAvailableFeatures(
457 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
458 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
462 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
463 if (getSTI().getFeatureBits()[Feature]) {
464 MCSubtargetInfo &STI = copySTI();
465 setAvailableFeatures(
466 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
467 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
471 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
472 setFeatureBits(Feature, FeatureString);
473 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
476 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
477 clearFeatureBits(Feature, FeatureString);
478 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
482 enum MipsMatchResultTy {
483 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
484 Match_RequiresDifferentOperands,
485 Match_RequiresNoZeroRegister,
486 Match_RequiresSameSrcAndDst,
487 Match_NoFCCRegisterForCurrentISA,
488 Match_NonZeroOperandForSync,
489 Match_NonZeroOperandForMTCX,
490 Match_RequiresPosSizeRange0_32,
491 Match_RequiresPosSizeRange33_64,
492 Match_RequiresPosSizeUImm6,
493 #define GET_OPERAND_DIAGNOSTIC_TYPES
494 #include "MipsGenAsmMatcher.inc"
495 #undef GET_OPERAND_DIAGNOSTIC_TYPES
498 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
499 const MCInstrInfo &MII, const MCTargetOptions &Options)
500 : MCTargetAsmParser(Options, sti, MII),
501 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
502 sti.getCPU(), Options)) {
503 MCAsmParserExtension::Initialize(parser);
505 parser.addAliasForDirective(".asciiz", ".asciz");
506 parser.addAliasForDirective(".hword", ".2byte");
507 parser.addAliasForDirective(".word", ".4byte");
508 parser.addAliasForDirective(".dword", ".8byte");
510 // Initialize the set of available features.
511 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
513 // Remember the initial assembler options. The user can not modify these.
514 AssemblerOptions.push_back(
515 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
517 // Create an assembler options environment for the user to modify.
518 AssemblerOptions.push_back(
519 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
521 getTargetStreamer().updateABIInfo(*this);
523 if (!isABI_O32() && !useOddSPReg() != 0)
524 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
528 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
530 IsCpRestoreSet = false;
531 CpRestoreOffset = -1;
532 GPReg = ABI.GetGlobalPtr();
534 const Triple &TheTriple = sti.getTargetTriple();
535 IsLittleEndian = TheTriple.isLittleEndian();
537 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
538 report_fatal_error("microMIPS64R6 is not supported", false);
540 if (!isABI_O32() && inMicroMipsMode())
541 report_fatal_error("microMIPS64 is not supported", false);
544 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
545 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
547 bool isGP64bit() const {
548 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
551 bool isFP64bit() const {
552 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
555 const MipsABIInfo &getABI() const { return ABI; }
556 bool isABI_N32() const { return ABI.IsN32(); }
557 bool isABI_N64() const { return ABI.IsN64(); }
558 bool isABI_O32() const { return ABI.IsO32(); }
559 bool isABI_FPXX() const {
560 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
563 bool useOddSPReg() const {
564 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
567 bool inMicroMipsMode() const {
568 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
571 bool hasMips1() const {
572 return getSTI().getFeatureBits()[Mips::FeatureMips1];
575 bool hasMips2() const {
576 return getSTI().getFeatureBits()[Mips::FeatureMips2];
579 bool hasMips3() const {
580 return getSTI().getFeatureBits()[Mips::FeatureMips3];
583 bool hasMips4() const {
584 return getSTI().getFeatureBits()[Mips::FeatureMips4];
587 bool hasMips5() const {
588 return getSTI().getFeatureBits()[Mips::FeatureMips5];
591 bool hasMips32() const {
592 return getSTI().getFeatureBits()[Mips::FeatureMips32];
595 bool hasMips64() const {
596 return getSTI().getFeatureBits()[Mips::FeatureMips64];
599 bool hasMips32r2() const {
600 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
603 bool hasMips64r2() const {
604 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
607 bool hasMips32r3() const {
608 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
611 bool hasMips64r3() const {
612 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
615 bool hasMips32r5() const {
616 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
619 bool hasMips64r5() const {
620 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
623 bool hasMips32r6() const {
624 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
627 bool hasMips64r6() const {
628 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
631 bool hasDSP() const {
632 return getSTI().getFeatureBits()[Mips::FeatureDSP];
635 bool hasDSPR2() const {
636 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
639 bool hasDSPR3() const {
640 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
643 bool hasMSA() const {
644 return getSTI().getFeatureBits()[Mips::FeatureMSA];
647 bool hasCnMips() const {
648 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
655 bool inMips16Mode() const {
656 return getSTI().getFeatureBits()[Mips::FeatureMips16];
659 bool useTraps() const {
660 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
663 bool useSoftFloat() const {
664 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
667 return getSTI().getFeatureBits()[Mips::FeatureMT];
670 bool hasCRC() const {
671 return getSTI().getFeatureBits()[Mips::FeatureCRC];
674 bool hasVirt() const {
675 return getSTI().getFeatureBits()[Mips::FeatureVirt];
678 bool hasGINV() const {
679 return getSTI().getFeatureBits()[Mips::FeatureGINV];
682 /// Warn if RegIndex is the same as the current AT.
683 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
685 void warnIfNoMacro(SMLoc Loc);
687 bool isLittle() const { return IsLittleEndian; }
689 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
690 AsmToken::TokenKind OperatorToken,
691 MCContext &Ctx) override {
692 switch(OperatorToken) {
694 llvm_unreachable("Unknown token");
696 case AsmToken::PercentCall16:
697 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
698 case AsmToken::PercentCall_Hi:
699 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
700 case AsmToken::PercentCall_Lo:
701 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
702 case AsmToken::PercentDtprel_Hi:
703 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
704 case AsmToken::PercentDtprel_Lo:
705 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
706 case AsmToken::PercentGot:
707 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
708 case AsmToken::PercentGot_Disp:
709 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
710 case AsmToken::PercentGot_Hi:
711 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
712 case AsmToken::PercentGot_Lo:
713 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
714 case AsmToken::PercentGot_Ofst:
715 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
716 case AsmToken::PercentGot_Page:
717 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
718 case AsmToken::PercentGottprel:
719 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
720 case AsmToken::PercentGp_Rel:
721 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
722 case AsmToken::PercentHi:
723 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
724 case AsmToken::PercentHigher:
725 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
726 case AsmToken::PercentHighest:
727 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
728 case AsmToken::PercentLo:
729 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
730 case AsmToken::PercentNeg:
731 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
732 case AsmToken::PercentPcrel_Hi:
733 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
734 case AsmToken::PercentPcrel_Lo:
735 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
736 case AsmToken::PercentTlsgd:
737 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
738 case AsmToken::PercentTlsldm:
739 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
740 case AsmToken::PercentTprel_Hi:
741 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
742 case AsmToken::PercentTprel_Lo:
743 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
748 /// MipsOperand - Instances of this class represent a parsed Mips machine
750 class MipsOperand : public MCParsedAsmOperand {
752 /// Broad categories of register classes
753 /// The exact class is finalized by the render method.
755 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
756 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
758 RegKind_FCC = 4, /// FCC
759 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
760 RegKind_MSACtrl = 16, /// MSA control registers
761 RegKind_COP2 = 32, /// COP2
762 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
764 RegKind_CCR = 128, /// CCR
765 RegKind_HWRegs = 256, /// HWRegs
766 RegKind_COP3 = 512, /// COP3
767 RegKind_COP0 = 1024, /// COP0
768 /// Potentially any (e.g. $1)
769 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
770 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
771 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
776 k_Immediate, /// An immediate (possibly involving symbol references)
777 k_Memory, /// Base + Offset Memory Address
778 k_RegisterIndex, /// A register index in one or more RegKind.
779 k_Token, /// A simple token
780 k_RegList, /// A physical register list
784 MipsOperand(KindTy K, MipsAsmParser &Parser)
785 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
787 ~MipsOperand() override {
796 case k_RegisterIndex:
803 /// For diagnostics, and checking the assembler temporary
804 MipsAsmParser &AsmParser;
812 unsigned Index; /// Index into the register class
813 RegKind Kind; /// Bitfield of the kinds it could possibly be
814 struct Token Tok; /// The input token this operand originated from.
815 const MCRegisterInfo *RegInfo;
828 SmallVector<unsigned, 10> *List;
833 struct RegIdxOp RegIdx;
836 struct RegListOp RegList;
839 SMLoc StartLoc, EndLoc;
841 /// Internal constructor for register kinds
842 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
844 const MCRegisterInfo *RegInfo,
846 MipsAsmParser &Parser) {
847 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
848 Op->RegIdx.Index = Index;
849 Op->RegIdx.RegInfo = RegInfo;
850 Op->RegIdx.Kind = RegKind;
851 Op->RegIdx.Tok.Data = Str.data();
852 Op->RegIdx.Tok.Length = Str.size();
859 /// Coerce the register to GPR32 and return the real register for the current
861 unsigned getGPR32Reg() const {
862 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
863 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
864 unsigned ClassID = Mips::GPR32RegClassID;
865 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
868 /// Coerce the register to GPR32 and return the real register for the current
870 unsigned getGPRMM16Reg() const {
871 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
872 unsigned ClassID = Mips::GPR32RegClassID;
873 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
876 /// Coerce the register to GPR64 and return the real register for the current
878 unsigned getGPR64Reg() const {
879 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
880 unsigned ClassID = Mips::GPR64RegClassID;
881 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
885 /// Coerce the register to AFGR64 and return the real register for the current
887 unsigned getAFGR64Reg() const {
888 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
889 if (RegIdx.Index % 2 != 0)
890 AsmParser.Warning(StartLoc, "Float register should be even.");
891 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
892 .getRegister(RegIdx.Index / 2);
895 /// Coerce the register to FGR64 and return the real register for the current
897 unsigned getFGR64Reg() const {
898 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
899 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
900 .getRegister(RegIdx.Index);
903 /// Coerce the register to FGR32 and return the real register for the current
905 unsigned getFGR32Reg() const {
906 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
907 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
908 .getRegister(RegIdx.Index);
911 /// Coerce the register to FCC and return the real register for the current
913 unsigned getFCCReg() const {
914 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
915 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
916 .getRegister(RegIdx.Index);
919 /// Coerce the register to MSA128 and return the real register for the current
921 unsigned getMSA128Reg() const {
922 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
923 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
925 unsigned ClassID = Mips::MSA128BRegClassID;
926 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
929 /// Coerce the register to MSACtrl and return the real register for the
931 unsigned getMSACtrlReg() const {
932 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
933 unsigned ClassID = Mips::MSACtrlRegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 /// Coerce the register to COP0 and return the real register for the
939 unsigned getCOP0Reg() const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
941 unsigned ClassID = Mips::COP0RegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 /// Coerce the register to COP2 and return the real register for the
947 unsigned getCOP2Reg() const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
949 unsigned ClassID = Mips::COP2RegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
953 /// Coerce the register to COP3 and return the real register for the
955 unsigned getCOP3Reg() const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
957 unsigned ClassID = Mips::COP3RegClassID;
958 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
961 /// Coerce the register to ACC64DSP and return the real register for the
963 unsigned getACC64DSPReg() const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
965 unsigned ClassID = Mips::ACC64DSPRegClassID;
966 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
969 /// Coerce the register to HI32DSP and return the real register for the
971 unsigned getHI32DSPReg() const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
973 unsigned ClassID = Mips::HI32DSPRegClassID;
974 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
977 /// Coerce the register to LO32DSP and return the real register for the
979 unsigned getLO32DSPReg() const {
980 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
981 unsigned ClassID = Mips::LO32DSPRegClassID;
982 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985 /// Coerce the register to CCR and return the real register for the
987 unsigned getCCRReg() const {
988 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
989 unsigned ClassID = Mips::CCRRegClassID;
990 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
993 /// Coerce the register to HWRegs and return the real register for the
995 unsigned getHWRegsReg() const {
996 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
997 unsigned ClassID = Mips::HWRegsRegClassID;
998 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1002 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1003 // Add as immediate when possible. Null MCExpr = 0.
1005 Inst.addOperand(MCOperand::createImm(0));
1006 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1007 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1009 Inst.addOperand(MCOperand::createExpr(Expr));
1012 void addRegOperands(MCInst &Inst, unsigned N) const {
1013 llvm_unreachable("Use a custom parser instead");
1016 /// Render the operand to an MCInst as a GPR32
1017 /// Asserts if the wrong number of operands are requested, or the operand
1018 /// is not a k_RegisterIndex compatible with RegKind_GPR
1019 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1020 assert(N == 1 && "Invalid number of operands!");
1021 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1024 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1025 assert(N == 1 && "Invalid number of operands!");
1026 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1029 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1030 assert(N == 1 && "Invalid number of operands!");
1031 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1034 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1035 assert(N == 1 && "Invalid number of operands!");
1036 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1039 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1040 assert(N == 1 && "Invalid number of operands!");
1041 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1044 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1045 assert(N == 1 && "Invalid number of operands!");
1046 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1049 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1050 assert(N == 1 && "Invalid number of operands!");
1051 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1054 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1056 assert(N == 1 && "Invalid number of operands!");
1057 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1060 /// Render the operand to an MCInst as a GPR64
1061 /// Asserts if the wrong number of operands are requested, or the operand
1062 /// is not a k_RegisterIndex compatible with RegKind_GPR
1063 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1064 assert(N == 1 && "Invalid number of operands!");
1065 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1068 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1069 assert(N == 1 && "Invalid number of operands!");
1070 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1073 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1074 assert(N == 1 && "Invalid number of operands!");
1075 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1078 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1079 assert(N == 1 && "Invalid number of operands!");
1080 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1083 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1084 assert(N == 1 && "Invalid number of operands!");
1085 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1088 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1089 assert(N == 1 && "Invalid number of operands!");
1090 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1091 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1092 // FIXME: This should propagate failure up to parseStatement.
1093 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1094 AsmParser.getParser().printError(
1095 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1099 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1100 assert(N == 1 && "Invalid number of operands!");
1101 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1102 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1103 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1104 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1108 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1109 assert(N == 1 && "Invalid number of operands!");
1110 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1113 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1114 assert(N == 1 && "Invalid number of operands!");
1115 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1118 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1119 assert(N == 1 && "Invalid number of operands!");
1120 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1123 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1124 assert(N == 1 && "Invalid number of operands!");
1125 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1128 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1129 assert(N == 1 && "Invalid number of operands!");
1130 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1133 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1134 assert(N == 1 && "Invalid number of operands!");
1135 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1138 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1139 assert(N == 1 && "Invalid number of operands!");
1140 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1143 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1144 assert(N == 1 && "Invalid number of operands!");
1145 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1148 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1149 assert(N == 1 && "Invalid number of operands!");
1150 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1153 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1154 assert(N == 1 && "Invalid number of operands!");
1155 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1158 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1159 assert(N == 1 && "Invalid number of operands!");
1160 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1163 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1164 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165 assert(N == 1 && "Invalid number of operands!");
1166 uint64_t Imm = getConstantImm() - Offset;
1167 Imm &= (1ULL << Bits) - 1;
1169 Imm += AdjustOffset;
1170 Inst.addOperand(MCOperand::createImm(Imm));
1173 template <unsigned Bits>
1174 void addSImmOperands(MCInst &Inst, unsigned N) const {
1175 if (isImm() && !isConstantImm()) {
1176 addExpr(Inst, getImm());
1179 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1182 template <unsigned Bits>
1183 void addUImmOperands(MCInst &Inst, unsigned N) const {
1184 if (isImm() && !isConstantImm()) {
1185 addExpr(Inst, getImm());
1188 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1191 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1192 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193 assert(N == 1 && "Invalid number of operands!");
1194 int64_t Imm = getConstantImm() - Offset;
1195 Imm = SignExtend64<Bits>(Imm);
1197 Imm += AdjustOffset;
1198 Inst.addOperand(MCOperand::createImm(Imm));
1201 void addImmOperands(MCInst &Inst, unsigned N) const {
1202 assert(N == 1 && "Invalid number of operands!");
1203 const MCExpr *Expr = getImm();
1204 addExpr(Inst, Expr);
1207 void addMemOperands(MCInst &Inst, unsigned N) const {
1208 assert(N == 2 && "Invalid number of operands!");
1210 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1211 ? getMemBase()->getGPR64Reg()
1212 : getMemBase()->getGPR32Reg()));
1214 const MCExpr *Expr = getMemOff();
1215 addExpr(Inst, Expr);
1218 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1219 assert(N == 2 && "Invalid number of operands!");
1221 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1223 const MCExpr *Expr = getMemOff();
1224 addExpr(Inst, Expr);
1227 void addRegListOperands(MCInst &Inst, unsigned N) const {
1228 assert(N == 1 && "Invalid number of operands!");
1230 for (auto RegNo : getRegList())
1231 Inst.addOperand(MCOperand::createReg(RegNo));
1234 bool isReg() const override {
1235 // As a special case until we sort out the definition of div/divu, accept
1236 // $0/$zero here so that MCK_ZERO works correctly.
1237 return isGPRAsmReg() && RegIdx.Index == 0;
1240 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1241 bool isImm() const override { return Kind == k_Immediate; }
1243 bool isConstantImm() const {
1245 return isImm() && getImm()->evaluateAsAbsolute(Res);
1248 bool isConstantImmz() const {
1249 return isConstantImm() && getConstantImm() == 0;
1252 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1256 template <unsigned Bits> bool isSImm() const {
1257 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1260 template <unsigned Bits> bool isUImm() const {
1261 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1264 template <unsigned Bits> bool isAnyImm() const {
1265 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1266 isUInt<Bits>(getConstantImm()))
1270 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1271 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1274 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1275 return isConstantImm() && getConstantImm() >= Bottom &&
1276 getConstantImm() <= Top;
1279 bool isToken() const override {
1280 // Note: It's not possible to pretend that other operand kinds are tokens.
1281 // The matcher emitter checks tokens first.
1282 return Kind == k_Token;
1285 bool isMem() const override { return Kind == k_Memory; }
1287 bool isConstantMemOff() const {
1288 return isMem() && isa<MCConstantExpr>(getMemOff());
1291 // Allow relocation operators.
1292 // FIXME: This predicate and others need to look through binary expressions
1293 // and determine whether a Value is a constant or not.
1294 template <unsigned Bits, unsigned ShiftAmount = 0>
1295 bool isMemWithSimmOffset() const {
1298 if (!getMemBase()->isGPRAsmReg())
1300 if (isa<MCTargetExpr>(getMemOff()) ||
1301 (isConstantMemOff() &&
1302 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1305 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1309 bool isMemWithPtrSizeOffset() const {
1312 if (!getMemBase()->isGPRAsmReg())
1314 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1315 if (isa<MCTargetExpr>(getMemOff()) ||
1316 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1319 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1320 return IsReloc && isIntN(PtrBits, Res.getConstant());
1323 bool isMemWithGRPMM16Base() const {
1324 return isMem() && getMemBase()->isMM16AsmReg();
1327 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1328 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1329 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1332 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1333 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1334 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1335 && (getMemBase()->getGPR32Reg() == Mips::SP);
1338 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1339 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1340 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1341 && (getMemBase()->getGPR32Reg() == Mips::GP);
1344 template <unsigned Bits, unsigned ShiftLeftAmount>
1345 bool isScaledUImm() const {
1346 return isConstantImm() &&
1347 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1350 template <unsigned Bits, unsigned ShiftLeftAmount>
1351 bool isScaledSImm() const {
1352 if (isConstantImm() &&
1353 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1355 // Operand can also be a symbol or symbol plus
1356 // offset in case of relocations.
1357 if (Kind != k_Immediate)
1360 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1361 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1364 bool isRegList16() const {
1368 int Size = RegList.List->size();
1369 if (Size < 2 || Size > 5)
1372 unsigned R0 = RegList.List->front();
1373 unsigned R1 = RegList.List->back();
1374 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1375 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1378 int PrevReg = *RegList.List->begin();
1379 for (int i = 1; i < Size - 1; i++) {
1380 int Reg = (*(RegList.List))[i];
1381 if ( Reg != PrevReg + 1)
1389 bool isInvNum() const { return Kind == k_Immediate; }
1391 bool isLSAImm() const {
1392 if (!isConstantImm())
1394 int64_t Val = getConstantImm();
1395 return 1 <= Val && Val <= 4;
1398 bool isRegList() const { return Kind == k_RegList; }
1400 StringRef getToken() const {
1401 assert(Kind == k_Token && "Invalid access!");
1402 return StringRef(Tok.Data, Tok.Length);
1405 unsigned getReg() const override {
1406 // As a special case until we sort out the definition of div/divu, accept
1407 // $0/$zero here so that MCK_ZERO works correctly.
1408 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1409 RegIdx.Kind & RegKind_GPR)
1410 return getGPR32Reg(); // FIXME: GPR64 too
1412 llvm_unreachable("Invalid access!");
1416 const MCExpr *getImm() const {
1417 assert((Kind == k_Immediate) && "Invalid access!");
1421 int64_t getConstantImm() const {
1422 const MCExpr *Val = getImm();
1424 (void)Val->evaluateAsAbsolute(Value);
1428 MipsOperand *getMemBase() const {
1429 assert((Kind == k_Memory) && "Invalid access!");
1433 const MCExpr *getMemOff() const {
1434 assert((Kind == k_Memory) && "Invalid access!");
1438 int64_t getConstantMemOff() const {
1439 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1442 const SmallVectorImpl<unsigned> &getRegList() const {
1443 assert((Kind == k_RegList) && "Invalid access!");
1444 return *(RegList.List);
1447 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1448 MipsAsmParser &Parser) {
1449 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1450 Op->Tok.Data = Str.data();
1451 Op->Tok.Length = Str.size();
1457 /// Create a numeric register (e.g. $1). The exact register remains
1458 /// unresolved until an instruction successfully matches
1459 static std::unique_ptr<MipsOperand>
1460 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1461 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1462 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1463 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1466 /// Create a register that is definitely a GPR.
1467 /// This is typically only used for named registers such as $gp.
1468 static std::unique_ptr<MipsOperand>
1469 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1470 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1471 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1474 /// Create a register that is definitely a FGR.
1475 /// This is typically only used for named registers such as $f0.
1476 static std::unique_ptr<MipsOperand>
1477 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1478 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1479 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1482 /// Create a register that is definitely a HWReg.
1483 /// This is typically only used for named registers such as $hwr_cpunum.
1484 static std::unique_ptr<MipsOperand>
1485 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1486 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1487 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1490 /// Create a register that is definitely an FCC.
1491 /// This is typically only used for named registers such as $fcc0.
1492 static std::unique_ptr<MipsOperand>
1493 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1494 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1495 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1498 /// Create a register that is definitely an ACC.
1499 /// This is typically only used for named registers such as $ac0.
1500 static std::unique_ptr<MipsOperand>
1501 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1502 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1503 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1506 /// Create a register that is definitely an MSA128.
1507 /// This is typically only used for named registers such as $w0.
1508 static std::unique_ptr<MipsOperand>
1509 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1510 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1511 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1514 /// Create a register that is definitely an MSACtrl.
1515 /// This is typically only used for named registers such as $msaaccess.
1516 static std::unique_ptr<MipsOperand>
1517 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1518 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1519 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1522 static std::unique_ptr<MipsOperand>
1523 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1524 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1531 static std::unique_ptr<MipsOperand>
1532 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1533 SMLoc E, MipsAsmParser &Parser) {
1534 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1535 Op->Mem.Base = Base.release();
1542 static std::unique_ptr<MipsOperand>
1543 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1544 MipsAsmParser &Parser) {
1545 assert(Regs.size() > 0 && "Empty list not allowed");
1547 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1548 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1549 Op->StartLoc = StartLoc;
1550 Op->EndLoc = EndLoc;
1554 bool isGPRZeroAsmReg() const {
1555 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1558 bool isGPRNonZeroAsmReg() const {
1559 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1563 bool isGPRAsmReg() const {
1564 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1567 bool isMM16AsmReg() const {
1568 if (!(isRegIdx() && RegIdx.Kind))
1570 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1571 || RegIdx.Index == 16 || RegIdx.Index == 17);
1574 bool isMM16AsmRegZero() const {
1575 if (!(isRegIdx() && RegIdx.Kind))
1577 return (RegIdx.Index == 0 ||
1578 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1579 RegIdx.Index == 17);
1582 bool isMM16AsmRegMoveP() const {
1583 if (!(isRegIdx() && RegIdx.Kind))
1585 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1586 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1589 bool isMM16AsmRegMovePPairFirst() const {
1590 if (!(isRegIdx() && RegIdx.Kind))
1592 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1595 bool isMM16AsmRegMovePPairSecond() const {
1596 if (!(isRegIdx() && RegIdx.Kind))
1598 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1599 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1602 bool isFGRAsmReg() const {
1603 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1604 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1607 bool isStrictlyFGRAsmReg() const {
1608 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1609 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1612 bool isHWRegsAsmReg() const {
1613 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1616 bool isCCRAsmReg() const {
1617 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1620 bool isFCCAsmReg() const {
1621 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1623 return RegIdx.Index <= 7;
1626 bool isACCAsmReg() const {
1627 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1630 bool isCOP0AsmReg() const {
1631 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1634 bool isCOP2AsmReg() const {
1635 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1638 bool isCOP3AsmReg() const {
1639 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1642 bool isMSA128AsmReg() const {
1643 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1646 bool isMSACtrlAsmReg() const {
1647 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1650 /// getStartLoc - Get the location of the first token of this operand.
1651 SMLoc getStartLoc() const override { return StartLoc; }
1652 /// getEndLoc - Get the location of the last token of this operand.
1653 SMLoc getEndLoc() const override { return EndLoc; }
1655 void print(raw_ostream &OS) const override {
1664 Mem.Base->print(OS);
1669 case k_RegisterIndex:
1670 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1671 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1678 for (auto Reg : (*RegList.List))
1685 bool isValidForTie(const MipsOperand &Other) const {
1686 if (Kind != Other.Kind)
1691 llvm_unreachable("Unexpected kind");
1693 case k_RegisterIndex: {
1694 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1695 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1696 return Token == OtherToken;
1700 }; // class MipsOperand
1702 } // end anonymous namespace
1706 extern const MCInstrDesc MipsInsts[];
1708 } // end namespace llvm
1710 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1711 return MipsInsts[Opcode];
1714 static bool hasShortDelaySlot(MCInst &Inst) {
1715 switch (Inst.getOpcode()) {
1722 case Mips::JRC16_MM:
1724 case Mips::JALRS_MM:
1725 case Mips::JALRS16_MM:
1726 case Mips::BGEZALS_MM:
1727 case Mips::BLTZALS_MM:
1730 return !Inst.getOperand(0).isReg();
1736 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1737 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1738 return &SRExpr->getSymbol();
1741 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1742 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1743 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1754 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1755 return getSingleMCSymbol(UExpr->getSubExpr());
1760 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1761 if (isa<MCSymbolRefExpr>(Expr))
1764 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1765 return countMCSymbolRefExpr(BExpr->getLHS()) +
1766 countMCSymbolRefExpr(BExpr->getRHS());
1768 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1769 return countMCSymbolRefExpr(UExpr->getSubExpr());
1774 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1776 const MCSubtargetInfo *STI) {
1777 MipsTargetStreamer &TOut = getTargetStreamer();
1778 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1779 bool ExpandedJalSym = false;
1783 if (MCID.isBranch() || MCID.isCall()) {
1784 const unsigned Opcode = Inst.getOpcode();
1794 assert(hasCnMips() && "instruction only valid for octeon cpus");
1801 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1802 Offset = Inst.getOperand(2);
1803 if (!Offset.isImm())
1804 break; // We'll deal with this situation later on when applying fixups.
1805 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1806 return Error(IDLoc, "branch target out of range");
1807 if (OffsetToAlignment(Offset.getImm(),
1808 1LL << (inMicroMipsMode() ? 1 : 2)))
1809 return Error(IDLoc, "branch to misaligned address");
1823 case Mips::BGEZAL_MM:
1824 case Mips::BLTZAL_MM:
1827 case Mips::BC1EQZC_MMR6:
1828 case Mips::BC1NEZC_MMR6:
1829 case Mips::BC2EQZC_MMR6:
1830 case Mips::BC2NEZC_MMR6:
1831 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1832 Offset = Inst.getOperand(1);
1833 if (!Offset.isImm())
1834 break; // We'll deal with this situation later on when applying fixups.
1835 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1836 return Error(IDLoc, "branch target out of range");
1837 if (OffsetToAlignment(Offset.getImm(),
1838 1LL << (inMicroMipsMode() ? 1 : 2)))
1839 return Error(IDLoc, "branch to misaligned address");
1841 case Mips::BGEC: case Mips::BGEC_MMR6:
1842 case Mips::BLTC: case Mips::BLTC_MMR6:
1843 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1844 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1845 case Mips::BEQC: case Mips::BEQC_MMR6:
1846 case Mips::BNEC: case Mips::BNEC_MMR6:
1847 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1848 Offset = Inst.getOperand(2);
1849 if (!Offset.isImm())
1850 break; // We'll deal with this situation later on when applying fixups.
1851 if (!isIntN(18, Offset.getImm()))
1852 return Error(IDLoc, "branch target out of range");
1853 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1854 return Error(IDLoc, "branch to misaligned address");
1856 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1857 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1858 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1859 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1860 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1861 Offset = Inst.getOperand(1);
1862 if (!Offset.isImm())
1863 break; // We'll deal with this situation later on when applying fixups.
1864 if (!isIntN(18, Offset.getImm()))
1865 return Error(IDLoc, "branch target out of range");
1866 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1867 return Error(IDLoc, "branch to misaligned address");
1869 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1870 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1871 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1872 Offset = Inst.getOperand(1);
1873 if (!Offset.isImm())
1874 break; // We'll deal with this situation later on when applying fixups.
1875 if (!isIntN(23, Offset.getImm()))
1876 return Error(IDLoc, "branch target out of range");
1877 if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1878 return Error(IDLoc, "branch to misaligned address");
1880 case Mips::BEQZ16_MM:
1881 case Mips::BEQZC16_MMR6:
1882 case Mips::BNEZ16_MM:
1883 case Mips::BNEZC16_MMR6:
1884 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1885 Offset = Inst.getOperand(1);
1886 if (!Offset.isImm())
1887 break; // We'll deal with this situation later on when applying fixups.
1888 if (!isInt<8>(Offset.getImm()))
1889 return Error(IDLoc, "branch target out of range");
1890 if (OffsetToAlignment(Offset.getImm(), 2LL))
1891 return Error(IDLoc, "branch to misaligned address");
1896 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1897 // We still accept it but it is a normal nop.
1898 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1899 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1900 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1905 const unsigned Opcode = Inst.getOpcode();
1917 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1918 // The offset is handled above
1919 Opnd = Inst.getOperand(1);
1921 return Error(IDLoc, "expected immediate operand kind");
1922 Imm = Opnd.getImm();
1923 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1924 Opcode == Mips::BBIT1 ? 63 : 31))
1925 return Error(IDLoc, "immediate operand value out of range");
1927 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1929 Inst.getOperand(1).setImm(Imm - 32);
1935 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1936 Opnd = Inst.getOperand(2);
1938 return Error(IDLoc, "expected immediate operand kind");
1939 Imm = Opnd.getImm();
1940 if (!isInt<10>(Imm))
1941 return Error(IDLoc, "immediate operand value out of range");
1946 // Warn on division by zero. We're checking here as all instructions get
1947 // processed here, not just the macros that need expansion.
1949 // The MIPS backend models most of the divison instructions and macros as
1950 // three operand instructions. The pre-R6 divide instructions however have
1951 // two operands and explicitly define HI/LO as part of the instruction,
1952 // not in the operands.
1953 unsigned FirstOp = 1;
1954 unsigned SecondOp = 2;
1955 switch (Inst.getOpcode()) {
1958 case Mips::SDivIMacro:
1959 case Mips::UDivIMacro:
1960 case Mips::DSDivIMacro:
1961 case Mips::DUDivIMacro:
1962 if (Inst.getOperand(2).getImm() == 0) {
1963 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1964 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1965 Warning(IDLoc, "dividing zero by zero");
1967 Warning(IDLoc, "division by zero");
1979 case Mips::SDivMacro:
1980 case Mips::DSDivMacro:
1981 case Mips::UDivMacro:
1982 case Mips::DUDivMacro:
1987 case Mips::DIVU_MMR6:
1988 case Mips::DIV_MMR6:
1989 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1990 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1991 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1992 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1993 Warning(IDLoc, "dividing zero by zero");
1995 Warning(IDLoc, "division by zero");
2000 // For PIC code convert unconditional jump to unconditional branch.
2001 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2004 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2005 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2006 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2007 BInst.addOperand(Inst.getOperand(0));
2011 // This expansion is not in a function called by tryExpandInstruction()
2012 // because the pseudo-instruction doesn't have a distinct opcode.
2013 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2015 warnIfNoMacro(IDLoc);
2017 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2019 // We can do this expansion if there's only 1 symbol in the argument
2021 if (countMCSymbolRefExpr(JalExpr) > 1)
2022 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2024 // FIXME: This is checking the expression can be handled by the later stages
2025 // of the assembler. We ought to leave it to those later stages.
2026 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2028 // FIXME: Add support for label+offset operands (currently causes an error).
2029 // FIXME: Add support for forward-declared local symbols.
2030 // FIXME: Add expansion for when the LargeGOT option is enabled.
2031 if (JalSym->isInSection() || JalSym->isTemporary() ||
2033 cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2035 // If it's a local symbol and the O32 ABI is being used, we expand to:
2037 // R_(MICRO)MIPS_GOT16 label
2038 // addiu $25, $25, 0
2039 // R_(MICRO)MIPS_LO16 label
2041 const MCExpr *Got16RelocExpr =
2042 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2043 const MCExpr *Lo16RelocExpr =
2044 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2046 TOut.emitRRX(Mips::LW, Mips::T9, GPReg,
2047 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2048 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2049 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2050 } else if (isABI_N32() || isABI_N64()) {
2051 // If it's a local symbol and the N32/N64 ABIs are being used,
2053 // lw/ld $25, 0($gp)
2054 // R_(MICRO)MIPS_GOT_DISP label
2056 const MCExpr *GotDispRelocExpr =
2057 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2059 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2060 GPReg, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2064 // If it's an external/weak symbol, we expand to:
2065 // lw/ld $25, 0($gp)
2066 // R_(MICRO)MIPS_CALL16 label
2068 const MCExpr *Call16RelocExpr =
2069 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2071 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, GPReg,
2072 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2076 if (IsCpRestoreSet && inMicroMipsMode())
2077 JalrInst.setOpcode(Mips::JALRS_MM);
2079 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2080 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2081 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2083 if (EmitJalrReloc) {
2084 // As an optimization hint for the linker, before the JALR we add:
2085 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2087 MCSymbol *TmpLabel = getContext().createTempSymbol();
2088 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2089 const MCExpr *RelocJalrExpr =
2090 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2091 getContext(), IDLoc);
2093 TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2094 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2095 RelocJalrExpr, IDLoc, *STI);
2096 TOut.getStreamer().EmitLabel(TmpLabel);
2100 ExpandedJalSym = true;
2103 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2104 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2105 // Check the offset of memory operand, if it is a symbol
2106 // reference or immediate we may have to expand instructions.
2107 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2108 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2109 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2110 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2111 MCOperand &Op = Inst.getOperand(i);
2113 int64_t MemOffset = Op.getImm();
2114 if (MemOffset < -32768 || MemOffset > 32767) {
2115 // Offset can't exceed 16bit value.
2116 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2117 return getParser().hasPendingError();
2119 } else if (Op.isExpr()) {
2120 const MCExpr *Expr = Op.getExpr();
2121 if (Expr->getKind() == MCExpr::SymbolRef) {
2122 const MCSymbolRefExpr *SR =
2123 static_cast<const MCSymbolRefExpr *>(Expr);
2124 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2126 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2127 return getParser().hasPendingError();
2129 } else if (!isEvaluated(Expr)) {
2130 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2131 return getParser().hasPendingError();
2138 if (inMicroMipsMode()) {
2139 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2140 // Try to create 16-bit GP relative load instruction.
2141 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2142 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2143 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2144 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2145 MCOperand &Op = Inst.getOperand(i);
2147 int MemOffset = Op.getImm();
2148 MCOperand &DstReg = Inst.getOperand(0);
2149 MCOperand &BaseReg = Inst.getOperand(1);
2150 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2151 getContext().getRegisterInfo()->getRegClass(
2152 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2153 (BaseReg.getReg() == Mips::GP ||
2154 BaseReg.getReg() == Mips::GP_64)) {
2156 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2165 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2170 switch (Inst.getOpcode()) {
2173 case Mips::ADDIUSP_MM:
2174 Opnd = Inst.getOperand(0);
2176 return Error(IDLoc, "expected immediate operand kind");
2177 Imm = Opnd.getImm();
2178 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2180 return Error(IDLoc, "immediate operand value out of range");
2182 case Mips::SLL16_MM:
2183 case Mips::SRL16_MM:
2184 Opnd = Inst.getOperand(2);
2186 return Error(IDLoc, "expected immediate operand kind");
2187 Imm = Opnd.getImm();
2188 if (Imm < 1 || Imm > 8)
2189 return Error(IDLoc, "immediate operand value out of range");
2192 Opnd = Inst.getOperand(1);
2194 return Error(IDLoc, "expected immediate operand kind");
2195 Imm = Opnd.getImm();
2196 if (Imm < -1 || Imm > 126)
2197 return Error(IDLoc, "immediate operand value out of range");
2199 case Mips::ADDIUR2_MM:
2200 Opnd = Inst.getOperand(2);
2202 return Error(IDLoc, "expected immediate operand kind");
2203 Imm = Opnd.getImm();
2204 if (!(Imm == 1 || Imm == -1 ||
2205 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2206 return Error(IDLoc, "immediate operand value out of range");
2208 case Mips::ANDI16_MM:
2209 Opnd = Inst.getOperand(2);
2211 return Error(IDLoc, "expected immediate operand kind");
2212 Imm = Opnd.getImm();
2213 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2214 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2215 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2216 return Error(IDLoc, "immediate operand value out of range");
2218 case Mips::LBU16_MM:
2219 Opnd = Inst.getOperand(2);
2221 return Error(IDLoc, "expected immediate operand kind");
2222 Imm = Opnd.getImm();
2223 if (Imm < -1 || Imm > 14)
2224 return Error(IDLoc, "immediate operand value out of range");
2227 case Mips::SB16_MMR6:
2228 Opnd = Inst.getOperand(2);
2230 return Error(IDLoc, "expected immediate operand kind");
2231 Imm = Opnd.getImm();
2232 if (Imm < 0 || Imm > 15)
2233 return Error(IDLoc, "immediate operand value out of range");
2235 case Mips::LHU16_MM:
2237 case Mips::SH16_MMR6:
2238 Opnd = Inst.getOperand(2);
2240 return Error(IDLoc, "expected immediate operand kind");
2241 Imm = Opnd.getImm();
2242 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2243 return Error(IDLoc, "immediate operand value out of range");
2247 case Mips::SW16_MMR6:
2248 Opnd = Inst.getOperand(2);
2250 return Error(IDLoc, "expected immediate operand kind");
2251 Imm = Opnd.getImm();
2252 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2253 return Error(IDLoc, "immediate operand value out of range");
2255 case Mips::ADDIUPC_MM:
2256 Opnd = Inst.getOperand(1);
2258 return Error(IDLoc, "expected immediate operand kind");
2259 Imm = Opnd.getImm();
2260 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2261 return Error(IDLoc, "immediate operand value out of range");
2265 if (Inst.getOperand(0).getReg() == Mips::RA)
2266 return Error(IDLoc, "invalid operand for instruction");
2268 case Mips::MOVEP_MM:
2269 case Mips::MOVEP_MMR6: {
2270 unsigned R0 = Inst.getOperand(0).getReg();
2271 unsigned R1 = Inst.getOperand(1).getReg();
2272 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2273 (R0 == Mips::A1 && R1 == Mips::A3) ||
2274 (R0 == Mips::A2 && R1 == Mips::A3) ||
2275 (R0 == Mips::A0 && R1 == Mips::S5) ||
2276 (R0 == Mips::A0 && R1 == Mips::S6) ||
2277 (R0 == Mips::A0 && R1 == Mips::A1) ||
2278 (R0 == Mips::A0 && R1 == Mips::A2) ||
2279 (R0 == Mips::A0 && R1 == Mips::A3));
2281 return Error(IDLoc, "invalid operand for instruction");
2287 bool FillDelaySlot =
2288 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2290 TOut.emitDirectiveSetNoReorder();
2292 MacroExpanderResultTy ExpandResult =
2293 tryExpandInstruction(Inst, IDLoc, Out, STI);
2294 switch (ExpandResult) {
2296 Out.EmitInstruction(Inst, *STI);
2304 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2305 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2306 if (inMicroMipsMode()) {
2307 TOut.setUsesMicroMips();
2308 TOut.updateABIInfo(*this);
2311 // If this instruction has a delay slot and .set reorder is active,
2312 // emit a NOP after it.
2313 if (FillDelaySlot) {
2314 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2315 TOut.emitDirectiveSetReorder();
2318 if ((Inst.getOpcode() == Mips::JalOneReg ||
2319 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2320 isPicAndNotNxxAbi()) {
2321 if (IsCpRestoreSet) {
2322 // We need a NOP between the JALR and the LW:
2323 // If .set reorder has been used, we've already emitted a NOP.
2324 // If .set noreorder has been used, we need to emit a NOP at this point.
2325 if (!AssemblerOptions.back()->isReorder())
2326 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2329 // Load the $gp from the stack.
2330 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2332 Warning(IDLoc, "no .cprestore used in PIC mode");
2338 MipsAsmParser::MacroExpanderResultTy
2339 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2340 const MCSubtargetInfo *STI) {
2341 switch (Inst.getOpcode()) {
2343 return MER_NotAMacro;
2344 case Mips::LoadImm32:
2345 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2346 case Mips::LoadImm64:
2347 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2348 case Mips::LoadAddrImm32:
2349 case Mips::LoadAddrImm64:
2350 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2351 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2352 "expected immediate operand kind");
2354 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2356 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2360 case Mips::LoadAddrReg32:
2361 case Mips::LoadAddrReg64:
2362 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2363 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2364 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2365 "expected immediate operand kind");
2367 return expandLoadAddress(Inst.getOperand(0).getReg(),
2368 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2369 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2373 case Mips::B_MM_Pseudo:
2374 case Mips::B_MMR6_Pseudo:
2375 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2379 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2381 case Mips::JalOneReg:
2382 case Mips::JalTwoReg:
2383 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2386 case Mips::BEQLImmMacro:
2387 case Mips::BNELImmMacro:
2388 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2405 case Mips::BLTImmMacro:
2406 case Mips::BLEImmMacro:
2407 case Mips::BGEImmMacro:
2408 case Mips::BGTImmMacro:
2409 case Mips::BLTUImmMacro:
2410 case Mips::BLEUImmMacro:
2411 case Mips::BGEUImmMacro:
2412 case Mips::BGTUImmMacro:
2413 case Mips::BLTLImmMacro:
2414 case Mips::BLELImmMacro:
2415 case Mips::BGELImmMacro:
2416 case Mips::BGTLImmMacro:
2417 case Mips::BLTULImmMacro:
2418 case Mips::BLEULImmMacro:
2419 case Mips::BGEULImmMacro:
2420 case Mips::BGTULImmMacro:
2421 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2422 case Mips::SDivMacro:
2423 case Mips::SDivIMacro:
2424 case Mips::SRemMacro:
2425 case Mips::SRemIMacro:
2426 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2428 case Mips::DSDivMacro:
2429 case Mips::DSDivIMacro:
2430 case Mips::DSRemMacro:
2431 case Mips::DSRemIMacro:
2432 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2434 case Mips::UDivMacro:
2435 case Mips::UDivIMacro:
2436 case Mips::URemMacro:
2437 case Mips::URemIMacro:
2438 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2440 case Mips::DUDivMacro:
2441 case Mips::DUDivIMacro:
2442 case Mips::DURemMacro:
2443 case Mips::DURemIMacro:
2444 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2446 case Mips::PseudoTRUNC_W_S:
2447 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2449 case Mips::PseudoTRUNC_W_D32:
2450 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2452 case Mips::PseudoTRUNC_W_D:
2453 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2456 case Mips::LoadImmSingleGPR:
2457 return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2460 case Mips::LoadImmSingleFGR:
2461 return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2464 case Mips::LoadImmDoubleGPR:
2465 return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2468 case Mips::LoadImmDoubleFGR:
2469 return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2472 case Mips::LoadImmDoubleFGR_32:
2473 return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2477 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2479 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2481 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2486 case Mips::NORImm64:
2487 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 case Mips::SGEImm64:
2494 case Mips::SGEUImm64:
2495 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2498 case Mips::SGTImm64:
2499 case Mips::SGTUImm64:
2500 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2501 case Mips::SLTImm64:
2502 if (isInt<16>(Inst.getOperand(2).getImm())) {
2503 Inst.setOpcode(Mips::SLTi64);
2504 return MER_NotAMacro;
2506 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2507 case Mips::SLTUImm64:
2508 if (isInt<16>(Inst.getOperand(2).getImm())) {
2509 Inst.setOpcode(Mips::SLTiu64);
2510 return MER_NotAMacro;
2512 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2513 case Mips::ADDi: case Mips::ADDi_MM:
2514 case Mips::ADDiu: case Mips::ADDiu_MM:
2515 case Mips::SLTi: case Mips::SLTi_MM:
2516 case Mips::SLTiu: case Mips::SLTiu_MM:
2517 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2518 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2519 int64_t ImmValue = Inst.getOperand(2).getImm();
2520 if (isInt<16>(ImmValue))
2521 return MER_NotAMacro;
2522 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2525 return MER_NotAMacro;
2526 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2527 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2528 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2529 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2530 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2531 int64_t ImmValue = Inst.getOperand(2).getImm();
2532 if (isUInt<16>(ImmValue))
2533 return MER_NotAMacro;
2534 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2537 return MER_NotAMacro;
2540 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2546 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2550 case Mips::ABSMacro:
2551 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 case Mips::MULImmMacro:
2553 case Mips::DMULImmMacro:
2554 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::MULOMacro:
2556 case Mips::DMULOMacro:
2557 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2558 case Mips::MULOUMacro:
2559 case Mips::DMULOUMacro:
2560 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2561 case Mips::DMULMacro:
2562 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2566 Inst.getOpcode() == Mips::LDMacro)
2570 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2573 case Mips::SEQMacro:
2574 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2575 case Mips::SEQIMacro:
2576 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 case Mips::MFTC0: case Mips::MTTC0:
2578 case Mips::MFTGPR: case Mips::MTTGPR:
2579 case Mips::MFTLO: case Mips::MTTLO:
2580 case Mips::MFTHI: case Mips::MTTHI:
2581 case Mips::MFTACX: case Mips::MTTACX:
2582 case Mips::MFTDSP: case Mips::MTTDSP:
2583 case Mips::MFTC1: case Mips::MTTC1:
2584 case Mips::MFTHC1: case Mips::MTTHC1:
2585 case Mips::CFTC1: case Mips::CTTC1:
2586 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2590 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2592 const MCSubtargetInfo *STI) {
2593 MipsTargetStreamer &TOut = getTargetStreamer();
2595 // Create a JALR instruction which is going to replace the pseudo-JAL.
2597 JalrInst.setLoc(IDLoc);
2598 const MCOperand FirstRegOp = Inst.getOperand(0);
2599 const unsigned Opcode = Inst.getOpcode();
2601 if (Opcode == Mips::JalOneReg) {
2602 // jal $rs => jalr $rs
2603 if (IsCpRestoreSet && inMicroMipsMode()) {
2604 JalrInst.setOpcode(Mips::JALRS16_MM);
2605 JalrInst.addOperand(FirstRegOp);
2606 } else if (inMicroMipsMode()) {
2607 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2608 JalrInst.addOperand(FirstRegOp);
2610 JalrInst.setOpcode(Mips::JALR);
2611 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2612 JalrInst.addOperand(FirstRegOp);
2614 } else if (Opcode == Mips::JalTwoReg) {
2615 // jal $rd, $rs => jalr $rd, $rs
2616 if (IsCpRestoreSet && inMicroMipsMode())
2617 JalrInst.setOpcode(Mips::JALRS_MM);
2619 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2620 JalrInst.addOperand(FirstRegOp);
2621 const MCOperand SecondRegOp = Inst.getOperand(1);
2622 JalrInst.addOperand(SecondRegOp);
2624 Out.EmitInstruction(JalrInst, *STI);
2626 // If .set reorder is active and branch instruction has a delay slot,
2627 // emit a NOP after it.
2628 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2629 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2630 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2636 /// Can the value be represented by a unsigned N-bit value and a shift left?
2637 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2638 unsigned BitNum = findFirstSet(x);
2640 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2643 /// Load (or add) an immediate into a register.
2645 /// @param ImmValue The immediate to load.
2646 /// @param DstReg The register that will hold the immediate.
2647 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2648 /// for a simple initialization.
2649 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2650 /// @param IsAddress True if the immediate represents an address. False if it
2652 /// @param IDLoc Location of the immediate in the source file.
2653 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2654 unsigned SrcReg, bool Is32BitImm,
2655 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2656 const MCSubtargetInfo *STI) {
2657 MipsTargetStreamer &TOut = getTargetStreamer();
2659 if (!Is32BitImm && !isGP64bit()) {
2660 Error(IDLoc, "instruction requires a 64-bit architecture");
2665 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2666 // Sign extend up to 64-bit so that the predicates match the hardware
2667 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2669 ImmValue = SignExtend64<32>(ImmValue);
2671 Error(IDLoc, "instruction requires a 32-bit immediate");
2676 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2677 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2679 bool UseSrcReg = false;
2680 if (SrcReg != Mips::NoRegister)
2683 unsigned TmpReg = DstReg;
2685 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2686 // At this point we need AT to perform the expansions and we exit if it is
2688 unsigned ATReg = getATReg(IDLoc);
2694 if (isInt<16>(ImmValue)) {
2698 // This doesn't quite follow the usual ABI expectations for N32 but matches
2699 // traditional assembler behaviour. N32 would normally use addiu for both
2700 // integers and addresses.
2701 if (IsAddress && !Is32BitImm) {
2702 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2706 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2710 if (isUInt<16>(ImmValue)) {
2711 unsigned TmpReg = DstReg;
2712 if (SrcReg == DstReg) {
2713 TmpReg = getATReg(IDLoc);
2718 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2720 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2724 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2725 warnIfNoMacro(IDLoc);
2727 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2728 uint16_t Bits15To0 = ImmValue & 0xffff;
2729 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2730 // Traditional behaviour seems to special case this particular value. It's
2731 // not clear why other masks are handled differently.
2732 if (ImmValue == 0xffffffff) {
2733 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2734 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2736 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2740 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2742 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2743 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2745 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2747 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2751 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2753 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2755 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2759 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2761 Error(IDLoc, "instruction requires a 32-bit immediate");
2765 // Traditionally, these immediates are shifted as little as possible and as
2766 // such we align the most significant bit to bit 15 of our temporary.
2767 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2768 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2769 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2770 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2771 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2772 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2775 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2780 warnIfNoMacro(IDLoc);
2782 // The remaining case is packed with a sequence of dsll and ori with zeros
2783 // being omitted and any neighbouring dsll's being coalesced.
2784 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2786 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2787 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2791 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2792 // skip it and defer the shift to the next chunk.
2793 unsigned ShiftCarriedForwards = 16;
2794 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2795 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2797 if (ImmChunk != 0) {
2798 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2799 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2800 ShiftCarriedForwards = 0;
2803 ShiftCarriedForwards += 16;
2805 ShiftCarriedForwards -= 16;
2807 // Finish any remaining shifts left by trailing zeros.
2808 if (ShiftCarriedForwards)
2809 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2812 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2817 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2818 MCStreamer &Out, const MCSubtargetInfo *STI) {
2819 const MCOperand &ImmOp = Inst.getOperand(1);
2820 assert(ImmOp.isImm() && "expected immediate operand kind");
2821 const MCOperand &DstRegOp = Inst.getOperand(0);
2822 assert(DstRegOp.isReg() && "expected register operand kind");
2824 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2825 Is32BitImm, false, IDLoc, Out, STI))
2831 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2832 const MCOperand &Offset,
2833 bool Is32BitAddress, SMLoc IDLoc,
2835 const MCSubtargetInfo *STI) {
2836 // la can't produce a usable address when addresses are 64-bit.
2837 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2838 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2839 // We currently can't do this because we depend on the equality
2840 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2841 Error(IDLoc, "la used to load 64-bit address");
2842 // Continue as if we had 'dla' instead.
2843 Is32BitAddress = false;
2847 // dla requires 64-bit addresses.
2848 if (!Is32BitAddress && !hasMips3()) {
2849 Error(IDLoc, "instruction requires a 64-bit architecture");
2853 if (!Offset.isImm())
2854 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2855 Is32BitAddress, IDLoc, Out, STI);
2857 if (!ABI.ArePtrs64bit()) {
2858 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2859 Is32BitAddress = true;
2862 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2866 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2867 unsigned DstReg, unsigned SrcReg,
2868 bool Is32BitSym, SMLoc IDLoc,
2870 const MCSubtargetInfo *STI) {
2871 // FIXME: These expansions do not respect -mxgot.
2872 MipsTargetStreamer &TOut = getTargetStreamer();
2873 bool UseSrcReg = SrcReg != Mips::NoRegister;
2874 warnIfNoMacro(IDLoc);
2876 if (inPicMode() && ABI.IsO32()) {
2878 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2879 Error(IDLoc, "expected relocatable expression");
2882 if (Res.getSymB() != nullptr) {
2883 Error(IDLoc, "expected relocatable expression with only one symbol");
2887 // The case where the result register is $25 is somewhat special. If the
2888 // symbol in the final relocation is external and not modified with a
2889 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2890 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2891 Res.getConstant() == 0 &&
2892 !(Res.getSymA()->getSymbol().isInSection() ||
2893 Res.getSymA()->getSymbol().isTemporary() ||
2894 (Res.getSymA()->getSymbol().isELF() &&
2895 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2897 const MCExpr *CallExpr =
2898 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2899 TOut.emitRRX(Mips::LW, DstReg, GPReg, MCOperand::createExpr(CallExpr),
2904 // The remaining cases are:
2905 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2906 // >addiu $tmp, $tmp, %lo(offset)
2907 // >addiu $rd, $tmp, $rs
2908 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2909 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2910 // >addiu $rd, $tmp, $rs
2911 // The addiu's marked with a '>' may be omitted if they are redundant. If
2912 // this happens then the last instruction must use $rd as the result
2914 const MipsMCExpr *GotExpr =
2915 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2916 const MCExpr *LoExpr = nullptr;
2917 if (Res.getSymA()->getSymbol().isInSection() ||
2918 Res.getSymA()->getSymbol().isTemporary())
2919 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2920 else if (Res.getConstant() != 0) {
2921 // External symbols fully resolve the symbol with just the %got(symbol)
2922 // but we must still account for any offset to the symbol for expressions
2924 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2927 unsigned TmpReg = DstReg;
2929 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2931 // If $rs is the same as $rd, we need to use AT.
2932 // If it is not available we exit.
2933 unsigned ATReg = getATReg(IDLoc);
2939 TOut.emitRRX(Mips::LW, TmpReg, GPReg, MCOperand::createExpr(GotExpr), IDLoc,
2943 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2947 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2952 if (inPicMode() && ABI.ArePtrs64bit()) {
2954 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2955 Error(IDLoc, "expected relocatable expression");
2958 if (Res.getSymB() != nullptr) {
2959 Error(IDLoc, "expected relocatable expression with only one symbol");
2963 // The case where the result register is $25 is somewhat special. If the
2964 // symbol in the final relocation is external and not modified with a
2965 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2966 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2967 Res.getConstant() == 0 &&
2968 !(Res.getSymA()->getSymbol().isInSection() ||
2969 Res.getSymA()->getSymbol().isTemporary() ||
2970 (Res.getSymA()->getSymbol().isELF() &&
2971 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2973 const MCExpr *CallExpr =
2974 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2975 TOut.emitRRX(Mips::LD, DstReg, GPReg, MCOperand::createExpr(CallExpr),
2980 // The remaining cases are:
2981 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2982 // >daddiu $tmp, $tmp, offset
2983 // >daddu $rd, $tmp, $rs
2984 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2985 // this happens then the last instruction must use $rd as the result
2987 const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2990 const MCExpr *LoExpr = nullptr;
2991 if (Res.getConstant() != 0) {
2992 // Symbols fully resolve with just the %got_disp(symbol) but we
2993 // must still account for any offset to the symbol for
2994 // expressions like symbol+8.
2995 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2997 // FIXME: Offsets greater than 16 bits are not yet implemented.
2998 // FIXME: The correct range is a 32-bit sign-extended number.
2999 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3000 Error(IDLoc, "macro instruction uses large offset, which is not "
3001 "currently supported");
3006 unsigned TmpReg = DstReg;
3008 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3010 // If $rs is the same as $rd, we need to use AT.
3011 // If it is not available we exit.
3012 unsigned ATReg = getATReg(IDLoc);
3018 TOut.emitRRX(Mips::LD, TmpReg, GPReg, MCOperand::createExpr(GotExpr), IDLoc,
3022 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3026 TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3031 const MipsMCExpr *HiExpr =
3032 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3033 const MipsMCExpr *LoExpr =
3034 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3036 // This is the 64-bit symbol address expansion.
3037 if (ABI.ArePtrs64bit() && isGP64bit()) {
3038 // We need AT for the 64-bit expansion in the cases where the optional
3039 // source register is the destination register and for the superscalar
3042 // If it is not available we exit if the destination is the same as the
3045 const MipsMCExpr *HighestExpr =
3046 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3047 const MipsMCExpr *HigherExpr =
3048 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3051 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3053 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3054 unsigned ATReg = getATReg(IDLoc);
3056 // If $rs is the same as $rd:
3057 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3058 // daddiu $at, $at, %higher(sym)
3059 // dsll $at, $at, 16
3060 // daddiu $at, $at, %hi(sym)
3061 // dsll $at, $at, 16
3062 // daddiu $at, $at, %lo(sym)
3063 // daddu $rd, $at, $rd
3064 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3066 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3067 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3068 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3069 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3071 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3072 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3074 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3077 } else if (canUseATReg() && !RdRegIsRsReg) {
3078 unsigned ATReg = getATReg(IDLoc);
3080 // If the $rs is different from $rd or if $rs isn't specified and we
3081 // have $at available:
3082 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3083 // lui $at, %hi(sym)
3084 // daddiu $rd, $rd, %higher(sym)
3085 // daddiu $at, $at, %lo(sym)
3086 // dsll32 $rd, $rd, 0
3087 // daddu $rd, $rd, $at
3088 // (daddu $rd, $rd, $rs)
3090 // Which is preferred for superscalar issue.
3091 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3093 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3094 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3095 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3096 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3098 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3099 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3101 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3104 } else if (!canUseATReg() && !RdRegIsRsReg) {
3105 // Otherwise, synthesize the address in the destination register
3107 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3108 // daddiu $rd, $rd, %higher(sym)
3109 // dsll $rd, $rd, 16
3110 // daddiu $rd, $rd, %hi(sym)
3111 // dsll $rd, $rd, 16
3112 // daddiu $rd, $rd, %lo(sym)
3113 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3115 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3116 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3117 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3118 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3119 MCOperand::createExpr(HiExpr), IDLoc, STI);
3120 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3121 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3122 MCOperand::createExpr(LoExpr), IDLoc, STI);
3124 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3128 // We have a case where SrcReg == DstReg and we don't have $at
3129 // available. We can't expand this case, so error out appropriately.
3130 assert(SrcReg == DstReg && !canUseATReg() &&
3131 "Could have expanded dla but didn't?");
3132 reportParseError(IDLoc,
3133 "pseudo-instruction requires $at, which is not available");
3138 // And now, the 32-bit symbol address expansion:
3139 // If $rs is the same as $rd:
3140 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3141 // ori $at, $at, %lo(sym)
3142 // addu $rd, $at, $rd
3143 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3144 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3145 // ori $rd, $rd, %lo(sym)
3146 // (addu $rd, $rd, $rs)
3147 unsigned TmpReg = DstReg;
3149 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3150 // If $rs is the same as $rd, we need to use AT.
3151 // If it is not available we exit.
3152 unsigned ATReg = getATReg(IDLoc);
3158 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3159 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3163 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3166 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3171 // Each double-precision register DO-D15 overlaps with two of the single
3172 // precision registers F0-F31. As an example, all of the following hold true:
3173 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3174 static unsigned nextReg(unsigned Reg) {
3175 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3176 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3178 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3179 case Mips::ZERO: return Mips::AT;
3180 case Mips::AT: return Mips::V0;
3181 case Mips::V0: return Mips::V1;
3182 case Mips::V1: return Mips::A0;
3183 case Mips::A0: return Mips::A1;
3184 case Mips::A1: return Mips::A2;
3185 case Mips::A2: return Mips::A3;
3186 case Mips::A3: return Mips::T0;
3187 case Mips::T0: return Mips::T1;
3188 case Mips::T1: return Mips::T2;
3189 case Mips::T2: return Mips::T3;
3190 case Mips::T3: return Mips::T4;
3191 case Mips::T4: return Mips::T5;
3192 case Mips::T5: return Mips::T6;
3193 case Mips::T6: return Mips::T7;
3194 case Mips::T7: return Mips::S0;
3195 case Mips::S0: return Mips::S1;
3196 case Mips::S1: return Mips::S2;
3197 case Mips::S2: return Mips::S3;
3198 case Mips::S3: return Mips::S4;
3199 case Mips::S4: return Mips::S5;
3200 case Mips::S5: return Mips::S6;
3201 case Mips::S6: return Mips::S7;
3202 case Mips::S7: return Mips::T8;
3203 case Mips::T8: return Mips::T9;
3204 case Mips::T9: return Mips::K0;
3205 case Mips::K0: return Mips::K1;
3206 case Mips::K1: return Mips::GP;
3207 case Mips::GP: return Mips::SP;
3208 case Mips::SP: return Mips::FP;
3209 case Mips::FP: return Mips::RA;
3210 case Mips::RA: return Mips::ZERO;
3211 case Mips::D0: return Mips::F1;
3212 case Mips::D1: return Mips::F3;
3213 case Mips::D2: return Mips::F5;
3214 case Mips::D3: return Mips::F7;
3215 case Mips::D4: return Mips::F9;
3216 case Mips::D5: return Mips::F11;
3217 case Mips::D6: return Mips::F13;
3218 case Mips::D7: return Mips::F15;
3219 case Mips::D8: return Mips::F17;
3220 case Mips::D9: return Mips::F19;
3221 case Mips::D10: return Mips::F21;
3222 case Mips::D11: return Mips::F23;
3223 case Mips::D12: return Mips::F25;
3224 case Mips::D13: return Mips::F27;
3225 case Mips::D14: return Mips::F29;
3226 case Mips::D15: return Mips::F31;
3230 // FIXME: This method is too general. In principle we should compute the number
3231 // of instructions required to synthesize the immediate inline compared to
3232 // synthesizing the address inline and relying on non .text sections.
3233 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3234 // likely to yield a much larger benefit as we have to synthesize a 64bit
3235 // address to load a 64 bit value.
3236 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3238 unsigned ATReg = getATReg(IDLoc);
3243 const MCExpr *GotSym =
3244 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3245 const MipsMCExpr *GotExpr =
3246 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3248 if(isABI_O32() || isABI_N32()) {
3249 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3251 } else { //isABI_N64()
3252 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3255 } else { //!IsPicEnabled
3256 const MCExpr *HiSym =
3257 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3258 const MipsMCExpr *HiExpr =
3259 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3261 // FIXME: This is technically correct but gives a different result to gas,
3262 // but gas is incomplete there (it has a fixme noting it doesn't work with
3263 // 64-bit addresses).
3264 // FIXME: With -msym32 option, the address expansion for N64 should probably
3265 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3266 // symbol's value is considered sign extended.
3267 if(isABI_O32() || isABI_N32()) {
3268 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3269 } else { //isABI_N64()
3270 const MCExpr *HighestSym =
3271 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3272 const MipsMCExpr *HighestExpr =
3273 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3274 const MCExpr *HigherSym =
3275 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3276 const MipsMCExpr *HigherExpr =
3277 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3279 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3281 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3282 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3283 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3284 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3286 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3292 bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3293 bool Is64FPU, SMLoc IDLoc,
3295 const MCSubtargetInfo *STI) {
3296 MipsTargetStreamer &TOut = getTargetStreamer();
3297 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3298 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3299 "Invalid instruction operand.");
3301 unsigned FirstReg = Inst.getOperand(0).getReg();
3302 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3304 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3305 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3306 // exponent field), convert it to double (e.g. 1 to 1.0)
3307 if ((HiImmOp64 & 0x7ff00000) == 0) {
3308 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3309 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3312 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3313 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3316 // Conversion of a double in an uint64_t to a float in a uint32_t,
3317 // retaining the bit pattern of a float.
3319 double doubleImm = BitsToDouble(ImmOp64);
3320 float tmp_float = static_cast<float>(doubleImm);
3321 ImmOp32 = FloatToBits(tmp_float);
3324 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3329 unsigned ATReg = getATReg(IDLoc);
3332 if (LoImmOp64 == 0) {
3333 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3336 TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3340 MCSection *CS = getStreamer().getCurrentSectionOnly();
3341 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3342 // where appropriate.
3343 MCSection *ReadOnlySection = getContext().getELFSection(
3344 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3346 MCSymbol *Sym = getContext().createTempSymbol();
3347 const MCExpr *LoSym =
3348 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3349 const MipsMCExpr *LoExpr =
3350 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3352 getStreamer().SwitchSection(ReadOnlySection);
3353 getStreamer().EmitLabel(Sym, IDLoc);
3354 getStreamer().EmitIntValue(ImmOp32, 4);
3355 getStreamer().SwitchSection(CS);
3357 if(emitPartialAddress(TOut, IDLoc, Sym))
3359 TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3360 MCOperand::createExpr(LoExpr), IDLoc, STI);
3366 unsigned ATReg = getATReg(IDLoc);
3371 if (LoImmOp64 == 0) {
3372 if(isABI_N32() || isABI_N64()) {
3373 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3378 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3382 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3389 MCSection *CS = getStreamer().getCurrentSectionOnly();
3390 MCSection *ReadOnlySection = getContext().getELFSection(
3391 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3393 MCSymbol *Sym = getContext().createTempSymbol();
3394 const MCExpr *LoSym =
3395 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3396 const MipsMCExpr *LoExpr =
3397 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3399 getStreamer().SwitchSection(ReadOnlySection);
3400 getStreamer().EmitLabel(Sym, IDLoc);
3401 getStreamer().EmitIntValue(HiImmOp64, 4);
3402 getStreamer().EmitIntValue(LoImmOp64, 4);
3403 getStreamer().SwitchSection(CS);
3405 if(emitPartialAddress(TOut, IDLoc, Sym))
3408 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3409 MCOperand::createExpr(LoExpr), IDLoc, STI);
3411 TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3412 MCOperand::createExpr(LoExpr), IDLoc, STI);
3414 if(isABI_N32() || isABI_N64())
3415 TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3417 TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3418 TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3421 } else { // if(!IsGPR && !IsSingle)
3422 if ((LoImmOp64 == 0) &&
3423 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3424 // FIXME: In the case where the constant is zero, we can load the
3425 // register directly from the zero register.
3426 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3429 if (isABI_N32() || isABI_N64())
3430 TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3431 else if (hasMips32r2()) {
3432 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3433 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3435 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3436 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3441 MCSection *CS = getStreamer().getCurrentSectionOnly();
3442 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3443 // where appropriate.
3444 MCSection *ReadOnlySection = getContext().getELFSection(
3445 ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3447 MCSymbol *Sym = getContext().createTempSymbol();
3448 const MCExpr *LoSym =
3449 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3450 const MipsMCExpr *LoExpr =
3451 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3453 getStreamer().SwitchSection(ReadOnlySection);
3454 getStreamer().EmitLabel(Sym, IDLoc);
3455 getStreamer().EmitIntValue(HiImmOp64, 4);
3456 getStreamer().EmitIntValue(LoImmOp64, 4);
3457 getStreamer().SwitchSection(CS);
3459 if(emitPartialAddress(TOut, IDLoc, Sym))
3461 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3462 MCOperand::createExpr(LoExpr), IDLoc, STI);
3467 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3469 const MCSubtargetInfo *STI) {
3470 MipsTargetStreamer &TOut = getTargetStreamer();
3472 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3473 "unexpected number of operands");
3475 MCOperand Offset = Inst.getOperand(0);
3476 if (Offset.isExpr()) {
3478 Inst.setOpcode(Mips::BEQ_MM);
3479 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3480 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3481 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3483 assert(Offset.isImm() && "expected immediate operand kind");
3484 if (isInt<11>(Offset.getImm())) {
3485 // If offset fits into 11 bits then this instruction becomes microMIPS
3486 // 16-bit unconditional branch instruction.
3487 if (inMicroMipsMode())
3488 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3490 if (!isInt<17>(Offset.getImm()))
3491 return Error(IDLoc, "branch target out of range");
3492 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3493 return Error(IDLoc, "branch to misaligned address");
3495 Inst.setOpcode(Mips::BEQ_MM);
3496 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3497 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3498 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3501 Out.EmitInstruction(Inst, *STI);
3503 // If .set reorder is active and branch instruction has a delay slot,
3504 // emit a NOP after it.
3505 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3506 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3507 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3512 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3513 const MCSubtargetInfo *STI) {
3514 MipsTargetStreamer &TOut = getTargetStreamer();
3515 const MCOperand &DstRegOp = Inst.getOperand(0);
3516 assert(DstRegOp.isReg() && "expected register operand kind");
3518 const MCOperand &ImmOp = Inst.getOperand(1);
3519 assert(ImmOp.isImm() && "expected immediate operand kind");
3521 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3522 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3523 "expected immediate or expression operand");
3525 bool IsLikely = false;
3527 unsigned OpCode = 0;
3528 switch(Inst.getOpcode()) {
3535 case Mips::BEQLImmMacro:
3536 OpCode = Mips::BEQL;
3539 case Mips::BNELImmMacro:
3540 OpCode = Mips::BNEL;
3544 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3548 int64_t ImmValue = ImmOp.getImm();
3549 if (ImmValue == 0) {
3551 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3552 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3553 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3555 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3558 warnIfNoMacro(IDLoc);
3560 unsigned ATReg = getATReg(IDLoc);
3564 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3569 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3570 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3571 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3573 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3578 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3579 const MCSubtargetInfo *STI, bool IsLoad) {
3580 const MCOperand &DstRegOp = Inst.getOperand(0);
3581 assert(DstRegOp.isReg() && "expected register operand kind");
3582 const MCOperand &BaseRegOp = Inst.getOperand(1);
3583 assert(BaseRegOp.isReg() && "expected register operand kind");
3584 const MCOperand &OffsetOp = Inst.getOperand(2);
3586 MipsTargetStreamer &TOut = getTargetStreamer();
3587 unsigned DstReg = DstRegOp.getReg();
3588 unsigned BaseReg = BaseRegOp.getReg();
3589 unsigned TmpReg = DstReg;
3591 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3592 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3593 unsigned DstRegClassID =
3594 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3595 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3596 (DstRegClassID == Mips::GPR64RegClassID);
3598 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3599 // At this point we need AT to perform the expansions
3600 // and we exit if it is not available.
3601 TmpReg = getATReg(IDLoc);
3606 if (OffsetOp.isImm()) {
3607 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3608 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3610 // If msb of LoOffset is 1(negative number) we must increment
3611 // HiOffset to account for the sign-extension of the low part.
3612 if (LoOffset & 0x8000)
3613 HiOffset += 0x10000;
3615 bool IsLargeOffset = HiOffset != 0;
3617 if (IsLargeOffset) {
3618 bool Is32BitImm = (HiOffset >> 32) == 0;
3619 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3624 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3625 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3626 BaseReg, IDLoc, STI);
3627 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3631 assert(OffsetOp.isExpr() && "expected expression operand kind");
3634 // a) Fix lw/sw $reg, symbol($reg) instruction expanding.
3635 // b) If expression includes offset (sym + number), do not
3636 // encode the offset into a relocation. Take it in account
3637 // in the last load/store instruction.
3638 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3639 // do not exceed 16-bit.
3640 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3641 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3643 expandLoadAddress(TmpReg, Mips::NoRegister, OffsetOp, !ABI.ArePtrs64bit(),
3645 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, 0, IDLoc, STI);
3647 const MCExpr *ExprOffset = OffsetOp.getExpr();
3648 MCOperand LoOperand = MCOperand::createExpr(
3649 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3650 MCOperand HiOperand = MCOperand::createExpr(
3651 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3654 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3655 LoOperand, TmpReg, IDLoc, STI);
3657 TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3658 LoOperand, TmpReg, IDLoc, STI);
3662 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3664 const MCSubtargetInfo *STI) {
3665 unsigned OpNum = Inst.getNumOperands();
3666 unsigned Opcode = Inst.getOpcode();
3667 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3669 assert(Inst.getOperand(OpNum - 1).isImm() &&
3670 Inst.getOperand(OpNum - 2).isReg() &&
3671 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3673 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3674 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3675 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3676 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3677 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3678 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3679 // It can be implemented as SWM16 or LWM16 instruction.
3680 if (inMicroMipsMode() && hasMips32r6())
3681 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3683 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3686 Inst.setOpcode(NewOpcode);
3687 Out.EmitInstruction(Inst, *STI);
3691 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3693 const MCSubtargetInfo *STI) {
3694 MipsTargetStreamer &TOut = getTargetStreamer();
3695 bool EmittedNoMacroWarning = false;
3696 unsigned PseudoOpcode = Inst.getOpcode();
3697 unsigned SrcReg = Inst.getOperand(0).getReg();
3698 const MCOperand &TrgOp = Inst.getOperand(1);
3699 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3701 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3702 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3706 TrgReg = TrgOp.getReg();
3707 else if (TrgOp.isImm()) {
3708 warnIfNoMacro(IDLoc);
3709 EmittedNoMacroWarning = true;
3711 TrgReg = getATReg(IDLoc);
3715 switch(PseudoOpcode) {
3717 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3718 case Mips::BLTImmMacro:
3719 PseudoOpcode = Mips::BLT;
3721 case Mips::BLEImmMacro:
3722 PseudoOpcode = Mips::BLE;
3724 case Mips::BGEImmMacro:
3725 PseudoOpcode = Mips::BGE;
3727 case Mips::BGTImmMacro:
3728 PseudoOpcode = Mips::BGT;
3730 case Mips::BLTUImmMacro:
3731 PseudoOpcode = Mips::BLTU;
3733 case Mips::BLEUImmMacro:
3734 PseudoOpcode = Mips::BLEU;
3736 case Mips::BGEUImmMacro:
3737 PseudoOpcode = Mips::BGEU;
3739 case Mips::BGTUImmMacro:
3740 PseudoOpcode = Mips::BGTU;
3742 case Mips::BLTLImmMacro:
3743 PseudoOpcode = Mips::BLTL;
3745 case Mips::BLELImmMacro:
3746 PseudoOpcode = Mips::BLEL;
3748 case Mips::BGELImmMacro:
3749 PseudoOpcode = Mips::BGEL;
3751 case Mips::BGTLImmMacro:
3752 PseudoOpcode = Mips::BGTL;
3754 case Mips::BLTULImmMacro:
3755 PseudoOpcode = Mips::BLTUL;
3757 case Mips::BLEULImmMacro:
3758 PseudoOpcode = Mips::BLEUL;
3760 case Mips::BGEULImmMacro:
3761 PseudoOpcode = Mips::BGEUL;
3763 case Mips::BGTULImmMacro:
3764 PseudoOpcode = Mips::BGTUL;
3768 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3769 false, IDLoc, Out, STI))
3773 switch (PseudoOpcode) {
3778 AcceptsEquality = false;
3779 ReverseOrderSLT = false;
3781 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3782 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3783 ZeroSrcOpcode = Mips::BGTZ;
3784 ZeroTrgOpcode = Mips::BLTZ;
3790 AcceptsEquality = true;
3791 ReverseOrderSLT = true;
3793 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3794 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3795 ZeroSrcOpcode = Mips::BGEZ;
3796 ZeroTrgOpcode = Mips::BLEZ;
3802 AcceptsEquality = true;
3803 ReverseOrderSLT = false;
3805 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3806 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3807 ZeroSrcOpcode = Mips::BLEZ;
3808 ZeroTrgOpcode = Mips::BGEZ;
3814 AcceptsEquality = false;
3815 ReverseOrderSLT = true;
3817 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3818 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3819 ZeroSrcOpcode = Mips::BLTZ;
3820 ZeroTrgOpcode = Mips::BGTZ;
3823 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3826 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3827 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3828 if (IsSrcRegZero && IsTrgRegZero) {
3829 // FIXME: All of these Opcode-specific if's are needed for compatibility
3830 // with GAS' behaviour. However, they may not generate the most efficient
3831 // code in some circumstances.
3832 if (PseudoOpcode == Mips::BLT) {
3833 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3837 if (PseudoOpcode == Mips::BLE) {
3838 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3840 Warning(IDLoc, "branch is always taken");
3843 if (PseudoOpcode == Mips::BGE) {
3844 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3846 Warning(IDLoc, "branch is always taken");
3849 if (PseudoOpcode == Mips::BGT) {
3850 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3854 if (PseudoOpcode == Mips::BGTU) {
3855 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3856 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3859 if (AcceptsEquality) {
3860 // If both registers are $0 and the pseudo-branch accepts equality, it
3861 // will always be taken, so we emit an unconditional branch.
3862 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3863 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3864 Warning(IDLoc, "branch is always taken");
3867 // If both registers are $0 and the pseudo-branch does not accept
3868 // equality, it will never be taken, so we don't have to emit anything.
3871 if (IsSrcRegZero || IsTrgRegZero) {
3872 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3873 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3874 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3875 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3876 // the pseudo-branch will never be taken, so we don't emit anything.
3877 // This only applies to unsigned pseudo-branches.
3880 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3881 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3882 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3883 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3884 // the pseudo-branch will always be taken, so we emit an unconditional
3886 // This only applies to unsigned pseudo-branches.
3887 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3888 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3889 Warning(IDLoc, "branch is always taken");
3893 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3894 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3895 // the pseudo-branch will be taken only when the non-zero register is
3896 // different from 0, so we emit a BNEZ.
3898 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3899 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3900 // the pseudo-branch will be taken only when the non-zero register is
3901 // equal to 0, so we emit a BEQZ.
3903 // Because only BLEU and BGEU branch on equality, we can use the
3904 // AcceptsEquality variable to decide when to emit the BEQZ.
3905 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3906 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3907 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3910 // If we have a signed pseudo-branch and one of the registers is $0,
3911 // we can use an appropriate compare-to-zero branch. We select which one
3912 // to use in the switch statement above.
3913 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3914 IsSrcRegZero ? TrgReg : SrcReg,
3915 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3919 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3920 // expansions. If it is not available, we return.
3921 unsigned ATRegNum = getATReg(IDLoc);
3925 if (!EmittedNoMacroWarning)
3926 warnIfNoMacro(IDLoc);
3928 // SLT fits well with 2 of our 4 pseudo-branches:
3929 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3930 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3931 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3932 // This is accomplished by using a BNEZ with the result of the SLT.
3934 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3935 // and BLE with BGT), so we change the BNEZ into a BEQZ.
3936 // Because only BGE and BLE branch on equality, we can use the
3937 // AcceptsEquality variable to decide when to emit the BEQZ.
3938 // Note that the order of the SLT arguments doesn't change between
3941 // The same applies to the unsigned variants, except that SLTu is used
3943 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3944 ReverseOrderSLT ? TrgReg : SrcReg,
3945 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3947 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3948 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3949 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3954 // Expand a integer division macro.
3956 // Notably we don't have to emit a warning when encountering $rt as the $zero
3957 // register, or 0 as an immediate. processInstruction() has already done that.
3959 // The destination register can only be $zero when expanding (S)DivIMacro or
3962 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3963 const MCSubtargetInfo *STI, const bool IsMips64,
3964 const bool Signed) {
3965 MipsTargetStreamer &TOut = getTargetStreamer();
3967 warnIfNoMacro(IDLoc);
3969 const MCOperand &RdRegOp = Inst.getOperand(0);
3970 assert(RdRegOp.isReg() && "expected register operand kind");
3971 unsigned RdReg = RdRegOp.getReg();
3973 const MCOperand &RsRegOp = Inst.getOperand(1);
3974 assert(RsRegOp.isReg() && "expected register operand kind");
3975 unsigned RsReg = RsRegOp.getReg();
3980 const MCOperand &RtOp = Inst.getOperand(2);
3981 assert((RtOp.isReg() || RtOp.isImm()) &&
3982 "expected register or immediate operand kind");
3984 RtReg = RtOp.getReg();
3986 ImmValue = RtOp.getImm();
3993 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3994 ZeroReg = Mips::ZERO_64;
3997 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3998 ZeroReg = Mips::ZERO;
4002 bool UseTraps = useTraps();
4004 unsigned Opcode = Inst.getOpcode();
4005 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4006 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4007 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4008 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4010 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4011 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4012 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4013 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4016 unsigned ATReg = getATReg(IDLoc);
4020 if (ImmValue == 0) {
4022 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4024 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4028 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4029 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4031 } else if (isDiv && ImmValue == 1) {
4032 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4034 } else if (isDiv && Signed && ImmValue == -1) {
4035 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4038 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4039 false, Inst.getLoc(), Out, STI))
4041 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4042 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4048 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4049 // break, insert the trap/break and exit. This gives a different result to
4050 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4051 // are handled equivalently. As the observed behaviour is the same, we're ok.
4052 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4054 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4057 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4061 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4062 // not expand to macro sequence.
4063 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4064 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4068 // Temporary label for first branch traget
4069 MCContext &Context = TOut.getStreamer().getContext();
4074 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4076 // Branch to the li instruction.
4077 BrTarget = Context.createTempSymbol();
4078 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4079 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4082 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4085 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4089 TOut.getStreamer().EmitLabel(BrTarget);
4091 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4095 unsigned ATReg = getATReg(IDLoc);
4100 TOut.getStreamer().EmitLabel(BrTarget);
4102 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4104 // Temporary label for the second branch target.
4105 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4106 MCOperand LabelOpEnd =
4107 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4109 // Branch to the mflo instruction.
4110 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4113 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4114 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4116 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4120 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4122 // Branch to the mflo instruction.
4123 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4124 TOut.emitNop(IDLoc, STI);
4125 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4128 TOut.getStreamer().EmitLabel(BrTargetEnd);
4129 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4133 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4134 SMLoc IDLoc, MCStreamer &Out,
4135 const MCSubtargetInfo *STI) {
4136 MipsTargetStreamer &TOut = getTargetStreamer();
4138 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4139 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4140 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4142 unsigned FirstReg = Inst.getOperand(0).getReg();
4143 unsigned SecondReg = Inst.getOperand(1).getReg();
4144 unsigned ThirdReg = Inst.getOperand(2).getReg();
4146 if (hasMips1() && !hasMips2()) {
4147 unsigned ATReg = getATReg(IDLoc);
4150 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4151 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4152 TOut.emitNop(IDLoc, STI);
4153 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4154 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4155 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4156 TOut.emitNop(IDLoc, STI);
4157 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4159 FirstReg, SecondReg, IDLoc, STI);
4160 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4161 TOut.emitNop(IDLoc, STI);
4165 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4167 FirstReg, SecondReg, IDLoc, STI);
4172 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4173 MCStreamer &Out, const MCSubtargetInfo *STI) {
4174 if (hasMips32r6() || hasMips64r6()) {
4175 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4178 const MCOperand &DstRegOp = Inst.getOperand(0);
4179 assert(DstRegOp.isReg() && "expected register operand kind");
4180 const MCOperand &SrcRegOp = Inst.getOperand(1);
4181 assert(SrcRegOp.isReg() && "expected register operand kind");
4182 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4183 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4185 MipsTargetStreamer &TOut = getTargetStreamer();
4186 unsigned DstReg = DstRegOp.getReg();
4187 unsigned SrcReg = SrcRegOp.getReg();
4188 int64_t OffsetValue = OffsetImmOp.getImm();
4190 // NOTE: We always need AT for ULHU, as it is always used as the source
4191 // register for one of the LBu's.
4192 warnIfNoMacro(IDLoc);
4193 unsigned ATReg = getATReg(IDLoc);
4197 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4198 if (IsLargeOffset) {
4199 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4204 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4205 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4207 std::swap(FirstOffset, SecondOffset);
4209 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4210 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4212 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4213 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4215 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4216 FirstOffset, IDLoc, STI);
4217 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4218 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4219 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4224 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4225 const MCSubtargetInfo *STI) {
4226 if (hasMips32r6() || hasMips64r6()) {
4227 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4230 const MCOperand &DstRegOp = Inst.getOperand(0);
4231 assert(DstRegOp.isReg() && "expected register operand kind");
4232 const MCOperand &SrcRegOp = Inst.getOperand(1);
4233 assert(SrcRegOp.isReg() && "expected register operand kind");
4234 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4235 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4237 MipsTargetStreamer &TOut = getTargetStreamer();
4238 unsigned DstReg = DstRegOp.getReg();
4239 unsigned SrcReg = SrcRegOp.getReg();
4240 int64_t OffsetValue = OffsetImmOp.getImm();
4242 warnIfNoMacro(IDLoc);
4243 unsigned ATReg = getATReg(IDLoc);
4247 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4248 if (IsLargeOffset) {
4249 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4254 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4255 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4257 std::swap(FirstOffset, SecondOffset);
4259 if (IsLargeOffset) {
4260 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4261 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4262 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4263 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4264 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4265 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4267 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4268 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4269 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4275 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4276 const MCSubtargetInfo *STI) {
4277 if (hasMips32r6() || hasMips64r6()) {
4278 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4281 const MCOperand &DstRegOp = Inst.getOperand(0);
4282 assert(DstRegOp.isReg() && "expected register operand kind");
4283 const MCOperand &SrcRegOp = Inst.getOperand(1);
4284 assert(SrcRegOp.isReg() && "expected register operand kind");
4285 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4286 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4288 MipsTargetStreamer &TOut = getTargetStreamer();
4289 unsigned DstReg = DstRegOp.getReg();
4290 unsigned SrcReg = SrcRegOp.getReg();
4291 int64_t OffsetValue = OffsetImmOp.getImm();
4293 // Compute left/right load/store offsets.
4294 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4295 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4296 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4298 std::swap(LxlOffset, LxrOffset);
4300 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4301 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4302 unsigned TmpReg = SrcReg;
4303 if (IsLargeOffset || DoMove) {
4304 warnIfNoMacro(IDLoc);
4305 TmpReg = getATReg(IDLoc);
4310 if (IsLargeOffset) {
4311 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4317 std::swap(DstReg, TmpReg);
4319 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4320 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4321 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4322 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4325 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4330 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4331 const MCSubtargetInfo *STI) {
4332 MipsTargetStreamer &TOut = getTargetStreamer();
4334 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4335 assert(Inst.getOperand(0).isReg() &&
4336 Inst.getOperand(1).isReg() &&
4337 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4339 unsigned DstReg = Inst.getOperand(0).getReg();
4340 unsigned SrcReg = Inst.getOperand(1).getReg();
4341 unsigned OpReg = Inst.getOperand(2).getReg();
4344 warnIfNoMacro(IDLoc);
4346 switch (Inst.getOpcode()) {
4351 OpCode = Mips::SLTu;
4354 llvm_unreachable("unexpected 'sge' opcode");
4357 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4358 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4359 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4364 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4365 const MCSubtargetInfo *STI) {
4366 MipsTargetStreamer &TOut = getTargetStreamer();
4368 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4369 assert(Inst.getOperand(0).isReg() &&
4370 Inst.getOperand(1).isReg() &&
4371 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4373 unsigned DstReg = Inst.getOperand(0).getReg();
4374 unsigned SrcReg = Inst.getOperand(1).getReg();
4375 int64_t ImmValue = Inst.getOperand(2).getImm();
4376 unsigned OpRegCode, OpImmCode;
4378 warnIfNoMacro(IDLoc);
4380 switch (Inst.getOpcode()) {
4382 case Mips::SGEImm64:
4383 OpRegCode = Mips::SLT;
4384 OpImmCode = Mips::SLTi;
4387 case Mips::SGEUImm64:
4388 OpRegCode = Mips::SLTu;
4389 OpImmCode = Mips::SLTiu;
4392 llvm_unreachable("unexpected 'sge' opcode with immediate");
4395 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4396 if (isInt<16>(ImmValue)) {
4397 // Use immediate version of STL.
4398 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4399 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4401 unsigned ImmReg = DstReg;
4402 if (DstReg == SrcReg) {
4403 unsigned ATReg = getATReg(Inst.getLoc());
4409 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4410 false, IDLoc, Out, STI))
4413 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4414 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4420 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4421 const MCSubtargetInfo *STI) {
4422 MipsTargetStreamer &TOut = getTargetStreamer();
4424 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4425 assert(Inst.getOperand(0).isReg() &&
4426 Inst.getOperand(1).isReg() &&
4427 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4429 unsigned DstReg = Inst.getOperand(0).getReg();
4430 unsigned SrcReg = Inst.getOperand(1).getReg();
4431 unsigned ImmReg = DstReg;
4432 int64_t ImmValue = Inst.getOperand(2).getImm();
4435 warnIfNoMacro(IDLoc);
4437 switch (Inst.getOpcode()) {
4439 case Mips::SGTImm64:
4443 case Mips::SGTUImm64:
4444 OpCode = Mips::SLTu;
4447 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4450 if (DstReg == SrcReg) {
4451 unsigned ATReg = getATReg(Inst.getLoc());
4457 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4458 false, IDLoc, Out, STI))
4461 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4462 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4467 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4469 const MCSubtargetInfo *STI) {
4470 MipsTargetStreamer &TOut = getTargetStreamer();
4472 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4473 assert(Inst.getOperand(0).isReg() &&
4474 Inst.getOperand(1).isReg() &&
4475 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4477 unsigned ATReg = Mips::NoRegister;
4478 unsigned FinalDstReg = Mips::NoRegister;
4479 unsigned DstReg = Inst.getOperand(0).getReg();
4480 unsigned SrcReg = Inst.getOperand(1).getReg();
4481 int64_t ImmValue = Inst.getOperand(2).getImm();
4483 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4485 unsigned FinalOpcode = Inst.getOpcode();
4487 if (DstReg == SrcReg) {
4488 ATReg = getATReg(Inst.getLoc());
4491 FinalDstReg = DstReg;
4495 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4496 Inst.getLoc(), Out, STI)) {
4497 switch (FinalOpcode) {
4499 llvm_unreachable("unimplemented expansion");
4501 FinalOpcode = Mips::ADD;
4504 FinalOpcode = Mips::ADDu;
4507 FinalOpcode = Mips::AND;
4510 FinalOpcode = Mips::NOR;
4513 FinalOpcode = Mips::OR;
4516 FinalOpcode = Mips::SLT;
4519 FinalOpcode = Mips::SLTu;
4522 FinalOpcode = Mips::XOR;
4525 FinalOpcode = Mips::ADD_MM;
4527 case Mips::ADDiu_MM:
4528 FinalOpcode = Mips::ADDu_MM;
4531 FinalOpcode = Mips::AND_MM;
4534 FinalOpcode = Mips::OR_MM;
4537 FinalOpcode = Mips::SLT_MM;
4539 case Mips::SLTiu_MM:
4540 FinalOpcode = Mips::SLTu_MM;
4543 FinalOpcode = Mips::XOR_MM;
4546 FinalOpcode = Mips::AND64;
4548 case Mips::NORImm64:
4549 FinalOpcode = Mips::NOR64;
4552 FinalOpcode = Mips::OR64;
4554 case Mips::SLTImm64:
4555 FinalOpcode = Mips::SLT64;
4557 case Mips::SLTUImm64:
4558 FinalOpcode = Mips::SLTu64;
4561 FinalOpcode = Mips::XOR64;
4565 if (FinalDstReg == Mips::NoRegister)
4566 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4568 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4574 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4575 const MCSubtargetInfo *STI) {
4576 MipsTargetStreamer &TOut = getTargetStreamer();
4577 unsigned ATReg = Mips::NoRegister;
4578 unsigned DReg = Inst.getOperand(0).getReg();
4579 unsigned SReg = Inst.getOperand(1).getReg();
4580 unsigned TReg = Inst.getOperand(2).getReg();
4581 unsigned TmpReg = DReg;
4583 unsigned FirstShift = Mips::NOP;
4584 unsigned SecondShift = Mips::NOP;
4586 if (hasMips32r2()) {
4588 TmpReg = getATReg(Inst.getLoc());
4593 if (Inst.getOpcode() == Mips::ROL) {
4594 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4595 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4599 if (Inst.getOpcode() == Mips::ROR) {
4600 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4608 switch (Inst.getOpcode()) {
4610 llvm_unreachable("unexpected instruction opcode");
4612 FirstShift = Mips::SRLV;
4613 SecondShift = Mips::SLLV;
4616 FirstShift = Mips::SLLV;
4617 SecondShift = Mips::SRLV;
4621 ATReg = getATReg(Inst.getLoc());
4625 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4626 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4627 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4628 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4636 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4638 const MCSubtargetInfo *STI) {
4639 MipsTargetStreamer &TOut = getTargetStreamer();
4640 unsigned ATReg = Mips::NoRegister;
4641 unsigned DReg = Inst.getOperand(0).getReg();
4642 unsigned SReg = Inst.getOperand(1).getReg();
4643 int64_t ImmValue = Inst.getOperand(2).getImm();
4645 unsigned FirstShift = Mips::NOP;
4646 unsigned SecondShift = Mips::NOP;
4648 if (hasMips32r2()) {
4649 if (Inst.getOpcode() == Mips::ROLImm) {
4650 uint64_t MaxShift = 32;
4651 uint64_t ShiftValue = ImmValue;
4653 ShiftValue = MaxShift - ImmValue;
4654 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4658 if (Inst.getOpcode() == Mips::RORImm) {
4659 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4667 if (ImmValue == 0) {
4668 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4672 switch (Inst.getOpcode()) {
4674 llvm_unreachable("unexpected instruction opcode");
4676 FirstShift = Mips::SLL;
4677 SecondShift = Mips::SRL;
4680 FirstShift = Mips::SRL;
4681 SecondShift = Mips::SLL;
4685 ATReg = getATReg(Inst.getLoc());
4689 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4690 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4691 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4699 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4700 const MCSubtargetInfo *STI) {
4701 MipsTargetStreamer &TOut = getTargetStreamer();
4702 unsigned ATReg = Mips::NoRegister;
4703 unsigned DReg = Inst.getOperand(0).getReg();
4704 unsigned SReg = Inst.getOperand(1).getReg();
4705 unsigned TReg = Inst.getOperand(2).getReg();
4706 unsigned TmpReg = DReg;
4708 unsigned FirstShift = Mips::NOP;
4709 unsigned SecondShift = Mips::NOP;
4711 if (hasMips64r2()) {
4712 if (TmpReg == SReg) {
4713 TmpReg = getATReg(Inst.getLoc());
4718 if (Inst.getOpcode() == Mips::DROL) {
4719 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4720 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4724 if (Inst.getOpcode() == Mips::DROR) {
4725 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4733 switch (Inst.getOpcode()) {
4735 llvm_unreachable("unexpected instruction opcode");
4737 FirstShift = Mips::DSRLV;
4738 SecondShift = Mips::DSLLV;
4741 FirstShift = Mips::DSLLV;
4742 SecondShift = Mips::DSRLV;
4746 ATReg = getATReg(Inst.getLoc());
4750 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4751 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4752 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4753 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4761 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4763 const MCSubtargetInfo *STI) {
4764 MipsTargetStreamer &TOut = getTargetStreamer();
4765 unsigned ATReg = Mips::NoRegister;
4766 unsigned DReg = Inst.getOperand(0).getReg();
4767 unsigned SReg = Inst.getOperand(1).getReg();
4768 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4770 unsigned FirstShift = Mips::NOP;
4771 unsigned SecondShift = Mips::NOP;
4775 if (hasMips64r2()) {
4776 unsigned FinalOpcode = Mips::NOP;
4778 FinalOpcode = Mips::DROTR;
4779 else if (ImmValue % 32 == 0)
4780 FinalOpcode = Mips::DROTR32;
4781 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4782 if (Inst.getOpcode() == Mips::DROLImm)
4783 FinalOpcode = Mips::DROTR32;
4785 FinalOpcode = Mips::DROTR;
4786 } else if (ImmValue >= 33) {
4787 if (Inst.getOpcode() == Mips::DROLImm)
4788 FinalOpcode = Mips::DROTR;
4790 FinalOpcode = Mips::DROTR32;
4793 uint64_t ShiftValue = ImmValue % 32;
4794 if (Inst.getOpcode() == Mips::DROLImm)
4795 ShiftValue = (32 - ImmValue % 32) % 32;
4797 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4803 if (ImmValue == 0) {
4804 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4808 switch (Inst.getOpcode()) {
4810 llvm_unreachable("unexpected instruction opcode");
4812 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4813 FirstShift = Mips::DSLL;
4814 SecondShift = Mips::DSRL32;
4816 if (ImmValue == 32) {
4817 FirstShift = Mips::DSLL32;
4818 SecondShift = Mips::DSRL32;
4820 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4821 FirstShift = Mips::DSLL32;
4822 SecondShift = Mips::DSRL;
4826 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4827 FirstShift = Mips::DSRL;
4828 SecondShift = Mips::DSLL32;
4830 if (ImmValue == 32) {
4831 FirstShift = Mips::DSRL32;
4832 SecondShift = Mips::DSLL32;
4834 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4835 FirstShift = Mips::DSRL32;
4836 SecondShift = Mips::DSLL;
4841 ATReg = getATReg(Inst.getLoc());
4845 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4846 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4847 Inst.getLoc(), STI);
4848 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4856 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4857 const MCSubtargetInfo *STI) {
4858 MipsTargetStreamer &TOut = getTargetStreamer();
4859 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4860 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4862 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4863 if (FirstRegOp != SecondRegOp)
4864 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4866 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4867 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4872 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4873 const MCSubtargetInfo *STI) {
4874 MipsTargetStreamer &TOut = getTargetStreamer();
4875 unsigned ATReg = Mips::NoRegister;
4876 unsigned DstReg = Inst.getOperand(0).getReg();
4877 unsigned SrcReg = Inst.getOperand(1).getReg();
4878 int32_t ImmValue = Inst.getOperand(2).getImm();
4880 ATReg = getATReg(IDLoc);
4884 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4887 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4888 SrcReg, ATReg, IDLoc, STI);
4890 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4895 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4896 const MCSubtargetInfo *STI) {
4897 MipsTargetStreamer &TOut = getTargetStreamer();
4898 unsigned ATReg = Mips::NoRegister;
4899 unsigned DstReg = Inst.getOperand(0).getReg();
4900 unsigned SrcReg = Inst.getOperand(1).getReg();
4901 unsigned TmpReg = Inst.getOperand(2).getReg();
4903 ATReg = getATReg(Inst.getLoc());
4907 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4908 SrcReg, TmpReg, IDLoc, STI);
4910 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4912 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
4913 DstReg, DstReg, 0x1F, IDLoc, STI);
4915 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4918 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4920 MCContext & Context = TOut.getStreamer().getContext();
4921 MCSymbol * BrTarget = Context.createTempSymbol();
4923 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4925 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4926 if (AssemblerOptions.back()->isReorder())
4927 TOut.emitNop(IDLoc, STI);
4928 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4930 TOut.getStreamer().EmitLabel(BrTarget);
4932 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4937 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4938 const MCSubtargetInfo *STI) {
4939 MipsTargetStreamer &TOut = getTargetStreamer();
4940 unsigned ATReg = Mips::NoRegister;
4941 unsigned DstReg = Inst.getOperand(0).getReg();
4942 unsigned SrcReg = Inst.getOperand(1).getReg();
4943 unsigned TmpReg = Inst.getOperand(2).getReg();
4945 ATReg = getATReg(IDLoc);
4949 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4950 SrcReg, TmpReg, IDLoc, STI);
4952 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
4953 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4955 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4957 MCContext & Context = TOut.getStreamer().getContext();
4958 MCSymbol * BrTarget = Context.createTempSymbol();
4960 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4962 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4963 if (AssemblerOptions.back()->isReorder())
4964 TOut.emitNop(IDLoc, STI);
4965 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4967 TOut.getStreamer().EmitLabel(BrTarget);
4973 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4974 const MCSubtargetInfo *STI) {
4975 MipsTargetStreamer &TOut = getTargetStreamer();
4976 unsigned DstReg = Inst.getOperand(0).getReg();
4977 unsigned SrcReg = Inst.getOperand(1).getReg();
4978 unsigned TmpReg = Inst.getOperand(2).getReg();
4980 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4981 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4986 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
4987 // lw $<reg+1>>, offset+4($reg2)'
4988 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
4989 // sw $<reg+1>>, offset+4($reg2)'
4991 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
4993 const MCSubtargetInfo *STI,
4998 warnIfNoMacro(IDLoc);
5000 MipsTargetStreamer &TOut = getTargetStreamer();
5001 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5002 unsigned FirstReg = Inst.getOperand(0).getReg();
5003 unsigned SecondReg = nextReg(FirstReg);
5004 unsigned BaseReg = Inst.getOperand(1).getReg();
5008 warnIfRegIndexIsAT(FirstReg, IDLoc);
5010 assert(Inst.getOperand(2).isImm() &&
5011 "Offset for load macro is not immediate!");
5013 MCOperand &FirstOffset = Inst.getOperand(2);
5014 signed NextOffset = FirstOffset.getImm() + 4;
5015 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5017 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5020 // For loads, clobber the base register with the second load instead of the
5021 // first if the BaseReg == FirstReg.
5022 if (FirstReg != BaseReg || !IsLoad) {
5023 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5024 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5026 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5027 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5034 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5035 // swc1 $<reg>, offset+4($reg2)'
5036 // or if little endian to 'swc1 $<reg>, offset($reg2);
5037 // swc1 $<reg+1>, offset+4($reg2)'
5039 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5041 const MCSubtargetInfo *STI) {
5045 warnIfNoMacro(IDLoc);
5047 MipsTargetStreamer &TOut = getTargetStreamer();
5048 unsigned Opcode = Mips::SWC1;
5049 unsigned FirstReg = Inst.getOperand(0).getReg();
5050 unsigned SecondReg = nextReg(FirstReg);
5051 unsigned BaseReg = Inst.getOperand(1).getReg();
5055 warnIfRegIndexIsAT(FirstReg, IDLoc);
5057 assert(Inst.getOperand(2).isImm() &&
5058 "Offset for macro is not immediate!");
5060 MCOperand &FirstOffset = Inst.getOperand(2);
5061 signed NextOffset = FirstOffset.getImm() + 4;
5062 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5064 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5067 if (!IsLittleEndian)
5068 std::swap(FirstReg, SecondReg);
5070 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5071 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5076 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5077 const MCSubtargetInfo *STI) {
5078 MipsTargetStreamer &TOut = getTargetStreamer();
5080 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5081 assert(Inst.getOperand(0).isReg() &&
5082 Inst.getOperand(1).isReg() &&
5083 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5085 unsigned DstReg = Inst.getOperand(0).getReg();
5086 unsigned SrcReg = Inst.getOperand(1).getReg();
5087 unsigned OpReg = Inst.getOperand(2).getReg();
5089 warnIfNoMacro(IDLoc);
5091 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5092 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5093 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5097 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5098 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5102 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5103 const MCSubtargetInfo *STI) {
5104 MipsTargetStreamer &TOut = getTargetStreamer();
5106 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5107 assert(Inst.getOperand(0).isReg() &&
5108 Inst.getOperand(1).isReg() &&
5109 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5111 unsigned DstReg = Inst.getOperand(0).getReg();
5112 unsigned SrcReg = Inst.getOperand(1).getReg();
5113 int64_t Imm = Inst.getOperand(2).getImm();
5115 warnIfNoMacro(IDLoc);
5118 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5122 if (SrcReg == Mips::ZERO) {
5123 Warning(IDLoc, "comparison is always false");
5124 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5125 DstReg, SrcReg, SrcReg, IDLoc, STI);
5130 if (Imm > -0x8000 && Imm < 0) {
5132 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5137 if (!isUInt<16>(Imm)) {
5138 unsigned ATReg = getATReg(IDLoc);
5142 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5146 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5147 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5151 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5152 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5156 // Map the DSP accumulator and control register to the corresponding gpr
5157 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5158 // do not map the DSP registers contigously to gpr registers.
5159 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5160 switch (Inst.getOpcode()) {
5163 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5173 llvm_unreachable("Unknown register for 'mttr' alias!");
5177 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5187 llvm_unreachable("Unknown register for 'mttr' alias!");
5191 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5201 llvm_unreachable("Unknown register for 'mttr' alias!");
5207 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5211 // Map the floating point register operand to the corresponding register
5213 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5214 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5215 case Mips::F0: return Mips::ZERO;
5216 case Mips::F1: return Mips::AT;
5217 case Mips::F2: return Mips::V0;
5218 case Mips::F3: return Mips::V1;
5219 case Mips::F4: return Mips::A0;
5220 case Mips::F5: return Mips::A1;
5221 case Mips::F6: return Mips::A2;
5222 case Mips::F7: return Mips::A3;
5223 case Mips::F8: return Mips::T0;
5224 case Mips::F9: return Mips::T1;
5225 case Mips::F10: return Mips::T2;
5226 case Mips::F11: return Mips::T3;
5227 case Mips::F12: return Mips::T4;
5228 case Mips::F13: return Mips::T5;
5229 case Mips::F14: return Mips::T6;
5230 case Mips::F15: return Mips::T7;
5231 case Mips::F16: return Mips::S0;
5232 case Mips::F17: return Mips::S1;
5233 case Mips::F18: return Mips::S2;
5234 case Mips::F19: return Mips::S3;
5235 case Mips::F20: return Mips::S4;
5236 case Mips::F21: return Mips::S5;
5237 case Mips::F22: return Mips::S6;
5238 case Mips::F23: return Mips::S7;
5239 case Mips::F24: return Mips::T8;
5240 case Mips::F25: return Mips::T9;
5241 case Mips::F26: return Mips::K0;
5242 case Mips::F27: return Mips::K1;
5243 case Mips::F28: return Mips::GP;
5244 case Mips::F29: return Mips::SP;
5245 case Mips::F30: return Mips::FP;
5246 case Mips::F31: return Mips::RA;
5247 default: llvm_unreachable("Unknown register for mttc1 alias!");
5251 // Map the coprocessor operand the corresponding gpr register operand.
5252 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5253 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5254 case Mips::COP00: return Mips::ZERO;
5255 case Mips::COP01: return Mips::AT;
5256 case Mips::COP02: return Mips::V0;
5257 case Mips::COP03: return Mips::V1;
5258 case Mips::COP04: return Mips::A0;
5259 case Mips::COP05: return Mips::A1;
5260 case Mips::COP06: return Mips::A2;
5261 case Mips::COP07: return Mips::A3;
5262 case Mips::COP08: return Mips::T0;
5263 case Mips::COP09: return Mips::T1;
5264 case Mips::COP010: return Mips::T2;
5265 case Mips::COP011: return Mips::T3;
5266 case Mips::COP012: return Mips::T4;
5267 case Mips::COP013: return Mips::T5;
5268 case Mips::COP014: return Mips::T6;
5269 case Mips::COP015: return Mips::T7;
5270 case Mips::COP016: return Mips::S0;
5271 case Mips::COP017: return Mips::S1;
5272 case Mips::COP018: return Mips::S2;
5273 case Mips::COP019: return Mips::S3;
5274 case Mips::COP020: return Mips::S4;
5275 case Mips::COP021: return Mips::S5;
5276 case Mips::COP022: return Mips::S6;
5277 case Mips::COP023: return Mips::S7;
5278 case Mips::COP024: return Mips::T8;
5279 case Mips::COP025: return Mips::T9;
5280 case Mips::COP026: return Mips::K0;
5281 case Mips::COP027: return Mips::K1;
5282 case Mips::COP028: return Mips::GP;
5283 case Mips::COP029: return Mips::SP;
5284 case Mips::COP030: return Mips::FP;
5285 case Mips::COP031: return Mips::RA;
5286 default: llvm_unreachable("Unknown register for mttc0 alias!");
5290 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5291 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5292 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5293 const MCSubtargetInfo *STI) {
5294 MipsTargetStreamer &TOut = getTargetStreamer();
5299 bool IsMFTR = false;
5300 switch (Inst.getOpcode()) {
5306 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5307 sel = Inst.getOperand(2).getImm();
5313 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5325 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5333 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5340 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5347 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5351 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5354 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5355 : Inst.getOperand(0).getReg());
5357 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5363 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5364 const OperandVector &Operands) {
5365 switch (Inst.getOpcode()) {
5367 return Match_Success;
5370 if (static_cast<MipsOperand &>(*Operands[1])
5371 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5372 return Match_Success;
5373 return Match_RequiresSameSrcAndDst;
5377 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5378 switch (Inst.getOpcode()) {
5379 // As described by the MIPSR6 spec, daui must not use the zero operand for
5380 // its source operand.
5382 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5383 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5384 return Match_RequiresNoZeroRegister;
5385 return Match_Success;
5386 // As described by the Mips32r2 spec, the registers Rd and Rs for
5387 // jalr.hb must be different.
5388 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5389 // and registers Rd and Base for microMIPS lwp instruction
5391 case Mips::JALR_HB64:
5392 case Mips::JALRC_HB_MMR6:
5393 case Mips::JALRC_MMR6:
5394 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5395 return Match_RequiresDifferentSrcAndDst;
5396 return Match_Success;
5398 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5399 return Match_RequiresDifferentSrcAndDst;
5400 return Match_Success;
5402 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5403 return Match_NonZeroOperandForSync;
5404 return Match_Success;
5409 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5410 return Match_NonZeroOperandForMTCX;
5411 return Match_Success;
5412 // As described the MIPSR6 spec, the compact branches that compare registers
5414 // a) Not use the zero register.
5415 // b) Not use the same register twice.
5416 // c) rs < rt for bnec, beqc.
5417 // NB: For this case, the encoding will swap the operands as their
5418 // ordering doesn't matter. GAS performs this transformation too.
5419 // Hence, that constraint does not have to be enforced.
5421 // The compact branches that branch iff the signed addition of two registers
5422 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5423 // operand swapping. They do not have restriction of using the zero register.
5424 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5425 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5426 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5427 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5428 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5429 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5436 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5437 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5438 return Match_RequiresNoZeroRegister;
5439 return Match_Success;
5440 case Mips::BGEC: case Mips::BGEC_MMR6:
5441 case Mips::BLTC: case Mips::BLTC_MMR6:
5442 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5443 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5444 case Mips::BEQC: case Mips::BEQC_MMR6:
5445 case Mips::BNEC: case Mips::BNEC_MMR6:
5452 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5453 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5454 return Match_RequiresNoZeroRegister;
5455 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5456 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5457 return Match_RequiresNoZeroRegister;
5458 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5459 return Match_RequiresDifferentOperands;
5460 return Match_Success;
5462 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5463 "Operands must be immediates for dins!");
5464 const signed Pos = Inst.getOperand(2).getImm();
5465 const signed Size = Inst.getOperand(3).getImm();
5466 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5467 return Match_RequiresPosSizeRange0_32;
5468 return Match_Success;
5472 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5473 "Operands must be immediates for dinsm/dinsu!");
5474 const signed Pos = Inst.getOperand(2).getImm();
5475 const signed Size = Inst.getOperand(3).getImm();
5476 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5477 return Match_RequiresPosSizeRange33_64;
5478 return Match_Success;
5481 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5482 "Operands must be immediates for DEXTM!");
5483 const signed Pos = Inst.getOperand(2).getImm();
5484 const signed Size = Inst.getOperand(3).getImm();
5485 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5486 return Match_RequiresPosSizeUImm6;
5487 return Match_Success;
5491 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5492 "Operands must be immediates for dextm/dextu!");
5493 const signed Pos = Inst.getOperand(2).getImm();
5494 const signed Size = Inst.getOperand(3).getImm();
5495 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5496 return Match_RequiresPosSizeRange33_64;
5497 return Match_Success;
5499 case Mips::CRC32B: case Mips::CRC32CB:
5500 case Mips::CRC32H: case Mips::CRC32CH:
5501 case Mips::CRC32W: case Mips::CRC32CW:
5502 case Mips::CRC32D: case Mips::CRC32CD:
5503 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5504 return Match_RequiresSameSrcAndDst;
5505 return Match_Success;
5508 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5509 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5510 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5511 return Match_NoFCCRegisterForCurrentISA;
5513 return Match_Success;
5517 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5518 uint64_t ErrorInfo) {
5519 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5520 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5521 if (ErrorLoc == SMLoc())
5528 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5529 OperandVector &Operands,
5531 uint64_t &ErrorInfo,
5532 bool MatchingInlineAsm) {
5534 unsigned MatchResult =
5535 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5537 switch (MatchResult) {
5539 if (processInstruction(Inst, IDLoc, Out, STI))
5542 case Match_MissingFeature:
5543 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5545 case Match_InvalidOperand: {
5546 SMLoc ErrorLoc = IDLoc;
5547 if (ErrorInfo != ~0ULL) {
5548 if (ErrorInfo >= Operands.size())
5549 return Error(IDLoc, "too few operands for instruction");
5551 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5552 if (ErrorLoc == SMLoc())
5556 return Error(ErrorLoc, "invalid operand for instruction");
5558 case Match_NonZeroOperandForSync:
5560 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5561 case Match_NonZeroOperandForMTCX:
5562 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5563 case Match_MnemonicFail:
5564 return Error(IDLoc, "invalid instruction");
5565 case Match_RequiresDifferentSrcAndDst:
5566 return Error(IDLoc, "source and destination must be different");
5567 case Match_RequiresDifferentOperands:
5568 return Error(IDLoc, "registers must be different");
5569 case Match_RequiresNoZeroRegister:
5570 return Error(IDLoc, "invalid operand ($zero) for instruction");
5571 case Match_RequiresSameSrcAndDst:
5572 return Error(IDLoc, "source and destination must match");
5573 case Match_NoFCCRegisterForCurrentISA:
5574 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5575 "non-zero fcc register doesn't exist in current ISA level");
5577 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5579 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5580 "expected 1-bit unsigned immediate");
5582 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5583 "expected 2-bit unsigned immediate");
5585 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5586 "expected immediate in range 1 .. 4");
5588 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5589 "expected 3-bit unsigned immediate");
5591 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5592 "expected 4-bit unsigned immediate");
5594 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5595 "expected 4-bit signed immediate");
5597 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5598 "expected 5-bit unsigned immediate");
5600 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5601 "expected 5-bit signed immediate");
5603 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5604 "expected immediate in range 1 .. 32");
5605 case Match_UImm5_32:
5606 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5607 "expected immediate in range 32 .. 63");
5608 case Match_UImm5_33:
5609 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5610 "expected immediate in range 33 .. 64");
5611 case Match_UImm5_0_Report_UImm6:
5612 // This is used on UImm5 operands that have a corresponding UImm5_32
5613 // operand to avoid confusing the user.
5614 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5615 "expected 6-bit unsigned immediate");
5616 case Match_UImm5_Lsl2:
5617 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5618 "expected both 7-bit unsigned immediate and multiple of 4");
5619 case Match_UImmRange2_64:
5620 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5621 "expected immediate in range 2 .. 64");
5623 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5624 "expected 6-bit unsigned immediate");
5625 case Match_UImm6_Lsl2:
5626 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5627 "expected both 8-bit unsigned immediate and multiple of 4");
5629 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5630 "expected 6-bit signed immediate");
5632 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5633 "expected 7-bit unsigned immediate");
5634 case Match_UImm7_N1:
5635 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5636 "expected immediate in range -1 .. 126");
5637 case Match_SImm7_Lsl2:
5638 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5639 "expected both 9-bit signed immediate and multiple of 4");
5641 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5642 "expected 8-bit unsigned immediate");
5643 case Match_UImm10_0:
5644 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5645 "expected 10-bit unsigned immediate");
5646 case Match_SImm10_0:
5647 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5648 "expected 10-bit signed immediate");
5649 case Match_SImm11_0:
5650 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5651 "expected 11-bit signed immediate");
5653 case Match_UImm16_Relaxed:
5654 case Match_UImm16_AltRelaxed:
5655 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5656 "expected 16-bit unsigned immediate");
5658 case Match_SImm16_Relaxed:
5659 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5660 "expected 16-bit signed immediate");
5661 case Match_SImm19_Lsl2:
5662 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5663 "expected both 19-bit signed immediate and multiple of 4");
5664 case Match_UImm20_0:
5665 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5666 "expected 20-bit unsigned immediate");
5667 case Match_UImm26_0:
5668 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5669 "expected 26-bit unsigned immediate");
5671 case Match_SImm32_Relaxed:
5672 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5673 "expected 32-bit signed immediate");
5674 case Match_UImm32_Coerced:
5675 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5676 "expected 32-bit immediate");
5677 case Match_MemSImm9:
5678 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5679 "expected memory with 9-bit signed offset");
5680 case Match_MemSImm10:
5681 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5682 "expected memory with 10-bit signed offset");
5683 case Match_MemSImm10Lsl1:
5684 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5685 "expected memory with 11-bit signed offset and multiple of 2");
5686 case Match_MemSImm10Lsl2:
5687 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5688 "expected memory with 12-bit signed offset and multiple of 4");
5689 case Match_MemSImm10Lsl3:
5690 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5691 "expected memory with 13-bit signed offset and multiple of 8");
5692 case Match_MemSImm11:
5693 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5694 "expected memory with 11-bit signed offset");
5695 case Match_MemSImm12:
5696 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5697 "expected memory with 12-bit signed offset");
5698 case Match_MemSImm16:
5699 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5700 "expected memory with 16-bit signed offset");
5701 case Match_MemSImmPtr:
5702 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5703 "expected memory with 32-bit signed offset");
5704 case Match_RequiresPosSizeRange0_32: {
5705 SMLoc ErrorStart = Operands[3]->getStartLoc();
5706 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5707 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5708 SMRange(ErrorStart, ErrorEnd));
5710 case Match_RequiresPosSizeUImm6: {
5711 SMLoc ErrorStart = Operands[3]->getStartLoc();
5712 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5713 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5714 SMRange(ErrorStart, ErrorEnd));
5716 case Match_RequiresPosSizeRange33_64: {
5717 SMLoc ErrorStart = Operands[3]->getStartLoc();
5718 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5719 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5720 SMRange(ErrorStart, ErrorEnd));
5724 llvm_unreachable("Implement any new match types added!");
5727 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5728 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5729 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5730 ") without \".set noat\"");
5733 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5734 if (!AssemblerOptions.back()->isMacro())
5735 Warning(Loc, "macro instruction expanded into multiple instructions");
5738 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5739 const OperandVector &Operands) {
5741 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
5742 "Unexpected instruction!");
5743 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5744 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5745 Inst.addOperand(MCOperand::createReg(NextReg));
5746 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5750 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5751 SMRange Range, bool ShowColors) {
5752 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5753 Range, SMFixIt(Range, FixMsg),
5757 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5760 CC = StringSwitch<unsigned>(Name)
5762 .Cases("at", "AT", 1)
5796 if (!(isABI_N32() || isABI_N64()))
5799 if (12 <= CC && CC <= 15) {
5800 // Name is one of t4-t7
5801 AsmToken RegTok = getLexer().peekTok();
5802 SMRange RegRange = RegTok.getLocRange();
5804 StringRef FixedName = StringSwitch<StringRef>(Name)
5810 assert(FixedName != "" && "Register name is not one of t4-t7.");
5812 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5813 "Did you mean $" + FixedName + "?", RegRange);
5816 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5817 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5818 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5819 if (8 <= CC && CC <= 11)
5823 CC = StringSwitch<unsigned>(Name)
5835 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5838 CC = StringSwitch<unsigned>(Name)
5839 .Case("hwr_cpunum", 0)
5840 .Case("hwr_synci_step", 1)
5842 .Case("hwr_ccres", 3)
5843 .Case("hwr_ulr", 29)
5849 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5850 if (Name[0] == 'f') {
5851 StringRef NumString = Name.substr(1);
5853 if (NumString.getAsInteger(10, IntVal))
5854 return -1; // This is not an integer.
5855 if (IntVal > 31) // Maximum index for fpu register.
5862 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5863 if (Name.startswith("fcc")) {
5864 StringRef NumString = Name.substr(3);
5866 if (NumString.getAsInteger(10, IntVal))
5867 return -1; // This is not an integer.
5868 if (IntVal > 7) // There are only 8 fcc registers.
5875 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5876 if (Name.startswith("ac")) {
5877 StringRef NumString = Name.substr(2);
5879 if (NumString.getAsInteger(10, IntVal))
5880 return -1; // This is not an integer.
5881 if (IntVal > 3) // There are only 3 acc registers.
5888 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5891 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5900 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5903 CC = StringSwitch<unsigned>(Name)
5906 .Case("msaaccess", 2)
5908 .Case("msamodify", 4)
5909 .Case("msarequest", 5)
5911 .Case("msaunmap", 7)
5917 bool MipsAsmParser::canUseATReg() {
5918 return AssemblerOptions.back()->getATRegIndex() != 0;
5921 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
5922 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
5924 reportParseError(Loc,
5925 "pseudo-instruction requires $at, which is not available");
5928 unsigned AT = getReg(
5929 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5933 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
5934 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5937 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
5938 MCAsmParser &Parser = getParser();
5939 LLVM_DEBUG(dbgs() << "parseOperand\n");
5941 // Check if the current operand has a custom associated parser, if so, try to
5942 // custom parse the operand, or fallback to the general approach.
5943 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5944 if (ResTy == MatchOperand_Success)
5946 // If there wasn't a custom match, try the generic matcher below. Otherwise,
5947 // there was a match, but an error occurred, in which case, just return that
5948 // the operand parsing failed.
5949 if (ResTy == MatchOperand_ParseFail)
5952 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
5954 switch (getLexer().getKind()) {
5955 case AsmToken::Dollar: {
5956 // Parse the register.
5957 SMLoc S = Parser.getTok().getLoc();
5959 // Almost all registers have been parsed by custom parsers. There is only
5960 // one exception to this. $zero (and it's alias $0) will reach this point
5961 // for div, divu, and similar instructions because it is not an operand
5962 // to the instruction definition but an explicit register. Special case
5963 // this situation for now.
5964 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
5967 // Maybe it is a symbol reference.
5968 StringRef Identifier;
5969 if (Parser.parseIdentifier(Identifier))
5972 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5973 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
5974 // Otherwise create a symbol reference.
5976 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
5978 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
5982 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
5985 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
5986 if (getParser().parseExpression(Expr))
5989 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5991 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
5994 } // switch(getLexer().getKind())
5998 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
5999 switch (Expr->getKind()) {
6000 case MCExpr::Constant:
6002 case MCExpr::SymbolRef:
6003 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
6004 case MCExpr::Binary: {
6005 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
6006 if (!isEvaluated(BE->getLHS()))
6008 return isEvaluated(BE->getRHS());
6011 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
6012 case MCExpr::Target:
6018 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
6020 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6021 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6022 if (ResTy == MatchOperand_Success) {
6023 assert(Operands.size() == 1);
6024 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6025 StartLoc = Operand.getStartLoc();
6026 EndLoc = Operand.getEndLoc();
6028 // AFAIK, we only support numeric registers and named GPR's in CFI
6030 // Don't worry about eating tokens before failing. Using an unrecognised
6031 // register is a parse error.
6032 if (Operand.isGPRAsmReg()) {
6033 // Resolve to GPR32 or GPR64 appropriately.
6034 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6037 return (RegNo == (unsigned)-1);
6040 assert(Operands.size() == 0);
6041 return (RegNo == (unsigned)-1);
6044 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
6048 return getParser().parseParenExprOfDepth(0, Res, S);
6049 return getParser().parseExpression(Res);
6052 OperandMatchResultTy
6053 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6054 MCAsmParser &Parser = getParser();
6055 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6056 const MCExpr *IdVal = nullptr;
6058 bool isParenExpr = false;
6059 OperandMatchResultTy Res = MatchOperand_NoMatch;
6060 // First operand is the offset.
6061 S = Parser.getTok().getLoc();
6063 if (getLexer().getKind() == AsmToken::LParen) {
6068 if (getLexer().getKind() != AsmToken::Dollar) {
6069 if (parseMemOffset(IdVal, isParenExpr))
6070 return MatchOperand_ParseFail;
6072 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6073 if (Tok.isNot(AsmToken::LParen)) {
6074 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6075 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6077 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6078 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6079 return MatchOperand_Success;
6081 if (Tok.is(AsmToken::EndOfStatement)) {
6083 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6085 // Zero register assumed, add a memory operand with ZERO as its base.
6086 // "Base" will be managed by k_Memory.
6087 auto Base = MipsOperand::createGPRReg(
6088 0, "0", getContext().getRegisterInfo(), S, E, *this);
6090 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6091 return MatchOperand_Success;
6093 MCBinaryExpr::Opcode Opcode;
6094 // GAS and LLVM treat comparison operators different. GAS will generate -1
6095 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6096 // highly unlikely to be found in a memory offset expression, we don't
6098 switch (Tok.getKind()) {
6099 case AsmToken::Plus:
6100 Opcode = MCBinaryExpr::Add;
6103 case AsmToken::Minus:
6104 Opcode = MCBinaryExpr::Sub;
6107 case AsmToken::Star:
6108 Opcode = MCBinaryExpr::Mul;
6111 case AsmToken::Pipe:
6112 Opcode = MCBinaryExpr::Or;
6116 Opcode = MCBinaryExpr::And;
6119 case AsmToken::LessLess:
6120 Opcode = MCBinaryExpr::Shl;
6123 case AsmToken::GreaterGreater:
6124 Opcode = MCBinaryExpr::LShr;
6127 case AsmToken::Caret:
6128 Opcode = MCBinaryExpr::Xor;
6131 case AsmToken::Slash:
6132 Opcode = MCBinaryExpr::Div;
6135 case AsmToken::Percent:
6136 Opcode = MCBinaryExpr::Mod;
6140 Error(Parser.getTok().getLoc(), "'(' or expression expected");
6141 return MatchOperand_ParseFail;
6143 const MCExpr * NextExpr;
6144 if (getParser().parseExpression(NextExpr))
6145 return MatchOperand_ParseFail;
6146 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6149 Parser.Lex(); // Eat the '(' token.
6152 Res = parseAnyRegister(Operands);
6153 if (Res != MatchOperand_Success)
6156 if (Parser.getTok().isNot(AsmToken::RParen)) {
6157 Error(Parser.getTok().getLoc(), "')' expected");
6158 return MatchOperand_ParseFail;
6161 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6163 Parser.Lex(); // Eat the ')' token.
6166 IdVal = MCConstantExpr::create(0, getContext());
6168 // Replace the register operand with the memory operand.
6169 std::unique_ptr<MipsOperand> op(
6170 static_cast<MipsOperand *>(Operands.back().release()));
6171 // Remove the register from the operands.
6172 // "op" will be managed by k_Memory.
6173 Operands.pop_back();
6174 // Add the memory operand.
6175 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6177 if (IdVal->evaluateAsAbsolute(Imm))
6178 IdVal = MCConstantExpr::create(Imm, getContext());
6179 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6180 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6184 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6185 return MatchOperand_Success;
6188 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6189 MCAsmParser &Parser = getParser();
6190 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6194 SMLoc S = Parser.getTok().getLoc();
6195 if (Sym->isVariable()) {
6196 const MCExpr *Expr = Sym->getVariableValue();
6197 if (Expr->getKind() == MCExpr::SymbolRef) {
6198 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6199 StringRef DefSymbol = Ref->getSymbol().getName();
6200 if (DefSymbol.startswith("$")) {
6201 OperandMatchResultTy ResTy =
6202 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6203 if (ResTy == MatchOperand_Success) {
6207 if (ResTy == MatchOperand_ParseFail)
6208 llvm_unreachable("Should never ParseFail");
6211 } else if (Sym->isUnset()) {
6212 // If symbol is unset, it might be created in the `parseSetAssignment`
6213 // routine as an alias for a numeric register name.
6214 // Lookup in the aliases list.
6215 auto Entry = RegisterSets.find(Sym->getName());
6216 if (Entry != RegisterSets.end()) {
6217 OperandMatchResultTy ResTy =
6218 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6219 if (ResTy == MatchOperand_Success) {
6229 OperandMatchResultTy
6230 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6231 StringRef Identifier,
6233 int Index = matchCPURegisterName(Identifier);
6235 Operands.push_back(MipsOperand::createGPRReg(
6236 Index, Identifier, getContext().getRegisterInfo(), S,
6237 getLexer().getLoc(), *this));
6238 return MatchOperand_Success;
6241 Index = matchHWRegsRegisterName(Identifier);
6243 Operands.push_back(MipsOperand::createHWRegsReg(
6244 Index, Identifier, getContext().getRegisterInfo(), S,
6245 getLexer().getLoc(), *this));
6246 return MatchOperand_Success;
6249 Index = matchFPURegisterName(Identifier);
6251 Operands.push_back(MipsOperand::createFGRReg(
6252 Index, Identifier, getContext().getRegisterInfo(), S,
6253 getLexer().getLoc(), *this));
6254 return MatchOperand_Success;
6257 Index = matchFCCRegisterName(Identifier);
6259 Operands.push_back(MipsOperand::createFCCReg(
6260 Index, Identifier, getContext().getRegisterInfo(), S,
6261 getLexer().getLoc(), *this));
6262 return MatchOperand_Success;
6265 Index = matchACRegisterName(Identifier);
6267 Operands.push_back(MipsOperand::createACCReg(
6268 Index, Identifier, getContext().getRegisterInfo(), S,
6269 getLexer().getLoc(), *this));
6270 return MatchOperand_Success;
6273 Index = matchMSA128RegisterName(Identifier);
6275 Operands.push_back(MipsOperand::createMSA128Reg(
6276 Index, Identifier, getContext().getRegisterInfo(), S,
6277 getLexer().getLoc(), *this));
6278 return MatchOperand_Success;
6281 Index = matchMSA128CtrlRegisterName(Identifier);
6283 Operands.push_back(MipsOperand::createMSACtrlReg(
6284 Index, Identifier, getContext().getRegisterInfo(), S,
6285 getLexer().getLoc(), *this));
6286 return MatchOperand_Success;
6289 return MatchOperand_NoMatch;
6292 OperandMatchResultTy
6293 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6294 const AsmToken &Token, SMLoc S) {
6295 if (Token.is(AsmToken::Identifier)) {
6296 LLVM_DEBUG(dbgs() << ".. identifier\n");
6297 StringRef Identifier = Token.getIdentifier();
6298 OperandMatchResultTy ResTy =
6299 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6301 } else if (Token.is(AsmToken::Integer)) {
6302 LLVM_DEBUG(dbgs() << ".. integer\n");
6303 int64_t RegNum = Token.getIntVal();
6304 if (RegNum < 0 || RegNum > 31) {
6305 // Show the error, but treat invalid register
6306 // number as a normal one to continue parsing
6307 // and catch other possible errors.
6308 Error(getLexer().getLoc(), "invalid register number");
6310 Operands.push_back(MipsOperand::createNumericReg(
6311 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6312 Token.getLoc(), *this));
6313 return MatchOperand_Success;
6316 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6318 return MatchOperand_NoMatch;
6321 OperandMatchResultTy
6322 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6323 auto Token = getLexer().peekTok(false);
6324 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6327 OperandMatchResultTy
6328 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6329 MCAsmParser &Parser = getParser();
6330 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6332 auto Token = Parser.getTok();
6334 SMLoc S = Token.getLoc();
6336 if (Token.isNot(AsmToken::Dollar)) {
6337 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6338 if (Token.is(AsmToken::Identifier)) {
6339 if (searchSymbolAlias(Operands))
6340 return MatchOperand_Success;
6342 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6343 return MatchOperand_NoMatch;
6345 LLVM_DEBUG(dbgs() << ".. $\n");
6347 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6348 if (ResTy == MatchOperand_Success) {
6350 Parser.Lex(); // identifier
6355 OperandMatchResultTy
6356 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6357 MCAsmParser &Parser = getParser();
6358 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6360 SMLoc S = getLexer().getLoc();
6362 // Registers are a valid target and have priority over symbols.
6363 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6364 if (ResTy != MatchOperand_NoMatch)
6367 // Integers and expressions are acceptable
6368 const MCExpr *Expr = nullptr;
6369 if (Parser.parseExpression(Expr)) {
6370 // We have no way of knowing if a symbol was consumed so we must ParseFail
6371 return MatchOperand_ParseFail;
6374 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6375 return MatchOperand_Success;
6378 OperandMatchResultTy
6379 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6380 MCAsmParser &Parser = getParser();
6381 const MCExpr *IdVal;
6382 // If the first token is '$' we may have register operand. We have to reject
6383 // cases where it is not a register. Complicating the matter is that
6384 // register names are not reserved across all ABIs.
6385 // Peek past the dollar to see if it's a register name for this ABI.
6386 SMLoc S = Parser.getTok().getLoc();
6387 if (Parser.getTok().is(AsmToken::Dollar)) {
6388 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6389 ? MatchOperand_ParseFail
6390 : MatchOperand_NoMatch;
6392 if (getParser().parseExpression(IdVal))
6393 return MatchOperand_ParseFail;
6394 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6396 return MatchOperand_NoMatch;
6397 int64_t Val = MCE->getValue();
6398 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6399 Operands.push_back(MipsOperand::CreateImm(
6400 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6401 return MatchOperand_Success;
6404 OperandMatchResultTy
6405 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6406 MCAsmParser &Parser = getParser();
6407 SmallVector<unsigned, 10> Regs;
6409 unsigned PrevReg = Mips::NoRegister;
6410 bool RegRange = false;
6411 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6413 if (Parser.getTok().isNot(AsmToken::Dollar))
6414 return MatchOperand_ParseFail;
6416 SMLoc S = Parser.getTok().getLoc();
6417 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6418 SMLoc E = getLexer().getLoc();
6419 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6420 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6422 // Remove last register operand because registers from register range
6423 // should be inserted first.
6424 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6425 (!isGP64bit() && RegNo == Mips::RA)) {
6426 Regs.push_back(RegNo);
6428 unsigned TmpReg = PrevReg + 1;
6429 while (TmpReg <= RegNo) {
6430 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6431 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6433 Error(E, "invalid register operand");
6434 return MatchOperand_ParseFail;
6438 Regs.push_back(TmpReg++);
6444 if ((PrevReg == Mips::NoRegister) &&
6445 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6446 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6447 Error(E, "$16 or $31 expected");
6448 return MatchOperand_ParseFail;
6449 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6450 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6452 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6453 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6455 Error(E, "invalid register operand");
6456 return MatchOperand_ParseFail;
6457 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6458 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6459 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6461 Error(E, "consecutive register numbers expected");
6462 return MatchOperand_ParseFail;
6465 Regs.push_back(RegNo);
6468 if (Parser.getTok().is(AsmToken::Minus))
6471 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6472 !Parser.getTok().isNot(AsmToken::Comma)) {
6473 Error(E, "',' or '-' expected");
6474 return MatchOperand_ParseFail;
6477 Lex(); // Consume comma or minus
6478 if (Parser.getTok().isNot(AsmToken::Dollar))
6484 SMLoc E = Parser.getTok().getLoc();
6485 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6486 parseMemOperand(Operands);
6487 return MatchOperand_Success;
6490 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6492 /// ::= '(', register, ')'
6493 /// handle it before we iterate so we don't get tripped up by the lack of
6495 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6496 MCAsmParser &Parser = getParser();
6497 if (getLexer().is(AsmToken::LParen)) {
6499 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6501 if (parseOperand(Operands, Name)) {
6502 SMLoc Loc = getLexer().getLoc();
6503 return Error(Loc, "unexpected token in argument list");
6505 if (Parser.getTok().isNot(AsmToken::RParen)) {
6506 SMLoc Loc = getLexer().getLoc();
6507 return Error(Loc, "unexpected token, expected ')'");
6510 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6516 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6517 /// either one of these.
6518 /// ::= '[', register, ']'
6519 /// ::= '[', integer, ']'
6520 /// handle it before we iterate so we don't get tripped up by the lack of
6522 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6523 OperandVector &Operands) {
6524 MCAsmParser &Parser = getParser();
6525 if (getLexer().is(AsmToken::LBrac)) {
6527 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6529 if (parseOperand(Operands, Name)) {
6530 SMLoc Loc = getLexer().getLoc();
6531 return Error(Loc, "unexpected token in argument list");
6533 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6534 SMLoc Loc = getLexer().getLoc();
6535 return Error(Loc, "unexpected token, expected ']'");
6538 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6544 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6545 unsigned VariantID = 0);
6547 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6548 SMLoc NameLoc, OperandVector &Operands) {
6549 MCAsmParser &Parser = getParser();
6550 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6552 // We have reached first instruction, module directive are now forbidden.
6553 getTargetStreamer().forbidModuleDirective();
6555 // Check if we have valid mnemonic
6556 if (!mnemonicIsValid(Name, 0)) {
6557 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6558 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6559 return Error(NameLoc, "unknown instruction" + Suggestion);
6561 // First operand in MCInst is instruction mnemonic.
6562 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6564 // Read the remaining operands.
6565 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6566 // Read the first operand.
6567 if (parseOperand(Operands, Name)) {
6568 SMLoc Loc = getLexer().getLoc();
6569 return Error(Loc, "unexpected token in argument list");
6571 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6573 // AFAIK, parenthesis suffixes are never on the first operand
6575 while (getLexer().is(AsmToken::Comma)) {
6576 Parser.Lex(); // Eat the comma.
6577 // Parse and remember the operand.
6578 if (parseOperand(Operands, Name)) {
6579 SMLoc Loc = getLexer().getLoc();
6580 return Error(Loc, "unexpected token in argument list");
6582 // Parse bracket and parenthesis suffixes before we iterate
6583 if (getLexer().is(AsmToken::LBrac)) {
6584 if (parseBracketSuffix(Name, Operands))
6586 } else if (getLexer().is(AsmToken::LParen) &&
6587 parseParenSuffix(Name, Operands))
6591 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6592 SMLoc Loc = getLexer().getLoc();
6593 return Error(Loc, "unexpected token in argument list");
6595 Parser.Lex(); // Consume the EndOfStatement.
6599 // FIXME: Given that these have the same name, these should both be
6600 // consistent on affecting the Parser.
6601 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6602 SMLoc Loc = getLexer().getLoc();
6603 return Error(Loc, ErrorMsg);
6606 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6607 return Error(Loc, ErrorMsg);
6610 bool MipsAsmParser::parseSetNoAtDirective() {
6611 MCAsmParser &Parser = getParser();
6612 // Line should look like: ".set noat".
6614 // Set the $at register to $0.
6615 AssemblerOptions.back()->setATRegIndex(0);
6617 Parser.Lex(); // Eat "noat".
6619 // If this is not the end of the statement, report an error.
6620 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6621 reportParseError("unexpected token, expected end of statement");
6625 getTargetStreamer().emitDirectiveSetNoAt();
6626 Parser.Lex(); // Consume the EndOfStatement.
6630 bool MipsAsmParser::parseSetAtDirective() {
6631 // Line can be: ".set at", which sets $at to $1
6632 // or ".set at=$reg", which sets $at to $reg.
6633 MCAsmParser &Parser = getParser();
6634 Parser.Lex(); // Eat "at".
6636 if (getLexer().is(AsmToken::EndOfStatement)) {
6637 // No register was specified, so we set $at to $1.
6638 AssemblerOptions.back()->setATRegIndex(1);
6640 getTargetStreamer().emitDirectiveSetAt();
6641 Parser.Lex(); // Consume the EndOfStatement.
6645 if (getLexer().isNot(AsmToken::Equal)) {
6646 reportParseError("unexpected token, expected equals sign");
6649 Parser.Lex(); // Eat "=".
6651 if (getLexer().isNot(AsmToken::Dollar)) {
6652 if (getLexer().is(AsmToken::EndOfStatement)) {
6653 reportParseError("no register specified");
6656 reportParseError("unexpected token, expected dollar sign '$'");
6660 Parser.Lex(); // Eat "$".
6662 // Find out what "reg" is.
6664 const AsmToken &Reg = Parser.getTok();
6665 if (Reg.is(AsmToken::Identifier)) {
6666 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6667 } else if (Reg.is(AsmToken::Integer)) {
6668 AtRegNo = Reg.getIntVal();
6670 reportParseError("unexpected token, expected identifier or integer");
6674 // Check if $reg is a valid register. If it is, set $at to $reg.
6675 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6676 reportParseError("invalid register");
6679 Parser.Lex(); // Eat "reg".
6681 // If this is not the end of the statement, report an error.
6682 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6683 reportParseError("unexpected token, expected end of statement");
6687 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6689 Parser.Lex(); // Consume the EndOfStatement.
6693 bool MipsAsmParser::parseSetReorderDirective() {
6694 MCAsmParser &Parser = getParser();
6696 // If this is not the end of the statement, report an error.
6697 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6698 reportParseError("unexpected token, expected end of statement");
6701 AssemblerOptions.back()->setReorder();
6702 getTargetStreamer().emitDirectiveSetReorder();
6703 Parser.Lex(); // Consume the EndOfStatement.
6707 bool MipsAsmParser::parseSetNoReorderDirective() {
6708 MCAsmParser &Parser = getParser();
6710 // If this is not the end of the statement, report an error.
6711 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6712 reportParseError("unexpected token, expected end of statement");
6715 AssemblerOptions.back()->setNoReorder();
6716 getTargetStreamer().emitDirectiveSetNoReorder();
6717 Parser.Lex(); // Consume the EndOfStatement.
6721 bool MipsAsmParser::parseSetMacroDirective() {
6722 MCAsmParser &Parser = getParser();
6724 // If this is not the end of the statement, report an error.
6725 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6726 reportParseError("unexpected token, expected end of statement");
6729 AssemblerOptions.back()->setMacro();
6730 getTargetStreamer().emitDirectiveSetMacro();
6731 Parser.Lex(); // Consume the EndOfStatement.
6735 bool MipsAsmParser::parseSetNoMacroDirective() {
6736 MCAsmParser &Parser = getParser();
6738 // If this is not the end of the statement, report an error.
6739 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6740 reportParseError("unexpected token, expected end of statement");
6743 if (AssemblerOptions.back()->isReorder()) {
6744 reportParseError("`noreorder' must be set before `nomacro'");
6747 AssemblerOptions.back()->setNoMacro();
6748 getTargetStreamer().emitDirectiveSetNoMacro();
6749 Parser.Lex(); // Consume the EndOfStatement.
6753 bool MipsAsmParser::parseSetMsaDirective() {
6754 MCAsmParser &Parser = getParser();
6757 // If this is not the end of the statement, report an error.
6758 if (getLexer().isNot(AsmToken::EndOfStatement))
6759 return reportParseError("unexpected token, expected end of statement");
6761 setFeatureBits(Mips::FeatureMSA, "msa");
6762 getTargetStreamer().emitDirectiveSetMsa();
6766 bool MipsAsmParser::parseSetNoMsaDirective() {
6767 MCAsmParser &Parser = getParser();
6770 // If this is not the end of the statement, report an error.
6771 if (getLexer().isNot(AsmToken::EndOfStatement))
6772 return reportParseError("unexpected token, expected end of statement");
6774 clearFeatureBits(Mips::FeatureMSA, "msa");
6775 getTargetStreamer().emitDirectiveSetNoMsa();
6779 bool MipsAsmParser::parseSetNoDspDirective() {
6780 MCAsmParser &Parser = getParser();
6781 Parser.Lex(); // Eat "nodsp".
6783 // If this is not the end of the statement, report an error.
6784 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6785 reportParseError("unexpected token, expected end of statement");
6789 clearFeatureBits(Mips::FeatureDSP, "dsp");
6790 getTargetStreamer().emitDirectiveSetNoDsp();
6794 bool MipsAsmParser::parseSetMips16Directive() {
6795 MCAsmParser &Parser = getParser();
6796 Parser.Lex(); // Eat "mips16".
6798 // If this is not the end of the statement, report an error.
6799 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6800 reportParseError("unexpected token, expected end of statement");
6804 setFeatureBits(Mips::FeatureMips16, "mips16");
6805 getTargetStreamer().emitDirectiveSetMips16();
6806 Parser.Lex(); // Consume the EndOfStatement.
6810 bool MipsAsmParser::parseSetNoMips16Directive() {
6811 MCAsmParser &Parser = getParser();
6812 Parser.Lex(); // Eat "nomips16".
6814 // If this is not the end of the statement, report an error.
6815 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6816 reportParseError("unexpected token, expected end of statement");
6820 clearFeatureBits(Mips::FeatureMips16, "mips16");
6821 getTargetStreamer().emitDirectiveSetNoMips16();
6822 Parser.Lex(); // Consume the EndOfStatement.
6826 bool MipsAsmParser::parseSetFpDirective() {
6827 MCAsmParser &Parser = getParser();
6828 MipsABIFlagsSection::FpABIKind FpAbiVal;
6829 // Line can be: .set fp=32
6832 Parser.Lex(); // Eat fp token
6833 AsmToken Tok = Parser.getTok();
6834 if (Tok.isNot(AsmToken::Equal)) {
6835 reportParseError("unexpected token, expected equals sign '='");
6838 Parser.Lex(); // Eat '=' token.
6839 Tok = Parser.getTok();
6841 if (!parseFpABIValue(FpAbiVal, ".set"))
6844 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6845 reportParseError("unexpected token, expected end of statement");
6848 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6849 Parser.Lex(); // Consume the EndOfStatement.
6853 bool MipsAsmParser::parseSetOddSPRegDirective() {
6854 MCAsmParser &Parser = getParser();
6856 Parser.Lex(); // Eat "oddspreg".
6857 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6858 reportParseError("unexpected token, expected end of statement");
6862 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6863 getTargetStreamer().emitDirectiveSetOddSPReg();
6867 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6868 MCAsmParser &Parser = getParser();
6870 Parser.Lex(); // Eat "nooddspreg".
6871 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6872 reportParseError("unexpected token, expected end of statement");
6876 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6877 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6881 bool MipsAsmParser::parseSetMtDirective() {
6882 MCAsmParser &Parser = getParser();
6883 Parser.Lex(); // Eat "mt".
6885 // If this is not the end of the statement, report an error.
6886 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6887 reportParseError("unexpected token, expected end of statement");
6891 setFeatureBits(Mips::FeatureMT, "mt");
6892 getTargetStreamer().emitDirectiveSetMt();
6893 Parser.Lex(); // Consume the EndOfStatement.
6897 bool MipsAsmParser::parseSetNoMtDirective() {
6898 MCAsmParser &Parser = getParser();
6899 Parser.Lex(); // Eat "nomt".
6901 // If this is not the end of the statement, report an error.
6902 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6903 reportParseError("unexpected token, expected end of statement");
6907 clearFeatureBits(Mips::FeatureMT, "mt");
6909 getTargetStreamer().emitDirectiveSetNoMt();
6910 Parser.Lex(); // Consume the EndOfStatement.
6914 bool MipsAsmParser::parseSetNoCRCDirective() {
6915 MCAsmParser &Parser = getParser();
6916 Parser.Lex(); // Eat "nocrc".
6918 // If this is not the end of the statement, report an error.
6919 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6920 reportParseError("unexpected token, expected end of statement");
6924 clearFeatureBits(Mips::FeatureCRC, "crc");
6926 getTargetStreamer().emitDirectiveSetNoCRC();
6927 Parser.Lex(); // Consume the EndOfStatement.
6931 bool MipsAsmParser::parseSetNoVirtDirective() {
6932 MCAsmParser &Parser = getParser();
6933 Parser.Lex(); // Eat "novirt".
6935 // If this is not the end of the statement, report an error.
6936 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6937 reportParseError("unexpected token, expected end of statement");
6941 clearFeatureBits(Mips::FeatureVirt, "virt");
6943 getTargetStreamer().emitDirectiveSetNoVirt();
6944 Parser.Lex(); // Consume the EndOfStatement.
6948 bool MipsAsmParser::parseSetNoGINVDirective() {
6949 MCAsmParser &Parser = getParser();
6950 Parser.Lex(); // Eat "noginv".
6952 // If this is not the end of the statement, report an error.
6953 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6954 reportParseError("unexpected token, expected end of statement");
6958 clearFeatureBits(Mips::FeatureGINV, "ginv");
6960 getTargetStreamer().emitDirectiveSetNoGINV();
6961 Parser.Lex(); // Consume the EndOfStatement.
6965 bool MipsAsmParser::parseSetPopDirective() {
6966 MCAsmParser &Parser = getParser();
6967 SMLoc Loc = getLexer().getLoc();
6970 if (getLexer().isNot(AsmToken::EndOfStatement))
6971 return reportParseError("unexpected token, expected end of statement");
6973 // Always keep an element on the options "stack" to prevent the user
6974 // from changing the initial options. This is how we remember them.
6975 if (AssemblerOptions.size() == 2)
6976 return reportParseError(Loc, ".set pop with no .set push");
6978 MCSubtargetInfo &STI = copySTI();
6979 AssemblerOptions.pop_back();
6980 setAvailableFeatures(
6981 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
6982 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
6984 getTargetStreamer().emitDirectiveSetPop();
6988 bool MipsAsmParser::parseSetPushDirective() {
6989 MCAsmParser &Parser = getParser();
6991 if (getLexer().isNot(AsmToken::EndOfStatement))
6992 return reportParseError("unexpected token, expected end of statement");
6994 // Create a copy of the current assembler options environment and push it.
6995 AssemblerOptions.push_back(
6996 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
6998 getTargetStreamer().emitDirectiveSetPush();
7002 bool MipsAsmParser::parseSetSoftFloatDirective() {
7003 MCAsmParser &Parser = getParser();
7005 if (getLexer().isNot(AsmToken::EndOfStatement))
7006 return reportParseError("unexpected token, expected end of statement");
7008 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7009 getTargetStreamer().emitDirectiveSetSoftFloat();
7013 bool MipsAsmParser::parseSetHardFloatDirective() {
7014 MCAsmParser &Parser = getParser();
7016 if (getLexer().isNot(AsmToken::EndOfStatement))
7017 return reportParseError("unexpected token, expected end of statement");
7019 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7020 getTargetStreamer().emitDirectiveSetHardFloat();
7024 bool MipsAsmParser::parseSetAssignment() {
7026 MCAsmParser &Parser = getParser();
7028 if (Parser.parseIdentifier(Name))
7029 return reportParseError("expected identifier after .set");
7031 if (getLexer().isNot(AsmToken::Comma))
7032 return reportParseError("unexpected token, expected comma");
7035 if (getLexer().is(AsmToken::Dollar) &&
7036 getLexer().peekTok().is(AsmToken::Integer)) {
7037 // Parse assignment of a numeric register:
7039 Parser.Lex(); // Eat $.
7040 RegisterSets[Name] = Parser.getTok();
7041 Parser.Lex(); // Eat identifier.
7042 getContext().getOrCreateSymbol(Name);
7047 const MCExpr *Value;
7048 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7049 Parser, Sym, Value))
7051 Sym->setVariableValue(Value);
7056 bool MipsAsmParser::parseSetMips0Directive() {
7057 MCAsmParser &Parser = getParser();
7059 if (getLexer().isNot(AsmToken::EndOfStatement))
7060 return reportParseError("unexpected token, expected end of statement");
7062 // Reset assembler options to their initial values.
7063 MCSubtargetInfo &STI = copySTI();
7064 setAvailableFeatures(
7065 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7066 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7067 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7069 getTargetStreamer().emitDirectiveSetMips0();
7073 bool MipsAsmParser::parseSetArchDirective() {
7074 MCAsmParser &Parser = getParser();
7076 if (getLexer().isNot(AsmToken::Equal))
7077 return reportParseError("unexpected token, expected equals sign");
7081 if (Parser.parseIdentifier(Arch))
7082 return reportParseError("expected arch identifier");
7084 StringRef ArchFeatureName =
7085 StringSwitch<StringRef>(Arch)
7086 .Case("mips1", "mips1")
7087 .Case("mips2", "mips2")
7088 .Case("mips3", "mips3")
7089 .Case("mips4", "mips4")
7090 .Case("mips5", "mips5")
7091 .Case("mips32", "mips32")
7092 .Case("mips32r2", "mips32r2")
7093 .Case("mips32r3", "mips32r3")
7094 .Case("mips32r5", "mips32r5")
7095 .Case("mips32r6", "mips32r6")
7096 .Case("mips64", "mips64")
7097 .Case("mips64r2", "mips64r2")
7098 .Case("mips64r3", "mips64r3")
7099 .Case("mips64r5", "mips64r5")
7100 .Case("mips64r6", "mips64r6")
7101 .Case("octeon", "cnmips")
7102 .Case("r4000", "mips3") // This is an implementation of Mips3.
7105 if (ArchFeatureName.empty())
7106 return reportParseError("unsupported architecture");
7108 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7109 return reportParseError("mips64r6 does not support microMIPS");
7111 selectArch(ArchFeatureName);
7112 getTargetStreamer().emitDirectiveSetArch(Arch);
7116 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7117 MCAsmParser &Parser = getParser();
7119 if (getLexer().isNot(AsmToken::EndOfStatement))
7120 return reportParseError("unexpected token, expected end of statement");
7124 llvm_unreachable("Unimplemented feature");
7125 case Mips::FeatureDSP:
7126 setFeatureBits(Mips::FeatureDSP, "dsp");
7127 getTargetStreamer().emitDirectiveSetDsp();
7129 case Mips::FeatureDSPR2:
7130 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7131 getTargetStreamer().emitDirectiveSetDspr2();
7133 case Mips::FeatureMicroMips:
7134 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7135 getTargetStreamer().emitDirectiveSetMicroMips();
7137 case Mips::FeatureMips1:
7138 selectArch("mips1");
7139 getTargetStreamer().emitDirectiveSetMips1();
7141 case Mips::FeatureMips2:
7142 selectArch("mips2");
7143 getTargetStreamer().emitDirectiveSetMips2();
7145 case Mips::FeatureMips3:
7146 selectArch("mips3");
7147 getTargetStreamer().emitDirectiveSetMips3();
7149 case Mips::FeatureMips4:
7150 selectArch("mips4");
7151 getTargetStreamer().emitDirectiveSetMips4();
7153 case Mips::FeatureMips5:
7154 selectArch("mips5");
7155 getTargetStreamer().emitDirectiveSetMips5();
7157 case Mips::FeatureMips32:
7158 selectArch("mips32");
7159 getTargetStreamer().emitDirectiveSetMips32();
7161 case Mips::FeatureMips32r2:
7162 selectArch("mips32r2");
7163 getTargetStreamer().emitDirectiveSetMips32R2();
7165 case Mips::FeatureMips32r3:
7166 selectArch("mips32r3");
7167 getTargetStreamer().emitDirectiveSetMips32R3();
7169 case Mips::FeatureMips32r5:
7170 selectArch("mips32r5");
7171 getTargetStreamer().emitDirectiveSetMips32R5();
7173 case Mips::FeatureMips32r6:
7174 selectArch("mips32r6");
7175 getTargetStreamer().emitDirectiveSetMips32R6();
7177 case Mips::FeatureMips64:
7178 selectArch("mips64");
7179 getTargetStreamer().emitDirectiveSetMips64();
7181 case Mips::FeatureMips64r2:
7182 selectArch("mips64r2");
7183 getTargetStreamer().emitDirectiveSetMips64R2();
7185 case Mips::FeatureMips64r3:
7186 selectArch("mips64r3");
7187 getTargetStreamer().emitDirectiveSetMips64R3();
7189 case Mips::FeatureMips64r5:
7190 selectArch("mips64r5");
7191 getTargetStreamer().emitDirectiveSetMips64R5();
7193 case Mips::FeatureMips64r6:
7194 selectArch("mips64r6");
7195 getTargetStreamer().emitDirectiveSetMips64R6();
7197 case Mips::FeatureCRC:
7198 setFeatureBits(Mips::FeatureCRC, "crc");
7199 getTargetStreamer().emitDirectiveSetCRC();
7201 case Mips::FeatureVirt:
7202 setFeatureBits(Mips::FeatureVirt, "virt");
7203 getTargetStreamer().emitDirectiveSetVirt();
7205 case Mips::FeatureGINV:
7206 setFeatureBits(Mips::FeatureGINV, "ginv");
7207 getTargetStreamer().emitDirectiveSetGINV();
7213 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7214 MCAsmParser &Parser = getParser();
7215 if (getLexer().isNot(AsmToken::Comma)) {
7216 SMLoc Loc = getLexer().getLoc();
7217 return Error(Loc, ErrorStr);
7220 Parser.Lex(); // Eat the comma.
7224 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7225 // In this class, it is only used for .cprestore.
7226 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7227 // MipsTargetELFStreamer and MipsAsmParser.
7228 bool MipsAsmParser::isPicAndNotNxxAbi() {
7229 return inPicMode() && !(isABI_N32() || isABI_N64());
7232 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7233 if (AssemblerOptions.back()->isReorder())
7234 Warning(Loc, ".cpload should be inside a noreorder section");
7236 if (inMips16Mode()) {
7237 reportParseError(".cpload is not supported in Mips16 mode");
7241 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7242 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7243 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7244 reportParseError("expected register containing function address");
7248 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7249 if (!RegOpnd.isGPRAsmReg()) {
7250 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7254 // If this is not the end of the statement, report an error.
7255 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7256 reportParseError("unexpected token, expected end of statement");
7260 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7264 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7265 if (!isABI_N32() && !isABI_N64()) {
7266 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7270 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7271 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7272 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7273 reportParseError("expected register containing global pointer");
7277 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7278 if (!RegOpnd.isGPRAsmReg()) {
7279 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7283 // If this is not the end of the statement, report an error.
7284 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7285 reportParseError("unexpected token, expected end of statement");
7288 getParser().Lex(); // Consume the EndOfStatement.
7290 unsigned NewReg = RegOpnd.getGPR32Reg();
7294 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7298 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7299 MCAsmParser &Parser = getParser();
7301 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7302 // is used in non-PIC mode.
7304 if (inMips16Mode()) {
7305 reportParseError(".cprestore is not supported in Mips16 mode");
7309 // Get the stack offset value.
7310 const MCExpr *StackOffset;
7311 int64_t StackOffsetVal;
7312 if (Parser.parseExpression(StackOffset)) {
7313 reportParseError("expected stack offset value");
7317 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7318 reportParseError("stack offset is not an absolute expression");
7322 if (StackOffsetVal < 0) {
7323 Warning(Loc, ".cprestore with negative stack offset has no effect");
7324 IsCpRestoreSet = false;
7326 IsCpRestoreSet = true;
7327 CpRestoreOffset = StackOffsetVal;
7330 // If this is not the end of the statement, report an error.
7331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7332 reportParseError("unexpected token, expected end of statement");
7336 if (!getTargetStreamer().emitDirectiveCpRestore(
7337 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7339 Parser.Lex(); // Consume the EndOfStatement.
7343 bool MipsAsmParser::parseDirectiveCPSetup() {
7344 MCAsmParser &Parser = getParser();
7347 bool SaveIsReg = true;
7349 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7350 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7351 if (ResTy == MatchOperand_NoMatch) {
7352 reportParseError("expected register containing function address");
7356 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7357 if (!FuncRegOpnd.isGPRAsmReg()) {
7358 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7362 FuncReg = FuncRegOpnd.getGPR32Reg();
7365 if (!eatComma("unexpected token, expected comma"))
7368 ResTy = parseAnyRegister(TmpReg);
7369 if (ResTy == MatchOperand_NoMatch) {
7370 const MCExpr *OffsetExpr;
7372 SMLoc ExprLoc = getLexer().getLoc();
7374 if (Parser.parseExpression(OffsetExpr) ||
7375 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7376 reportParseError(ExprLoc, "expected save register or stack offset");
7383 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7384 if (!SaveOpnd.isGPRAsmReg()) {
7385 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7388 Save = SaveOpnd.getGPR32Reg();
7391 if (!eatComma("unexpected token, expected comma"))
7395 if (Parser.parseExpression(Expr)) {
7396 reportParseError("expected expression");
7400 if (Expr->getKind() != MCExpr::SymbolRef) {
7401 reportParseError("expected symbol");
7404 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7406 CpSaveLocation = Save;
7407 CpSaveLocationIsRegister = SaveIsReg;
7409 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7414 bool MipsAsmParser::parseDirectiveCPReturn() {
7415 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7416 CpSaveLocationIsRegister);
7420 bool MipsAsmParser::parseDirectiveNaN() {
7421 MCAsmParser &Parser = getParser();
7422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7423 const AsmToken &Tok = Parser.getTok();
7425 if (Tok.getString() == "2008") {
7427 getTargetStreamer().emitDirectiveNaN2008();
7429 } else if (Tok.getString() == "legacy") {
7431 getTargetStreamer().emitDirectiveNaNLegacy();
7435 // If we don't recognize the option passed to the .nan
7436 // directive (e.g. no option or unknown option), emit an error.
7437 reportParseError("invalid option in .nan directive");
7441 bool MipsAsmParser::parseDirectiveSet() {
7442 const AsmToken &Tok = getParser().getTok();
7443 StringRef IdVal = Tok.getString();
7444 SMLoc Loc = Tok.getLoc();
7446 if (IdVal == "noat")
7447 return parseSetNoAtDirective();
7449 return parseSetAtDirective();
7450 if (IdVal == "arch")
7451 return parseSetArchDirective();
7452 if (IdVal == "bopt") {
7453 Warning(Loc, "'bopt' feature is unsupported");
7457 if (IdVal == "nobopt") {
7458 // We're already running in nobopt mode, so nothing to do.
7463 return parseSetFpDirective();
7464 if (IdVal == "oddspreg")
7465 return parseSetOddSPRegDirective();
7466 if (IdVal == "nooddspreg")
7467 return parseSetNoOddSPRegDirective();
7469 return parseSetPopDirective();
7470 if (IdVal == "push")
7471 return parseSetPushDirective();
7472 if (IdVal == "reorder")
7473 return parseSetReorderDirective();
7474 if (IdVal == "noreorder")
7475 return parseSetNoReorderDirective();
7476 if (IdVal == "macro")
7477 return parseSetMacroDirective();
7478 if (IdVal == "nomacro")
7479 return parseSetNoMacroDirective();
7480 if (IdVal == "mips16")
7481 return parseSetMips16Directive();
7482 if (IdVal == "nomips16")
7483 return parseSetNoMips16Directive();
7484 if (IdVal == "nomicromips") {
7485 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7486 getTargetStreamer().emitDirectiveSetNoMicroMips();
7487 getParser().eatToEndOfStatement();
7490 if (IdVal == "micromips") {
7491 if (hasMips64r6()) {
7492 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7495 return parseSetFeature(Mips::FeatureMicroMips);
7497 if (IdVal == "mips0")
7498 return parseSetMips0Directive();
7499 if (IdVal == "mips1")
7500 return parseSetFeature(Mips::FeatureMips1);
7501 if (IdVal == "mips2")
7502 return parseSetFeature(Mips::FeatureMips2);
7503 if (IdVal == "mips3")
7504 return parseSetFeature(Mips::FeatureMips3);
7505 if (IdVal == "mips4")
7506 return parseSetFeature(Mips::FeatureMips4);
7507 if (IdVal == "mips5")
7508 return parseSetFeature(Mips::FeatureMips5);
7509 if (IdVal == "mips32")
7510 return parseSetFeature(Mips::FeatureMips32);
7511 if (IdVal == "mips32r2")
7512 return parseSetFeature(Mips::FeatureMips32r2);
7513 if (IdVal == "mips32r3")
7514 return parseSetFeature(Mips::FeatureMips32r3);
7515 if (IdVal == "mips32r5")
7516 return parseSetFeature(Mips::FeatureMips32r5);
7517 if (IdVal == "mips32r6")
7518 return parseSetFeature(Mips::FeatureMips32r6);
7519 if (IdVal == "mips64")
7520 return parseSetFeature(Mips::FeatureMips64);
7521 if (IdVal == "mips64r2")
7522 return parseSetFeature(Mips::FeatureMips64r2);
7523 if (IdVal == "mips64r3")
7524 return parseSetFeature(Mips::FeatureMips64r3);
7525 if (IdVal == "mips64r5")
7526 return parseSetFeature(Mips::FeatureMips64r5);
7527 if (IdVal == "mips64r6") {
7528 if (inMicroMipsMode()) {
7529 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7532 return parseSetFeature(Mips::FeatureMips64r6);
7535 return parseSetFeature(Mips::FeatureDSP);
7536 if (IdVal == "dspr2")
7537 return parseSetFeature(Mips::FeatureDSPR2);
7538 if (IdVal == "nodsp")
7539 return parseSetNoDspDirective();
7541 return parseSetMsaDirective();
7542 if (IdVal == "nomsa")
7543 return parseSetNoMsaDirective();
7545 return parseSetMtDirective();
7546 if (IdVal == "nomt")
7547 return parseSetNoMtDirective();
7548 if (IdVal == "softfloat")
7549 return parseSetSoftFloatDirective();
7550 if (IdVal == "hardfloat")
7551 return parseSetHardFloatDirective();
7553 return parseSetFeature(Mips::FeatureCRC);
7554 if (IdVal == "nocrc")
7555 return parseSetNoCRCDirective();
7556 if (IdVal == "virt")
7557 return parseSetFeature(Mips::FeatureVirt);
7558 if (IdVal == "novirt")
7559 return parseSetNoVirtDirective();
7560 if (IdVal == "ginv")
7561 return parseSetFeature(Mips::FeatureGINV);
7562 if (IdVal == "noginv")
7563 return parseSetNoGINVDirective();
7565 // It is just an identifier, look for an assignment.
7566 return parseSetAssignment();
7569 /// parseDirectiveGpWord
7570 /// ::= .gpword local_sym
7571 bool MipsAsmParser::parseDirectiveGpWord() {
7572 MCAsmParser &Parser = getParser();
7573 const MCExpr *Value;
7574 // EmitGPRel32Value requires an expression, so we are using base class
7575 // method to evaluate the expression.
7576 if (getParser().parseExpression(Value))
7578 getParser().getStreamer().EmitGPRel32Value(Value);
7580 if (getLexer().isNot(AsmToken::EndOfStatement))
7581 return Error(getLexer().getLoc(),
7582 "unexpected token, expected end of statement");
7583 Parser.Lex(); // Eat EndOfStatement token.
7587 /// parseDirectiveGpDWord
7588 /// ::= .gpdword local_sym
7589 bool MipsAsmParser::parseDirectiveGpDWord() {
7590 MCAsmParser &Parser = getParser();
7591 const MCExpr *Value;
7592 // EmitGPRel64Value requires an expression, so we are using base class
7593 // method to evaluate the expression.
7594 if (getParser().parseExpression(Value))
7596 getParser().getStreamer().EmitGPRel64Value(Value);
7598 if (getLexer().isNot(AsmToken::EndOfStatement))
7599 return Error(getLexer().getLoc(),
7600 "unexpected token, expected end of statement");
7601 Parser.Lex(); // Eat EndOfStatement token.
7605 /// parseDirectiveDtpRelWord
7606 /// ::= .dtprelword tls_sym
7607 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7608 MCAsmParser &Parser = getParser();
7609 const MCExpr *Value;
7610 // EmitDTPRel32Value requires an expression, so we are using base class
7611 // method to evaluate the expression.
7612 if (getParser().parseExpression(Value))
7614 getParser().getStreamer().EmitDTPRel32Value(Value);
7616 if (getLexer().isNot(AsmToken::EndOfStatement))
7617 return Error(getLexer().getLoc(),
7618 "unexpected token, expected end of statement");
7619 Parser.Lex(); // Eat EndOfStatement token.
7623 /// parseDirectiveDtpRelDWord
7624 /// ::= .dtpreldword tls_sym
7625 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7626 MCAsmParser &Parser = getParser();
7627 const MCExpr *Value;
7628 // EmitDTPRel64Value requires an expression, so we are using base class
7629 // method to evaluate the expression.
7630 if (getParser().parseExpression(Value))
7632 getParser().getStreamer().EmitDTPRel64Value(Value);
7634 if (getLexer().isNot(AsmToken::EndOfStatement))
7635 return Error(getLexer().getLoc(),
7636 "unexpected token, expected end of statement");
7637 Parser.Lex(); // Eat EndOfStatement token.
7641 /// parseDirectiveTpRelWord
7642 /// ::= .tprelword tls_sym
7643 bool MipsAsmParser::parseDirectiveTpRelWord() {
7644 MCAsmParser &Parser = getParser();
7645 const MCExpr *Value;
7646 // EmitTPRel32Value requires an expression, so we are using base class
7647 // method to evaluate the expression.
7648 if (getParser().parseExpression(Value))
7650 getParser().getStreamer().EmitTPRel32Value(Value);
7652 if (getLexer().isNot(AsmToken::EndOfStatement))
7653 return Error(getLexer().getLoc(),
7654 "unexpected token, expected end of statement");
7655 Parser.Lex(); // Eat EndOfStatement token.
7659 /// parseDirectiveTpRelDWord
7660 /// ::= .tpreldword tls_sym
7661 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7662 MCAsmParser &Parser = getParser();
7663 const MCExpr *Value;
7664 // EmitTPRel64Value requires an expression, so we are using base class
7665 // method to evaluate the expression.
7666 if (getParser().parseExpression(Value))
7668 getParser().getStreamer().EmitTPRel64Value(Value);
7670 if (getLexer().isNot(AsmToken::EndOfStatement))
7671 return Error(getLexer().getLoc(),
7672 "unexpected token, expected end of statement");
7673 Parser.Lex(); // Eat EndOfStatement token.
7677 bool MipsAsmParser::parseDirectiveOption() {
7678 MCAsmParser &Parser = getParser();
7679 // Get the option token.
7680 AsmToken Tok = Parser.getTok();
7681 // At the moment only identifiers are supported.
7682 if (Tok.isNot(AsmToken::Identifier)) {
7683 return Error(Parser.getTok().getLoc(),
7684 "unexpected token, expected identifier");
7687 StringRef Option = Tok.getIdentifier();
7689 if (Option == "pic0") {
7690 // MipsAsmParser needs to know if the current PIC mode changes.
7691 IsPicEnabled = false;
7693 getTargetStreamer().emitDirectiveOptionPic0();
7695 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7696 return Error(Parser.getTok().getLoc(),
7697 "unexpected token, expected end of statement");
7702 if (Option == "pic2") {
7703 // MipsAsmParser needs to know if the current PIC mode changes.
7704 IsPicEnabled = true;
7706 getTargetStreamer().emitDirectiveOptionPic2();
7708 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7709 return Error(Parser.getTok().getLoc(),
7710 "unexpected token, expected end of statement");
7716 Warning(Parser.getTok().getLoc(),
7717 "unknown option, expected 'pic0' or 'pic2'");
7718 Parser.eatToEndOfStatement();
7722 /// parseInsnDirective
7724 bool MipsAsmParser::parseInsnDirective() {
7725 // If this is not the end of the statement, report an error.
7726 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7727 reportParseError("unexpected token, expected end of statement");
7731 // The actual label marking happens in
7732 // MipsELFStreamer::createPendingLabelRelocs().
7733 getTargetStreamer().emitDirectiveInsn();
7735 getParser().Lex(); // Eat EndOfStatement token.
7739 /// parseRSectionDirective
7741 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
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 MCSection *ELFSection = getContext().getELFSection(
7749 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7750 getParser().getStreamer().SwitchSection(ELFSection);
7752 getParser().Lex(); // Eat EndOfStatement token.
7756 /// parseSSectionDirective
7759 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7760 // If this is not the end of the statement, report an error.
7761 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7762 reportParseError("unexpected token, expected end of statement");
7766 MCSection *ELFSection = getContext().getELFSection(
7767 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7768 getParser().getStreamer().SwitchSection(ELFSection);
7770 getParser().Lex(); // Eat EndOfStatement token.
7774 /// parseDirectiveModule
7775 /// ::= .module oddspreg
7776 /// ::= .module nooddspreg
7777 /// ::= .module fp=value
7778 /// ::= .module softfloat
7779 /// ::= .module hardfloat
7782 /// ::= .module nocrc
7783 /// ::= .module virt
7784 /// ::= .module novirt
7785 /// ::= .module ginv
7786 /// ::= .module noginv
7787 bool MipsAsmParser::parseDirectiveModule() {
7788 MCAsmParser &Parser = getParser();
7789 MCAsmLexer &Lexer = getLexer();
7790 SMLoc L = Lexer.getLoc();
7792 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7793 // TODO : get a better message.
7794 reportParseError(".module directive must appear before any code");
7799 if (Parser.parseIdentifier(Option)) {
7800 reportParseError("expected .module option identifier");
7804 if (Option == "oddspreg") {
7805 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7807 // Synchronize the abiflags information with the FeatureBits information we
7809 getTargetStreamer().updateABIInfo(*this);
7811 // If printing assembly, use the recently updated abiflags information.
7812 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7813 // emitted at the end).
7814 getTargetStreamer().emitDirectiveModuleOddSPReg();
7816 // If this is not the end of the statement, report an error.
7817 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7818 reportParseError("unexpected token, expected end of statement");
7822 return false; // parseDirectiveModule has finished successfully.
7823 } else if (Option == "nooddspreg") {
7825 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7828 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7830 // Synchronize the abiflags information with the FeatureBits information we
7832 getTargetStreamer().updateABIInfo(*this);
7834 // If printing assembly, use the recently updated abiflags information.
7835 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7836 // emitted at the end).
7837 getTargetStreamer().emitDirectiveModuleOddSPReg();
7839 // If this is not the end of the statement, report an error.
7840 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7841 reportParseError("unexpected token, expected end of statement");
7845 return false; // parseDirectiveModule has finished successfully.
7846 } else if (Option == "fp") {
7847 return parseDirectiveModuleFP();
7848 } else if (Option == "softfloat") {
7849 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7851 // Synchronize the ABI Flags information with the FeatureBits information we
7853 getTargetStreamer().updateABIInfo(*this);
7855 // If printing assembly, use the recently updated ABI Flags information.
7856 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7858 getTargetStreamer().emitDirectiveModuleSoftFloat();
7860 // If this is not the end of the statement, report an error.
7861 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7862 reportParseError("unexpected token, expected end of statement");
7866 return false; // parseDirectiveModule has finished successfully.
7867 } else if (Option == "hardfloat") {
7868 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7870 // Synchronize the ABI Flags information with the FeatureBits information we
7872 getTargetStreamer().updateABIInfo(*this);
7874 // If printing assembly, use the recently updated ABI Flags information.
7875 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7877 getTargetStreamer().emitDirectiveModuleHardFloat();
7879 // If this is not the end of the statement, report an error.
7880 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7881 reportParseError("unexpected token, expected end of statement");
7885 return false; // parseDirectiveModule has finished successfully.
7886 } else if (Option == "mt") {
7887 setModuleFeatureBits(Mips::FeatureMT, "mt");
7889 // Synchronize the ABI Flags information with the FeatureBits information we
7891 getTargetStreamer().updateABIInfo(*this);
7893 // If printing assembly, use the recently updated ABI Flags information.
7894 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7896 getTargetStreamer().emitDirectiveModuleMT();
7898 // If this is not the end of the statement, report an error.
7899 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7900 reportParseError("unexpected token, expected end of statement");
7904 return false; // parseDirectiveModule has finished successfully.
7905 } else if (Option == "crc") {
7906 setModuleFeatureBits(Mips::FeatureCRC, "crc");
7908 // Synchronize the ABI Flags information with the FeatureBits information we
7910 getTargetStreamer().updateABIInfo(*this);
7912 // If printing assembly, use the recently updated ABI Flags information.
7913 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7915 getTargetStreamer().emitDirectiveModuleCRC();
7917 // If this is not the end of the statement, report an error.
7918 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7919 reportParseError("unexpected token, expected end of statement");
7923 return false; // parseDirectiveModule has finished successfully.
7924 } else if (Option == "nocrc") {
7925 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
7927 // Synchronize the ABI Flags information with the FeatureBits information we
7929 getTargetStreamer().updateABIInfo(*this);
7931 // If printing assembly, use the recently updated ABI Flags information.
7932 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7934 getTargetStreamer().emitDirectiveModuleNoCRC();
7936 // If this is not the end of the statement, report an error.
7937 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7938 reportParseError("unexpected token, expected end of statement");
7942 return false; // parseDirectiveModule has finished successfully.
7943 } else if (Option == "virt") {
7944 setModuleFeatureBits(Mips::FeatureVirt, "virt");
7946 // Synchronize the ABI Flags information with the FeatureBits information we
7948 getTargetStreamer().updateABIInfo(*this);
7950 // If printing assembly, use the recently updated ABI Flags information.
7951 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7953 getTargetStreamer().emitDirectiveModuleVirt();
7955 // If this is not the end of the statement, report an error.
7956 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7957 reportParseError("unexpected token, expected end of statement");
7961 return false; // parseDirectiveModule has finished successfully.
7962 } else if (Option == "novirt") {
7963 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
7965 // Synchronize the ABI Flags information with the FeatureBits information we
7967 getTargetStreamer().updateABIInfo(*this);
7969 // If printing assembly, use the recently updated ABI Flags information.
7970 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7972 getTargetStreamer().emitDirectiveModuleNoVirt();
7974 // If this is not the end of the statement, report an error.
7975 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7976 reportParseError("unexpected token, expected end of statement");
7980 return false; // parseDirectiveModule has finished successfully.
7981 } else if (Option == "ginv") {
7982 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
7984 // Synchronize the ABI Flags information with the FeatureBits information we
7986 getTargetStreamer().updateABIInfo(*this);
7988 // If printing assembly, use the recently updated ABI Flags information.
7989 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7991 getTargetStreamer().emitDirectiveModuleGINV();
7993 // If this is not the end of the statement, report an error.
7994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7995 reportParseError("unexpected token, expected end of statement");
7999 return false; // parseDirectiveModule has finished successfully.
8000 } else if (Option == "noginv") {
8001 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8003 // Synchronize the ABI Flags information with the FeatureBits information we
8005 getTargetStreamer().updateABIInfo(*this);
8007 // If printing assembly, use the recently updated ABI Flags information.
8008 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8010 getTargetStreamer().emitDirectiveModuleNoGINV();
8012 // If this is not the end of the statement, report an error.
8013 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8014 reportParseError("unexpected token, expected end of statement");
8018 return false; // parseDirectiveModule has finished successfully.
8020 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8024 /// parseDirectiveModuleFP
8028 bool MipsAsmParser::parseDirectiveModuleFP() {
8029 MCAsmParser &Parser = getParser();
8030 MCAsmLexer &Lexer = getLexer();
8032 if (Lexer.isNot(AsmToken::Equal)) {
8033 reportParseError("unexpected token, expected equals sign '='");
8036 Parser.Lex(); // Eat '=' token.
8038 MipsABIFlagsSection::FpABIKind FpABI;
8039 if (!parseFpABIValue(FpABI, ".module"))
8042 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8043 reportParseError("unexpected token, expected end of statement");
8047 // Synchronize the abiflags information with the FeatureBits information we
8049 getTargetStreamer().updateABIInfo(*this);
8051 // If printing assembly, use the recently updated abiflags information.
8052 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8053 // emitted at the end).
8054 getTargetStreamer().emitDirectiveModuleFP();
8056 Parser.Lex(); // Consume the EndOfStatement.
8060 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8061 StringRef Directive) {
8062 MCAsmParser &Parser = getParser();
8063 MCAsmLexer &Lexer = getLexer();
8064 bool ModuleLevelOptions = Directive == ".module";
8066 if (Lexer.is(AsmToken::Identifier)) {
8067 StringRef Value = Parser.getTok().getString();
8070 if (Value != "xx") {
8071 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8076 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8080 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8081 if (ModuleLevelOptions) {
8082 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8083 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8085 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8086 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8091 if (Lexer.is(AsmToken::Integer)) {
8092 unsigned Value = Parser.getTok().getIntVal();
8095 if (Value != 32 && Value != 64) {
8096 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8102 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8106 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8107 if (ModuleLevelOptions) {
8108 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8109 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8111 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8112 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8115 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8116 if (ModuleLevelOptions) {
8117 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8118 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8120 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8121 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8131 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8132 // This returns false if this function recognizes the directive
8133 // regardless of whether it is successfully handles or reports an
8134 // error. Otherwise it returns true to give the generic parser a
8135 // chance at recognizing it.
8137 MCAsmParser &Parser = getParser();
8138 StringRef IDVal = DirectiveID.getString();
8140 if (IDVal == ".cpload") {
8141 parseDirectiveCpLoad(DirectiveID.getLoc());
8144 if (IDVal == ".cprestore") {
8145 parseDirectiveCpRestore(DirectiveID.getLoc());
8148 if (IDVal == ".cplocal") {
8149 parseDirectiveCpLocal(DirectiveID.getLoc());
8152 if (IDVal == ".ent") {
8153 StringRef SymbolName;
8155 if (Parser.parseIdentifier(SymbolName)) {
8156 reportParseError("expected identifier after .ent");
8160 // There's an undocumented extension that allows an integer to
8161 // follow the name of the procedure which AFAICS is ignored by GAS.
8162 // Example: .ent foo,2
8163 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8164 if (getLexer().isNot(AsmToken::Comma)) {
8165 // Even though we accept this undocumented extension for compatibility
8166 // reasons, the additional integer argument does not actually change
8167 // the behaviour of the '.ent' directive, so we would like to discourage
8168 // its use. We do this by not referring to the extended version in
8169 // error messages which are not directly related to its use.
8170 reportParseError("unexpected token, expected end of statement");
8173 Parser.Lex(); // Eat the comma.
8174 const MCExpr *DummyNumber;
8175 int64_t DummyNumberVal;
8176 // If the user was explicitly trying to use the extended version,
8177 // we still give helpful extension-related error messages.
8178 if (Parser.parseExpression(DummyNumber)) {
8179 reportParseError("expected number after comma");
8182 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8183 reportParseError("expected an absolute expression after comma");
8188 // If this is not the end of the statement, report an error.
8189 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8190 reportParseError("unexpected token, expected end of statement");
8194 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8196 getTargetStreamer().emitDirectiveEnt(*Sym);
8198 IsCpRestoreSet = false;
8202 if (IDVal == ".end") {
8203 StringRef SymbolName;
8205 if (Parser.parseIdentifier(SymbolName)) {
8206 reportParseError("expected identifier after .end");
8210 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8211 reportParseError("unexpected token, expected end of statement");
8215 if (CurrentFn == nullptr) {
8216 reportParseError(".end used without .ent");
8220 if ((SymbolName != CurrentFn->getName())) {
8221 reportParseError(".end symbol does not match .ent symbol");
8225 getTargetStreamer().emitDirectiveEnd(SymbolName);
8226 CurrentFn = nullptr;
8227 IsCpRestoreSet = false;
8231 if (IDVal == ".frame") {
8232 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8233 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8234 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
8235 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8236 reportParseError("expected stack register");
8240 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8241 if (!StackRegOpnd.isGPRAsmReg()) {
8242 reportParseError(StackRegOpnd.getStartLoc(),
8243 "expected general purpose register");
8246 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8248 if (Parser.getTok().is(AsmToken::Comma))
8251 reportParseError("unexpected token, expected comma");
8255 // Parse the frame size.
8256 const MCExpr *FrameSize;
8257 int64_t FrameSizeVal;
8259 if (Parser.parseExpression(FrameSize)) {
8260 reportParseError("expected frame size value");
8264 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8265 reportParseError("frame size not an absolute expression");
8269 if (Parser.getTok().is(AsmToken::Comma))
8272 reportParseError("unexpected token, expected comma");
8276 // Parse the return register.
8278 ResTy = parseAnyRegister(TmpReg);
8279 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8280 reportParseError("expected return register");
8284 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8285 if (!ReturnRegOpnd.isGPRAsmReg()) {
8286 reportParseError(ReturnRegOpnd.getStartLoc(),
8287 "expected general purpose register");
8291 // If this is not the end of the statement, report an error.
8292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8293 reportParseError("unexpected token, expected end of statement");
8297 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8298 ReturnRegOpnd.getGPR32Reg());
8299 IsCpRestoreSet = false;
8303 if (IDVal == ".set") {
8304 parseDirectiveSet();
8308 if (IDVal == ".mask" || IDVal == ".fmask") {
8309 // .mask bitmask, frame_offset
8310 // bitmask: One bit for each register used.
8311 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8312 // first register is expected to be saved.
8314 // .mask 0x80000000, -4
8315 // .fmask 0x80000000, -4
8318 // Parse the bitmask
8319 const MCExpr *BitMask;
8322 if (Parser.parseExpression(BitMask)) {
8323 reportParseError("expected bitmask value");
8327 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8328 reportParseError("bitmask not an absolute expression");
8332 if (Parser.getTok().is(AsmToken::Comma))
8335 reportParseError("unexpected token, expected comma");
8339 // Parse the frame_offset
8340 const MCExpr *FrameOffset;
8341 int64_t FrameOffsetVal;
8343 if (Parser.parseExpression(FrameOffset)) {
8344 reportParseError("expected frame offset value");
8348 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8349 reportParseError("frame offset not an absolute expression");
8353 // If this is not the end of the statement, report an error.
8354 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8355 reportParseError("unexpected token, expected end of statement");
8359 if (IDVal == ".mask")
8360 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8362 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8366 if (IDVal == ".nan")
8367 return parseDirectiveNaN();
8369 if (IDVal == ".gpword") {
8370 parseDirectiveGpWord();
8374 if (IDVal == ".gpdword") {
8375 parseDirectiveGpDWord();
8379 if (IDVal == ".dtprelword") {
8380 parseDirectiveDtpRelWord();
8384 if (IDVal == ".dtpreldword") {
8385 parseDirectiveDtpRelDWord();
8389 if (IDVal == ".tprelword") {
8390 parseDirectiveTpRelWord();
8394 if (IDVal == ".tpreldword") {
8395 parseDirectiveTpRelDWord();
8399 if (IDVal == ".option") {
8400 parseDirectiveOption();
8404 if (IDVal == ".abicalls") {
8405 getTargetStreamer().emitDirectiveAbiCalls();
8406 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8407 Error(Parser.getTok().getLoc(),
8408 "unexpected token, expected end of statement");
8413 if (IDVal == ".cpsetup") {
8414 parseDirectiveCPSetup();
8417 if (IDVal == ".cpreturn") {
8418 parseDirectiveCPReturn();
8421 if (IDVal == ".module") {
8422 parseDirectiveModule();
8425 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8426 parseInternalDirectiveReallowModule();
8429 if (IDVal == ".insn") {
8430 parseInsnDirective();
8433 if (IDVal == ".rdata") {
8434 parseRSectionDirective(".rodata");
8437 if (IDVal == ".sbss") {
8438 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8441 if (IDVal == ".sdata") {
8442 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8449 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8450 // If this is not the end of the statement, report an error.
8451 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8452 reportParseError("unexpected token, expected end of statement");
8456 getTargetStreamer().reallowModuleDirective();
8458 getParser().Lex(); // Eat EndOfStatement token.
8462 extern "C" void LLVMInitializeMipsAsmParser() {
8463 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8464 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8465 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8466 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8469 #define GET_REGISTER_MATCHER
8470 #define GET_MATCHER_IMPLEMENTATION
8471 #define GET_MNEMONIC_SPELL_CHECKER
8472 #include "MipsGenAsmMatcher.inc"
8474 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8475 // Find the appropriate table for this asm variant.
8476 const MatchEntry *Start, *End;
8477 switch (VariantID) {
8478 default: llvm_unreachable("invalid variant!");
8479 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8481 // Search the table.
8482 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8483 return MnemonicRange.first != MnemonicRange.second;