[VPlan] Check VPWidenIntrinsicSC in VPRecipeWithIRFlags::classof.
[llvm-project.git] / llvm / lib / Target / Mips / AsmParser / MipsAsmParser.cpp
blobae1f4545c6a498e18072e2ccb8b145beff0529d3
1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2 //
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
6 //
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/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/BinaryFormat/ELF.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrDesc.h"
26 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCParser/MCAsmLexer.h"
29 #include "llvm/MC/MCParser/MCAsmParser.h"
30 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
31 #include "llvm/MC/MCParser/MCAsmParserUtils.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/TargetRegistry.h"
41 #include "llvm/Support/Alignment.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/raw_ostream.h"
51 #include "llvm/TargetParser/SubtargetFeature.h"
52 #include "llvm/TargetParser/Triple.h"
53 #include <algorithm>
54 #include <cassert>
55 #include <cstdint>
56 #include <memory>
57 #include <string>
58 #include <utility>
60 using namespace llvm;
62 #define DEBUG_TYPE "mips-asm-parser"
64 namespace llvm {
66 class MCInstrInfo;
68 } // end namespace llvm
70 extern cl::opt<bool> EmitJalrReloc;
72 namespace {
74 class MipsAssemblerOptions {
75 public:
76 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
78 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
85 unsigned getATRegIndex() const { return ATReg; }
86 bool setATRegIndex(unsigned Reg) {
87 if (Reg > 31)
88 return false;
90 ATReg = Reg;
91 return true;
94 bool isReorder() const { return Reorder; }
95 void setReorder() { Reorder = true; }
96 void setNoReorder() { Reorder = false; }
98 bool isMacro() const { return Macro; }
99 void setMacro() { Macro = true; }
100 void setNoMacro() { Macro = false; }
102 const FeatureBitset &getFeatures() const { return Features; }
103 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
105 // Set of features that are either architecture features or referenced
106 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
107 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
108 // The reason we need this mask is explained in the selectArch function.
109 // FIXME: Ideally we would like TableGen to generate this information.
110 static const FeatureBitset AllArchRelatedMask;
112 private:
113 unsigned ATReg = 1;
114 bool Reorder = true;
115 bool Macro = true;
116 FeatureBitset Features;
119 } // end anonymous namespace
121 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
130 Mips::FeatureNaN2008
133 namespace {
135 class MipsAsmParser : public MCTargetAsmParser {
136 MipsTargetStreamer &getTargetStreamer() {
137 assert(getParser().getStreamer().getTargetStreamer() &&
138 "do not have a target streamer");
139 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
140 return static_cast<MipsTargetStreamer &>(TS);
143 MipsABIInfo ABI;
144 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
145 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
146 // nullptr, which indicates that no function is currently
147 // selected. This usually happens after an '.end func'
148 // directive.
149 bool IsLittleEndian;
150 bool IsPicEnabled;
151 bool IsCpRestoreSet;
152 bool CurForbiddenSlotAttr;
153 int CpRestoreOffset;
154 unsigned GPReg;
155 unsigned CpSaveLocation;
156 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
157 bool CpSaveLocationIsRegister;
159 // Map of register aliases created via the .set directive.
160 StringMap<AsmToken> RegisterSets;
162 // Print a warning along with its fix-it message at the given range.
163 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
164 SMRange Range, bool ShowColors = true);
166 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
168 #define GET_ASSEMBLER_HEADER
169 #include "MipsGenAsmMatcher.inc"
171 unsigned
172 checkEarlyTargetMatchPredicate(MCInst &Inst,
173 const OperandVector &Operands) override;
174 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
176 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
177 OperandVector &Operands, MCStreamer &Out,
178 uint64_t &ErrorInfo,
179 bool MatchingInlineAsm) override;
181 /// Parse a register as used in CFI directives
182 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
183 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
184 SMLoc &EndLoc) override;
186 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
188 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
190 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
192 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
193 SMLoc NameLoc, OperandVector &Operands) override;
195 bool ParseDirective(AsmToken DirectiveID) override;
197 ParseStatus parseMemOperand(OperandVector &Operands);
198 ParseStatus matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
199 StringRef Identifier, SMLoc S);
200 ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands,
201 const AsmToken &Token, SMLoc S);
202 ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
203 ParseStatus parseAnyRegister(OperandVector &Operands);
204 ParseStatus parseImm(OperandVector &Operands);
205 ParseStatus parseJumpTarget(OperandVector &Operands);
206 ParseStatus parseInvNum(OperandVector &Operands);
207 ParseStatus parseRegisterList(OperandVector &Operands);
209 bool searchSymbolAlias(OperandVector &Operands);
211 bool parseOperand(OperandVector &, StringRef Mnemonic);
213 enum MacroExpanderResultTy {
214 MER_NotAMacro,
215 MER_Success,
216 MER_Fail,
219 // Expands assembly pseudo instructions.
220 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
221 MCStreamer &Out,
222 const MCSubtargetInfo *STI);
224 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
225 const MCSubtargetInfo *STI);
227 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
228 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
229 MCStreamer &Out, const MCSubtargetInfo *STI);
231 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
232 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
233 MCStreamer &Out, const MCSubtargetInfo *STI);
235 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
237 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
238 MCStreamer &Out, const MCSubtargetInfo *STI);
240 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI);
242 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
243 const MCSubtargetInfo *STI);
244 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
245 const MCSubtargetInfo *STI);
246 bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
247 MCStreamer &Out, const MCSubtargetInfo *STI);
249 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
250 const MCOperand &Offset, bool Is32BitAddress,
251 SMLoc IDLoc, MCStreamer &Out,
252 const MCSubtargetInfo *STI);
254 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI);
257 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI, bool IsLoad);
259 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
260 const MCSubtargetInfo *STI, bool IsLoad);
262 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
263 const MCSubtargetInfo *STI);
265 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
268 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
271 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
274 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI, const bool IsMips64,
276 const bool Signed);
278 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
279 MCStreamer &Out, const MCSubtargetInfo *STI);
281 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
282 const MCSubtargetInfo *STI);
284 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
285 const MCSubtargetInfo *STI);
287 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
288 const MCSubtargetInfo *STI);
290 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291 const MCSubtargetInfo *STI);
293 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
294 const MCSubtargetInfo *STI);
296 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
299 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
300 const MCSubtargetInfo *STI);
302 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
303 const MCSubtargetInfo *STI);
305 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
306 MCStreamer &Out, const MCSubtargetInfo *STI);
307 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308 const MCSubtargetInfo *STI);
309 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310 const MCSubtargetInfo *STI);
311 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
312 const MCSubtargetInfo *STI);
314 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
315 const MCSubtargetInfo *STI);
317 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
318 const MCSubtargetInfo *STI);
320 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
321 const MCSubtargetInfo *STI);
323 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
324 const MCSubtargetInfo *STI);
326 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
327 const MCSubtargetInfo *STI);
329 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
330 const MCSubtargetInfo *STI, bool IsLoad);
332 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
333 const MCSubtargetInfo *STI);
335 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
336 const MCSubtargetInfo *STI);
338 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
339 const MCSubtargetInfo *STI);
341 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
342 const MCSubtargetInfo *STI);
344 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
345 const MCSubtargetInfo *STI);
347 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
348 const MCSubtargetInfo *STI);
350 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
351 const MCSubtargetInfo *STI);
353 bool reportParseError(const Twine &ErrorMsg);
354 bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
356 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
358 bool parseSetMips0Directive();
359 bool parseSetArchDirective();
360 bool parseSetFeature(uint64_t Feature);
361 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
362 bool parseDirectiveCpAdd(SMLoc Loc);
363 bool parseDirectiveCpLoad(SMLoc Loc);
364 bool parseDirectiveCpLocal(SMLoc Loc);
365 bool parseDirectiveCpRestore(SMLoc Loc);
366 bool parseDirectiveCPSetup();
367 bool parseDirectiveCPReturn();
368 bool parseDirectiveNaN();
369 bool parseDirectiveSet();
370 bool parseDirectiveOption();
371 bool parseInsnDirective();
372 bool parseRSectionDirective(StringRef Section);
373 bool parseSSectionDirective(StringRef Section, unsigned Type);
375 bool parseSetAtDirective();
376 bool parseSetNoAtDirective();
377 bool parseSetMacroDirective();
378 bool parseSetNoMacroDirective();
379 bool parseSetMsaDirective();
380 bool parseSetNoMsaDirective();
381 bool parseSetNoDspDirective();
382 bool parseSetNoMips3DDirective();
383 bool parseSetReorderDirective();
384 bool parseSetNoReorderDirective();
385 bool parseSetMips16Directive();
386 bool parseSetNoMips16Directive();
387 bool parseSetFpDirective();
388 bool parseSetOddSPRegDirective();
389 bool parseSetNoOddSPRegDirective();
390 bool parseSetPopDirective();
391 bool parseSetPushDirective();
392 bool parseSetSoftFloatDirective();
393 bool parseSetHardFloatDirective();
394 bool parseSetMtDirective();
395 bool parseSetNoMtDirective();
396 bool parseSetNoCRCDirective();
397 bool parseSetNoVirtDirective();
398 bool parseSetNoGINVDirective();
400 bool parseSetAssignment();
402 bool parseDirectiveGpWord();
403 bool parseDirectiveGpDWord();
404 bool parseDirectiveDtpRelWord();
405 bool parseDirectiveDtpRelDWord();
406 bool parseDirectiveTpRelWord();
407 bool parseDirectiveTpRelDWord();
408 bool parseDirectiveModule();
409 bool parseDirectiveModuleFP();
410 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
411 StringRef Directive);
413 bool parseInternalDirectiveReallowModule();
415 bool eatComma(StringRef ErrorStr);
417 int matchCPURegisterName(StringRef Symbol);
419 int matchHWRegsRegisterName(StringRef Symbol);
421 int matchFPURegisterName(StringRef Name);
423 int matchFCCRegisterName(StringRef Name);
425 int matchACRegisterName(StringRef Name);
427 int matchMSA128RegisterName(StringRef Name);
429 int matchMSA128CtrlRegisterName(StringRef Name);
431 unsigned getReg(int RC, int RegNo);
433 /// Returns the internal register number for the current AT. Also checks if
434 /// the current AT is unavailable (set to $0) and gives an error if it is.
435 /// This should be used in pseudo-instruction expansions which need AT.
436 unsigned getATReg(SMLoc Loc);
438 bool canUseATReg();
440 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
441 const MCSubtargetInfo *STI);
443 // Helper function that checks if the value of a vector index is within the
444 // boundaries of accepted values for each RegisterKind
445 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
446 bool validateMSAIndex(int Val, int RegKind);
448 // Selects a new architecture by updating the FeatureBits with the necessary
449 // info including implied dependencies.
450 // Internally, it clears all the feature bits related to *any* architecture
451 // and selects the new one using the ToggleFeature functionality of the
452 // MCSubtargetInfo object that handles implied dependencies. The reason we
453 // clear all the arch related bits manually is because ToggleFeature only
454 // clears the features that imply the feature being cleared and not the
455 // features implied by the feature being cleared. This is easier to see
456 // with an example:
457 // --------------------------------------------------
458 // | Feature | Implies |
459 // | -------------------------------------------------|
460 // | FeatureMips1 | None |
461 // | FeatureMips2 | FeatureMips1 |
462 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
463 // | FeatureMips4 | FeatureMips3 |
464 // | ... | |
465 // --------------------------------------------------
467 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
468 // FeatureMipsGP64 | FeatureMips1)
469 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
470 void selectArch(StringRef ArchFeature) {
471 MCSubtargetInfo &STI = copySTI();
472 FeatureBitset FeatureBits = STI.getFeatureBits();
473 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
474 STI.setFeatureBits(FeatureBits);
475 setAvailableFeatures(
476 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
477 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
480 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
481 if (!(getSTI().hasFeature(Feature))) {
482 MCSubtargetInfo &STI = copySTI();
483 setAvailableFeatures(
484 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
485 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
489 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
490 if (getSTI().hasFeature(Feature)) {
491 MCSubtargetInfo &STI = copySTI();
492 setAvailableFeatures(
493 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
494 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
498 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
499 setFeatureBits(Feature, FeatureString);
500 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
503 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
504 clearFeatureBits(Feature, FeatureString);
505 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
508 public:
509 enum MipsMatchResultTy {
510 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
511 Match_RequiresDifferentOperands,
512 Match_RequiresNoZeroRegister,
513 Match_RequiresSameSrcAndDst,
514 Match_NoFCCRegisterForCurrentISA,
515 Match_NonZeroOperandForSync,
516 Match_NonZeroOperandForMTCX,
517 Match_RequiresPosSizeRange0_32,
518 Match_RequiresPosSizeRange33_64,
519 Match_RequiresPosSizeUImm6,
520 #define GET_OPERAND_DIAGNOSTIC_TYPES
521 #include "MipsGenAsmMatcher.inc"
522 #undef GET_OPERAND_DIAGNOSTIC_TYPES
525 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
526 const MCInstrInfo &MII, const MCTargetOptions &Options)
527 : MCTargetAsmParser(Options, sti, MII),
528 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
529 sti.getCPU(), Options)) {
530 MCAsmParserExtension::Initialize(parser);
532 parser.addAliasForDirective(".asciiz", ".asciz");
533 parser.addAliasForDirective(".hword", ".2byte");
534 parser.addAliasForDirective(".word", ".4byte");
535 parser.addAliasForDirective(".dword", ".8byte");
537 // Initialize the set of available features.
538 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
540 // Remember the initial assembler options. The user can not modify these.
541 AssemblerOptions.push_back(
542 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
544 // Create an assembler options environment for the user to modify.
545 AssemblerOptions.push_back(
546 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
551 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
553 CurrentFn = nullptr;
555 CurForbiddenSlotAttr = false;
556 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
558 IsCpRestoreSet = false;
559 CpRestoreOffset = -1;
560 GPReg = ABI.GetGlobalPtr();
562 const Triple &TheTriple = sti.getTargetTriple();
563 IsLittleEndian = TheTriple.isLittleEndian();
565 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
566 report_fatal_error("microMIPS64R6 is not supported", false);
568 if (!isABI_O32() && inMicroMipsMode())
569 report_fatal_error("microMIPS64 is not supported", false);
572 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
573 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
575 bool isGP64bit() const {
576 return getSTI().hasFeature(Mips::FeatureGP64Bit);
579 bool isFP64bit() const {
580 return getSTI().hasFeature(Mips::FeatureFP64Bit);
583 bool isJalrRelocAvailable(const MCExpr *JalExpr) {
584 if (!EmitJalrReloc)
585 return false;
586 MCValue Res;
587 if (!JalExpr->evaluateAsRelocatable(Res, nullptr, nullptr))
588 return false;
589 if (Res.getSymB() != nullptr)
590 return false;
591 if (Res.getConstant() != 0)
592 return ABI.IsN32() || ABI.IsN64();
593 return true;
596 const MipsABIInfo &getABI() const { return ABI; }
597 bool isABI_N32() const { return ABI.IsN32(); }
598 bool isABI_N64() const { return ABI.IsN64(); }
599 bool isABI_O32() const { return ABI.IsO32(); }
600 bool isABI_FPXX() const {
601 return getSTI().hasFeature(Mips::FeatureFPXX);
604 bool useOddSPReg() const {
605 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
608 bool inMicroMipsMode() const {
609 return getSTI().hasFeature(Mips::FeatureMicroMips);
612 bool hasMips1() const {
613 return getSTI().hasFeature(Mips::FeatureMips1);
616 bool hasMips2() const {
617 return getSTI().hasFeature(Mips::FeatureMips2);
620 bool hasMips3() const {
621 return getSTI().hasFeature(Mips::FeatureMips3);
624 bool hasMips4() const {
625 return getSTI().hasFeature(Mips::FeatureMips4);
628 bool hasMips5() const {
629 return getSTI().hasFeature(Mips::FeatureMips5);
632 bool hasMips32() const {
633 return getSTI().hasFeature(Mips::FeatureMips32);
636 bool hasMips64() const {
637 return getSTI().hasFeature(Mips::FeatureMips64);
640 bool hasMips32r2() const {
641 return getSTI().hasFeature(Mips::FeatureMips32r2);
644 bool hasMips64r2() const {
645 return getSTI().hasFeature(Mips::FeatureMips64r2);
648 bool hasMips32r3() const {
649 return (getSTI().hasFeature(Mips::FeatureMips32r3));
652 bool hasMips64r3() const {
653 return (getSTI().hasFeature(Mips::FeatureMips64r3));
656 bool hasMips32r5() const {
657 return (getSTI().hasFeature(Mips::FeatureMips32r5));
660 bool hasMips64r5() const {
661 return (getSTI().hasFeature(Mips::FeatureMips64r5));
664 bool hasMips32r6() const {
665 return getSTI().hasFeature(Mips::FeatureMips32r6);
668 bool hasMips64r6() const {
669 return getSTI().hasFeature(Mips::FeatureMips64r6);
672 bool hasDSP() const {
673 return getSTI().hasFeature(Mips::FeatureDSP);
676 bool hasDSPR2() const {
677 return getSTI().hasFeature(Mips::FeatureDSPR2);
680 bool hasDSPR3() const {
681 return getSTI().hasFeature(Mips::FeatureDSPR3);
684 bool hasMSA() const {
685 return getSTI().hasFeature(Mips::FeatureMSA);
688 bool hasCnMips() const {
689 return (getSTI().hasFeature(Mips::FeatureCnMips));
692 bool hasCnMipsP() const {
693 return (getSTI().hasFeature(Mips::FeatureCnMipsP));
696 bool inPicMode() {
697 return IsPicEnabled;
700 bool inMips16Mode() const {
701 return getSTI().hasFeature(Mips::FeatureMips16);
704 bool useTraps() const {
705 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
708 bool useSoftFloat() const {
709 return getSTI().hasFeature(Mips::FeatureSoftFloat);
711 bool hasMT() const {
712 return getSTI().hasFeature(Mips::FeatureMT);
715 bool hasCRC() const {
716 return getSTI().hasFeature(Mips::FeatureCRC);
719 bool hasVirt() const {
720 return getSTI().hasFeature(Mips::FeatureVirt);
723 bool hasGINV() const {
724 return getSTI().hasFeature(Mips::FeatureGINV);
727 bool hasForbiddenSlot(const MCInstrDesc &MCID) const {
728 return !inMicroMipsMode() && (MCID.TSFlags & MipsII::HasForbiddenSlot);
731 bool SafeInForbiddenSlot(const MCInstrDesc &MCID) const {
732 return !(MCID.TSFlags & MipsII::IsCTI);
735 void onEndOfFile() override;
737 /// Warn if RegIndex is the same as the current AT.
738 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
740 void warnIfNoMacro(SMLoc Loc);
742 bool isLittle() const { return IsLittleEndian; }
744 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
745 AsmToken::TokenKind OperatorToken,
746 MCContext &Ctx) override {
747 switch(OperatorToken) {
748 default:
749 llvm_unreachable("Unknown token");
750 return nullptr;
751 case AsmToken::PercentCall16:
752 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
753 case AsmToken::PercentCall_Hi:
754 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
755 case AsmToken::PercentCall_Lo:
756 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
757 case AsmToken::PercentDtprel_Hi:
758 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
759 case AsmToken::PercentDtprel_Lo:
760 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
761 case AsmToken::PercentGot:
762 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
763 case AsmToken::PercentGot_Disp:
764 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
765 case AsmToken::PercentGot_Hi:
766 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
767 case AsmToken::PercentGot_Lo:
768 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
769 case AsmToken::PercentGot_Ofst:
770 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
771 case AsmToken::PercentGot_Page:
772 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
773 case AsmToken::PercentGottprel:
774 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
775 case AsmToken::PercentGp_Rel:
776 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
777 case AsmToken::PercentHi:
778 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
779 case AsmToken::PercentHigher:
780 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
781 case AsmToken::PercentHighest:
782 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
783 case AsmToken::PercentLo:
784 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
785 case AsmToken::PercentNeg:
786 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
787 case AsmToken::PercentPcrel_Hi:
788 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
789 case AsmToken::PercentPcrel_Lo:
790 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
791 case AsmToken::PercentTlsgd:
792 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
793 case AsmToken::PercentTlsldm:
794 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
795 case AsmToken::PercentTprel_Hi:
796 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
797 case AsmToken::PercentTprel_Lo:
798 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
802 bool areEqualRegs(const MCParsedAsmOperand &Op1,
803 const MCParsedAsmOperand &Op2) const override;
806 /// MipsOperand - Instances of this class represent a parsed Mips machine
807 /// instruction.
808 class MipsOperand : public MCParsedAsmOperand {
809 public:
810 /// Broad categories of register classes
811 /// The exact class is finalized by the render method.
812 enum RegKind {
813 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
814 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
815 /// isFP64bit())
816 RegKind_FCC = 4, /// FCC
817 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
818 RegKind_MSACtrl = 16, /// MSA control registers
819 RegKind_COP2 = 32, /// COP2
820 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
821 /// context).
822 RegKind_CCR = 128, /// CCR
823 RegKind_HWRegs = 256, /// HWRegs
824 RegKind_COP3 = 512, /// COP3
825 RegKind_COP0 = 1024, /// COP0
826 /// Potentially any (e.g. $1)
827 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
828 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
829 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
832 private:
833 enum KindTy {
834 k_Immediate, /// An immediate (possibly involving symbol references)
835 k_Memory, /// Base + Offset Memory Address
836 k_RegisterIndex, /// A register index in one or more RegKind.
837 k_Token, /// A simple token
838 k_RegList, /// A physical register list
839 } Kind;
841 public:
842 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(K), AsmParser(Parser) {}
844 ~MipsOperand() override {
845 switch (Kind) {
846 case k_Memory:
847 delete Mem.Base;
848 break;
849 case k_RegList:
850 delete RegList.List;
851 break;
852 case k_Immediate:
853 case k_RegisterIndex:
854 case k_Token:
855 break;
859 private:
860 /// For diagnostics, and checking the assembler temporary
861 MipsAsmParser &AsmParser;
863 struct Token {
864 const char *Data;
865 unsigned Length;
868 struct RegIdxOp {
869 unsigned Index; /// Index into the register class
870 RegKind Kind; /// Bitfield of the kinds it could possibly be
871 struct Token Tok; /// The input token this operand originated from.
872 const MCRegisterInfo *RegInfo;
875 struct ImmOp {
876 const MCExpr *Val;
879 struct MemOp {
880 MipsOperand *Base;
881 const MCExpr *Off;
884 struct RegListOp {
885 SmallVector<unsigned, 10> *List;
888 union {
889 struct Token Tok;
890 struct RegIdxOp RegIdx;
891 struct ImmOp Imm;
892 struct MemOp Mem;
893 struct RegListOp RegList;
896 SMLoc StartLoc, EndLoc;
898 /// Internal constructor for register kinds
899 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
900 RegKind RegKind,
901 const MCRegisterInfo *RegInfo,
902 SMLoc S, SMLoc E,
903 MipsAsmParser &Parser) {
904 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
905 Op->RegIdx.Index = Index;
906 Op->RegIdx.RegInfo = RegInfo;
907 Op->RegIdx.Kind = RegKind;
908 Op->RegIdx.Tok.Data = Str.data();
909 Op->RegIdx.Tok.Length = Str.size();
910 Op->StartLoc = S;
911 Op->EndLoc = E;
912 return Op;
915 public:
916 /// Coerce the register to GPR32 and return the real register for the current
917 /// target.
918 unsigned getGPR32Reg() const {
919 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
920 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
921 unsigned ClassID = Mips::GPR32RegClassID;
922 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
925 /// Coerce the register to GPR32 and return the real register for the current
926 /// target.
927 unsigned getGPRMM16Reg() const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
929 unsigned ClassID = Mips::GPR32RegClassID;
930 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
933 /// Coerce the register to GPR64 and return the real register for the current
934 /// target.
935 unsigned getGPR64Reg() const {
936 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
937 unsigned ClassID = Mips::GPR64RegClassID;
938 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
941 private:
942 /// Coerce the register to AFGR64 and return the real register for the current
943 /// target.
944 unsigned getAFGR64Reg() const {
945 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
946 if (RegIdx.Index % 2 != 0)
947 AsmParser.Warning(StartLoc, "Float register should be even.");
948 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
949 .getRegister(RegIdx.Index / 2);
952 /// Coerce the register to FGR64 and return the real register for the current
953 /// target.
954 unsigned getFGR64Reg() const {
955 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
956 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
957 .getRegister(RegIdx.Index);
960 /// Coerce the register to FGR32 and return the real register for the current
961 /// target.
962 unsigned getFGR32Reg() const {
963 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
964 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
965 .getRegister(RegIdx.Index);
968 /// Coerce the register to FCC and return the real register for the current
969 /// target.
970 unsigned getFCCReg() const {
971 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
972 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
973 .getRegister(RegIdx.Index);
976 /// Coerce the register to MSA128 and return the real register for the current
977 /// target.
978 unsigned getMSA128Reg() const {
979 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
980 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
981 // identical
982 unsigned ClassID = Mips::MSA128BRegClassID;
983 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
986 /// Coerce the register to MSACtrl and return the real register for the
987 /// current target.
988 unsigned getMSACtrlReg() const {
989 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
990 unsigned ClassID = Mips::MSACtrlRegClassID;
991 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
994 /// Coerce the register to COP0 and return the real register for the
995 /// current target.
996 unsigned getCOP0Reg() const {
997 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
998 unsigned ClassID = Mips::COP0RegClassID;
999 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1002 /// Coerce the register to COP2 and return the real register for the
1003 /// current target.
1004 unsigned getCOP2Reg() const {
1005 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
1006 unsigned ClassID = Mips::COP2RegClassID;
1007 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1010 /// Coerce the register to COP3 and return the real register for the
1011 /// current target.
1012 unsigned getCOP3Reg() const {
1013 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
1014 unsigned ClassID = Mips::COP3RegClassID;
1015 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1018 /// Coerce the register to ACC64DSP and return the real register for the
1019 /// current target.
1020 unsigned getACC64DSPReg() const {
1021 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1022 unsigned ClassID = Mips::ACC64DSPRegClassID;
1023 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1026 /// Coerce the register to HI32DSP and return the real register for the
1027 /// current target.
1028 unsigned getHI32DSPReg() const {
1029 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1030 unsigned ClassID = Mips::HI32DSPRegClassID;
1031 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1034 /// Coerce the register to LO32DSP and return the real register for the
1035 /// current target.
1036 unsigned getLO32DSPReg() const {
1037 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1038 unsigned ClassID = Mips::LO32DSPRegClassID;
1039 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1042 /// Coerce the register to CCR and return the real register for the
1043 /// current target.
1044 unsigned getCCRReg() const {
1045 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
1046 unsigned ClassID = Mips::CCRRegClassID;
1047 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1050 /// Coerce the register to HWRegs and return the real register for the
1051 /// current target.
1052 unsigned getHWRegsReg() const {
1053 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
1054 unsigned ClassID = Mips::HWRegsRegClassID;
1055 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1058 public:
1059 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1060 // Add as immediate when possible. Null MCExpr = 0.
1061 if (!Expr)
1062 Inst.addOperand(MCOperand::createImm(0));
1063 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1064 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1065 else
1066 Inst.addOperand(MCOperand::createExpr(Expr));
1069 void addRegOperands(MCInst &Inst, unsigned N) const {
1070 llvm_unreachable("Use a custom parser instead");
1073 /// Render the operand to an MCInst as a GPR32
1074 /// Asserts if the wrong number of operands are requested, or the operand
1075 /// is not a k_RegisterIndex compatible with RegKind_GPR
1076 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1077 assert(N == 1 && "Invalid number of operands!");
1078 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1081 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1082 assert(N == 1 && "Invalid number of operands!");
1083 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1086 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1087 assert(N == 1 && "Invalid number of operands!");
1088 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1091 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1096 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1097 assert(N == 1 && "Invalid number of operands!");
1098 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1101 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1102 assert(N == 1 && "Invalid number of operands!");
1103 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1106 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1107 assert(N == 1 && "Invalid number of operands!");
1108 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1111 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1112 unsigned N) const {
1113 assert(N == 1 && "Invalid number of operands!");
1114 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1117 /// Render the operand to an MCInst as a GPR64
1118 /// Asserts if the wrong number of operands are requested, or the operand
1119 /// is not a k_RegisterIndex compatible with RegKind_GPR
1120 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1121 assert(N == 1 && "Invalid number of operands!");
1122 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1125 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1126 assert(N == 1 && "Invalid number of operands!");
1127 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1130 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1131 assert(N == 1 && "Invalid number of operands!");
1132 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1135 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1136 assert(N == 1 && "Invalid number of operands!");
1137 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1140 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1141 assert(N == 1 && "Invalid number of operands!");
1142 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1145 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1146 assert(N == 1 && "Invalid number of operands!");
1147 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1148 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1149 // FIXME: This should propagate failure up to parseStatement.
1150 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1151 AsmParser.getParser().printError(
1152 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1153 "registers");
1156 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1157 assert(N == 1 && "Invalid number of operands!");
1158 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1159 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1160 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1161 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1162 "registers");
1165 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1166 assert(N == 1 && "Invalid number of operands!");
1167 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1170 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1171 assert(N == 1 && "Invalid number of operands!");
1172 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1175 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1176 assert(N == 1 && "Invalid number of operands!");
1177 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1180 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1181 assert(N == 1 && "Invalid number of operands!");
1182 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1185 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1186 assert(N == 1 && "Invalid number of operands!");
1187 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1190 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1191 assert(N == 1 && "Invalid number of operands!");
1192 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1195 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1196 assert(N == 1 && "Invalid number of operands!");
1197 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1200 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1201 assert(N == 1 && "Invalid number of operands!");
1202 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1205 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1206 assert(N == 1 && "Invalid number of operands!");
1207 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1210 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1211 assert(N == 1 && "Invalid number of operands!");
1212 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1215 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1216 assert(N == 1 && "Invalid number of operands!");
1217 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1220 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1221 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1222 assert(N == 1 && "Invalid number of operands!");
1223 uint64_t Imm = getConstantImm() - Offset;
1224 Imm &= (1ULL << Bits) - 1;
1225 Imm += Offset;
1226 Imm += AdjustOffset;
1227 Inst.addOperand(MCOperand::createImm(Imm));
1230 template <unsigned Bits>
1231 void addSImmOperands(MCInst &Inst, unsigned N) const {
1232 if (isImm() && !isConstantImm()) {
1233 addExpr(Inst, getImm());
1234 return;
1236 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1239 template <unsigned Bits>
1240 void addUImmOperands(MCInst &Inst, unsigned N) const {
1241 if (isImm() && !isConstantImm()) {
1242 addExpr(Inst, getImm());
1243 return;
1245 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1248 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1249 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1250 assert(N == 1 && "Invalid number of operands!");
1251 int64_t Imm = getConstantImm() - Offset;
1252 Imm = SignExtend64<Bits>(Imm);
1253 Imm += Offset;
1254 Imm += AdjustOffset;
1255 Inst.addOperand(MCOperand::createImm(Imm));
1258 void addImmOperands(MCInst &Inst, unsigned N) const {
1259 assert(N == 1 && "Invalid number of operands!");
1260 const MCExpr *Expr = getImm();
1261 addExpr(Inst, Expr);
1264 void addMemOperands(MCInst &Inst, unsigned N) const {
1265 assert(N == 2 && "Invalid number of operands!");
1267 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1268 ? getMemBase()->getGPR64Reg()
1269 : getMemBase()->getGPR32Reg()));
1271 const MCExpr *Expr = getMemOff();
1272 addExpr(Inst, Expr);
1275 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1276 assert(N == 2 && "Invalid number of operands!");
1278 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1280 const MCExpr *Expr = getMemOff();
1281 addExpr(Inst, Expr);
1284 void addRegListOperands(MCInst &Inst, unsigned N) const {
1285 assert(N == 1 && "Invalid number of operands!");
1287 for (auto RegNo : getRegList())
1288 Inst.addOperand(MCOperand::createReg(RegNo));
1291 bool isReg() const override {
1292 // As a special case until we sort out the definition of div/divu, accept
1293 // $0/$zero here so that MCK_ZERO works correctly.
1294 return isGPRAsmReg() && RegIdx.Index == 0;
1297 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1298 bool isImm() const override { return Kind == k_Immediate; }
1300 bool isConstantImm() const {
1301 int64_t Res;
1302 return isImm() && getImm()->evaluateAsAbsolute(Res);
1305 bool isConstantImmz() const {
1306 return isConstantImm() && getConstantImm() == 0;
1309 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1310 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1313 template <unsigned Bits> bool isSImm() const {
1314 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1317 template <unsigned Bits> bool isUImm() const {
1318 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1321 template <unsigned Bits> bool isAnyImm() const {
1322 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1323 isUInt<Bits>(getConstantImm()))
1324 : isImm();
1327 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1328 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1331 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1332 return isConstantImm() && getConstantImm() >= Bottom &&
1333 getConstantImm() <= Top;
1336 bool isToken() const override {
1337 // Note: It's not possible to pretend that other operand kinds are tokens.
1338 // The matcher emitter checks tokens first.
1339 return Kind == k_Token;
1342 bool isMem() const override { return Kind == k_Memory; }
1344 bool isConstantMemOff() const {
1345 return isMem() && isa<MCConstantExpr>(getMemOff());
1348 // Allow relocation operators.
1349 template <unsigned Bits, unsigned ShiftAmount = 0>
1350 bool isMemWithSimmOffset() const {
1351 if (!isMem())
1352 return false;
1353 if (!getMemBase()->isGPRAsmReg())
1354 return false;
1355 if (isa<MCTargetExpr>(getMemOff()) ||
1356 (isConstantMemOff() &&
1357 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1358 return true;
1359 MCValue Res;
1360 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1361 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1364 bool isMemWithPtrSizeOffset() const {
1365 if (!isMem())
1366 return false;
1367 if (!getMemBase()->isGPRAsmReg())
1368 return false;
1369 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1370 if (isa<MCTargetExpr>(getMemOff()) ||
1371 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1372 return true;
1373 MCValue Res;
1374 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1375 return IsReloc && isIntN(PtrBits, Res.getConstant());
1378 bool isMemWithGRPMM16Base() const {
1379 return isMem() && getMemBase()->isMM16AsmReg();
1382 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1383 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1384 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1387 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1388 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1389 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1390 && (getMemBase()->getGPR32Reg() == Mips::SP);
1393 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1394 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1395 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1396 && (getMemBase()->getGPR32Reg() == Mips::GP);
1399 template <unsigned Bits, unsigned ShiftLeftAmount>
1400 bool isScaledUImm() const {
1401 return isConstantImm() &&
1402 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1405 template <unsigned Bits, unsigned ShiftLeftAmount>
1406 bool isScaledSImm() const {
1407 if (isConstantImm() &&
1408 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1409 return true;
1410 // Operand can also be a symbol or symbol plus
1411 // offset in case of relocations.
1412 if (Kind != k_Immediate)
1413 return false;
1414 MCValue Res;
1415 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1416 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1419 bool isRegList16() const {
1420 if (!isRegList())
1421 return false;
1423 int Size = RegList.List->size();
1424 if (Size < 2 || Size > 5)
1425 return false;
1427 unsigned R0 = RegList.List->front();
1428 unsigned R1 = RegList.List->back();
1429 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1430 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1431 return false;
1433 int PrevReg = *RegList.List->begin();
1434 for (int i = 1; i < Size - 1; i++) {
1435 int Reg = (*(RegList.List))[i];
1436 if ( Reg != PrevReg + 1)
1437 return false;
1438 PrevReg = Reg;
1441 return true;
1444 bool isInvNum() const { return Kind == k_Immediate; }
1446 bool isLSAImm() const {
1447 if (!isConstantImm())
1448 return false;
1449 int64_t Val = getConstantImm();
1450 return 1 <= Val && Val <= 4;
1453 bool isRegList() const { return Kind == k_RegList; }
1455 StringRef getToken() const {
1456 assert(Kind == k_Token && "Invalid access!");
1457 return StringRef(Tok.Data, Tok.Length);
1460 MCRegister getReg() const override {
1461 // As a special case until we sort out the definition of div/divu, accept
1462 // $0/$zero here so that MCK_ZERO works correctly.
1463 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1464 RegIdx.Kind & RegKind_GPR)
1465 return getGPR32Reg(); // FIXME: GPR64 too
1467 llvm_unreachable("Invalid access!");
1468 return 0;
1471 const MCExpr *getImm() const {
1472 assert((Kind == k_Immediate) && "Invalid access!");
1473 return Imm.Val;
1476 int64_t getConstantImm() const {
1477 const MCExpr *Val = getImm();
1478 int64_t Value = 0;
1479 (void)Val->evaluateAsAbsolute(Value);
1480 return Value;
1483 MipsOperand *getMemBase() const {
1484 assert((Kind == k_Memory) && "Invalid access!");
1485 return Mem.Base;
1488 const MCExpr *getMemOff() const {
1489 assert((Kind == k_Memory) && "Invalid access!");
1490 return Mem.Off;
1493 int64_t getConstantMemOff() const {
1494 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1497 const SmallVectorImpl<unsigned> &getRegList() const {
1498 assert((Kind == k_RegList) && "Invalid access!");
1499 return *(RegList.List);
1502 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1503 MipsAsmParser &Parser) {
1504 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1505 Op->Tok.Data = Str.data();
1506 Op->Tok.Length = Str.size();
1507 Op->StartLoc = S;
1508 Op->EndLoc = S;
1509 return Op;
1512 /// Create a numeric register (e.g. $1). The exact register remains
1513 /// unresolved until an instruction successfully matches
1514 static std::unique_ptr<MipsOperand>
1515 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1516 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1517 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1518 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1521 /// Create a register that is definitely a GPR.
1522 /// This is typically only used for named registers such as $gp.
1523 static std::unique_ptr<MipsOperand>
1524 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1525 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1526 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1529 /// Create a register that is definitely a FGR.
1530 /// This is typically only used for named registers such as $f0.
1531 static std::unique_ptr<MipsOperand>
1532 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1533 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1534 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1537 /// Create a register that is definitely a HWReg.
1538 /// This is typically only used for named registers such as $hwr_cpunum.
1539 static std::unique_ptr<MipsOperand>
1540 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1541 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1542 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1545 /// Create a register that is definitely an FCC.
1546 /// This is typically only used for named registers such as $fcc0.
1547 static std::unique_ptr<MipsOperand>
1548 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1549 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1550 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1553 /// Create a register that is definitely an ACC.
1554 /// This is typically only used for named registers such as $ac0.
1555 static std::unique_ptr<MipsOperand>
1556 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1557 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1558 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1561 /// Create a register that is definitely an MSA128.
1562 /// This is typically only used for named registers such as $w0.
1563 static std::unique_ptr<MipsOperand>
1564 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1565 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1566 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1569 /// Create a register that is definitely an MSACtrl.
1570 /// This is typically only used for named registers such as $msaaccess.
1571 static std::unique_ptr<MipsOperand>
1572 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1573 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1574 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1577 static std::unique_ptr<MipsOperand>
1578 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1579 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1580 Op->Imm.Val = Val;
1581 Op->StartLoc = S;
1582 Op->EndLoc = E;
1583 return Op;
1586 static std::unique_ptr<MipsOperand>
1587 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1588 SMLoc E, MipsAsmParser &Parser) {
1589 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1590 Op->Mem.Base = Base.release();
1591 Op->Mem.Off = Off;
1592 Op->StartLoc = S;
1593 Op->EndLoc = E;
1594 return Op;
1597 static std::unique_ptr<MipsOperand>
1598 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1599 MipsAsmParser &Parser) {
1600 assert(Regs.size() > 0 && "Empty list not allowed");
1602 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1603 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1604 Op->StartLoc = StartLoc;
1605 Op->EndLoc = EndLoc;
1606 return Op;
1609 bool isGPRZeroAsmReg() const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1613 bool isGPRNonZeroAsmReg() const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1615 RegIdx.Index <= 31;
1618 bool isGPRAsmReg() const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1622 bool isMM16AsmReg() const {
1623 if (!(isRegIdx() && RegIdx.Kind))
1624 return false;
1625 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1626 || RegIdx.Index == 16 || RegIdx.Index == 17);
1629 bool isMM16AsmRegZero() const {
1630 if (!(isRegIdx() && RegIdx.Kind))
1631 return false;
1632 return (RegIdx.Index == 0 ||
1633 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1634 RegIdx.Index == 17);
1637 bool isMM16AsmRegMoveP() const {
1638 if (!(isRegIdx() && RegIdx.Kind))
1639 return false;
1640 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1641 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1644 bool isMM16AsmRegMovePPairFirst() const {
1645 if (!(isRegIdx() && RegIdx.Kind))
1646 return false;
1647 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1650 bool isMM16AsmRegMovePPairSecond() const {
1651 if (!(isRegIdx() && RegIdx.Kind))
1652 return false;
1653 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1654 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1657 bool isFGRAsmReg() const {
1658 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1659 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1662 bool isStrictlyFGRAsmReg() const {
1663 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1664 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1667 bool isHWRegsAsmReg() const {
1668 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1671 bool isCCRAsmReg() const {
1672 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1675 bool isFCCAsmReg() const {
1676 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1677 return false;
1678 return RegIdx.Index <= 7;
1681 bool isACCAsmReg() const {
1682 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1685 bool isCOP0AsmReg() const {
1686 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1689 bool isCOP2AsmReg() const {
1690 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1693 bool isCOP3AsmReg() const {
1694 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1697 bool isMSA128AsmReg() const {
1698 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1701 bool isMSACtrlAsmReg() const {
1702 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1705 /// getStartLoc - Get the location of the first token of this operand.
1706 SMLoc getStartLoc() const override { return StartLoc; }
1707 /// getEndLoc - Get the location of the last token of this operand.
1708 SMLoc getEndLoc() const override { return EndLoc; }
1710 void print(raw_ostream &OS) const override {
1711 switch (Kind) {
1712 case k_Immediate:
1713 OS << "Imm<";
1714 OS << *Imm.Val;
1715 OS << ">";
1716 break;
1717 case k_Memory:
1718 OS << "Mem<";
1719 Mem.Base->print(OS);
1720 OS << ", ";
1721 OS << *Mem.Off;
1722 OS << ">";
1723 break;
1724 case k_RegisterIndex:
1725 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1726 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1727 break;
1728 case k_Token:
1729 OS << getToken();
1730 break;
1731 case k_RegList:
1732 OS << "RegList< ";
1733 for (auto Reg : (*RegList.List))
1734 OS << Reg << " ";
1735 OS << ">";
1736 break;
1740 bool isValidForTie(const MipsOperand &Other) const {
1741 if (Kind != Other.Kind)
1742 return false;
1744 switch (Kind) {
1745 default:
1746 llvm_unreachable("Unexpected kind");
1747 return false;
1748 case k_RegisterIndex: {
1749 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1750 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1751 return Token == OtherToken;
1755 }; // class MipsOperand
1757 } // end anonymous namespace
1759 static bool hasShortDelaySlot(MCInst &Inst) {
1760 switch (Inst.getOpcode()) {
1761 case Mips::BEQ_MM:
1762 case Mips::BNE_MM:
1763 case Mips::BLTZ_MM:
1764 case Mips::BGEZ_MM:
1765 case Mips::BLEZ_MM:
1766 case Mips::BGTZ_MM:
1767 case Mips::JRC16_MM:
1768 case Mips::JALS_MM:
1769 case Mips::JALRS_MM:
1770 case Mips::JALRS16_MM:
1771 case Mips::BGEZALS_MM:
1772 case Mips::BLTZALS_MM:
1773 return true;
1774 case Mips::J_MM:
1775 return !Inst.getOperand(0).isReg();
1776 default:
1777 return false;
1781 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1782 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1783 return &SRExpr->getSymbol();
1786 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1787 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1788 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1790 if (LHSSym)
1791 return LHSSym;
1793 if (RHSSym)
1794 return RHSSym;
1796 return nullptr;
1799 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1800 return getSingleMCSymbol(UExpr->getSubExpr());
1802 return nullptr;
1805 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1806 if (isa<MCSymbolRefExpr>(Expr))
1807 return 1;
1809 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1810 return countMCSymbolRefExpr(BExpr->getLHS()) +
1811 countMCSymbolRefExpr(BExpr->getRHS());
1813 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1814 return countMCSymbolRefExpr(UExpr->getSubExpr());
1816 return 0;
1819 static bool isEvaluated(const MCExpr *Expr) {
1820 switch (Expr->getKind()) {
1821 case MCExpr::Constant:
1822 return true;
1823 case MCExpr::SymbolRef:
1824 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1825 case MCExpr::Binary: {
1826 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1827 if (!isEvaluated(BE->getLHS()))
1828 return false;
1829 return isEvaluated(BE->getRHS());
1831 case MCExpr::Unary:
1832 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1833 case MCExpr::Target:
1834 return true;
1836 return false;
1839 static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID) {
1840 unsigned NumOp = MCID.getNumOperands();
1841 if (NumOp != 3 && NumOp != 4)
1842 return false;
1844 const MCOperandInfo &OpInfo = MCID.operands()[NumOp - 1];
1845 if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
1846 OpInfo.OperandType != MCOI::OPERAND_UNKNOWN &&
1847 OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9)
1848 return false;
1850 MCOperand &Op = Inst.getOperand(NumOp - 1);
1851 if (Op.isImm()) {
1852 if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9)
1853 return !isInt<9>(Op.getImm());
1854 // Offset can't exceed 16bit value.
1855 return !isInt<16>(Op.getImm());
1858 if (Op.isExpr()) {
1859 const MCExpr *Expr = Op.getExpr();
1860 if (Expr->getKind() != MCExpr::SymbolRef)
1861 return !isEvaluated(Expr);
1863 // Expand symbol.
1864 const MCSymbolRefExpr *SR = static_cast<const MCSymbolRefExpr *>(Expr);
1865 return SR->getKind() == MCSymbolRefExpr::VK_None;
1868 return false;
1871 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1872 MCStreamer &Out,
1873 const MCSubtargetInfo *STI) {
1874 MipsTargetStreamer &TOut = getTargetStreamer();
1875 const unsigned Opcode = Inst.getOpcode();
1876 const MCInstrDesc &MCID = MII.get(Opcode);
1877 bool ExpandedJalSym = false;
1879 Inst.setLoc(IDLoc);
1881 if (MCID.isBranch() || MCID.isCall()) {
1882 MCOperand Offset;
1884 switch (Opcode) {
1885 default:
1886 break;
1887 case Mips::BBIT0:
1888 case Mips::BBIT032:
1889 case Mips::BBIT1:
1890 case Mips::BBIT132:
1891 assert(hasCnMips() && "instruction only valid for octeon cpus");
1892 [[fallthrough]];
1894 case Mips::BEQ:
1895 case Mips::BNE:
1896 case Mips::BEQ_MM:
1897 case Mips::BNE_MM:
1898 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1899 Offset = Inst.getOperand(2);
1900 if (!Offset.isImm())
1901 break; // We'll deal with this situation later on when applying fixups.
1902 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1903 return Error(IDLoc, "branch target out of range");
1904 if (offsetToAlignment(Offset.getImm(),
1905 (inMicroMipsMode() ? Align(2) : Align(4))))
1906 return Error(IDLoc, "branch to misaligned address");
1907 break;
1908 case Mips::BGEZ:
1909 case Mips::BGTZ:
1910 case Mips::BLEZ:
1911 case Mips::BLTZ:
1912 case Mips::BGEZAL:
1913 case Mips::BLTZAL:
1914 case Mips::BC1F:
1915 case Mips::BC1T:
1916 case Mips::BGEZ_MM:
1917 case Mips::BGTZ_MM:
1918 case Mips::BLEZ_MM:
1919 case Mips::BLTZ_MM:
1920 case Mips::BGEZAL_MM:
1921 case Mips::BLTZAL_MM:
1922 case Mips::BC1F_MM:
1923 case Mips::BC1T_MM:
1924 case Mips::BC1EQZC_MMR6:
1925 case Mips::BC1NEZC_MMR6:
1926 case Mips::BC2EQZC_MMR6:
1927 case Mips::BC2NEZC_MMR6:
1928 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1929 Offset = Inst.getOperand(1);
1930 if (!Offset.isImm())
1931 break; // We'll deal with this situation later on when applying fixups.
1932 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1933 return Error(IDLoc, "branch target out of range");
1934 if (offsetToAlignment(Offset.getImm(),
1935 (inMicroMipsMode() ? Align(2) : Align(4))))
1936 return Error(IDLoc, "branch to misaligned address");
1937 break;
1938 case Mips::BGEC: case Mips::BGEC_MMR6:
1939 case Mips::BLTC: case Mips::BLTC_MMR6:
1940 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1941 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1942 case Mips::BEQC: case Mips::BEQC_MMR6:
1943 case Mips::BNEC: case Mips::BNEC_MMR6:
1944 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1945 Offset = Inst.getOperand(2);
1946 if (!Offset.isImm())
1947 break; // We'll deal with this situation later on when applying fixups.
1948 if (!isIntN(18, Offset.getImm()))
1949 return Error(IDLoc, "branch target out of range");
1950 if (offsetToAlignment(Offset.getImm(), Align(4)))
1951 return Error(IDLoc, "branch to misaligned address");
1952 break;
1953 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1954 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1955 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1956 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1957 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1958 Offset = Inst.getOperand(1);
1959 if (!Offset.isImm())
1960 break; // We'll deal with this situation later on when applying fixups.
1961 if (!isIntN(18, Offset.getImm()))
1962 return Error(IDLoc, "branch target out of range");
1963 if (offsetToAlignment(Offset.getImm(), Align(4)))
1964 return Error(IDLoc, "branch to misaligned address");
1965 break;
1966 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1967 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1968 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1969 Offset = Inst.getOperand(1);
1970 if (!Offset.isImm())
1971 break; // We'll deal with this situation later on when applying fixups.
1972 if (!isIntN(23, Offset.getImm()))
1973 return Error(IDLoc, "branch target out of range");
1974 if (offsetToAlignment(Offset.getImm(), Align(4)))
1975 return Error(IDLoc, "branch to misaligned address");
1976 break;
1977 case Mips::BEQZ16_MM:
1978 case Mips::BEQZC16_MMR6:
1979 case Mips::BNEZ16_MM:
1980 case Mips::BNEZC16_MMR6:
1981 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1982 Offset = Inst.getOperand(1);
1983 if (!Offset.isImm())
1984 break; // We'll deal with this situation later on when applying fixups.
1985 if (!isInt<8>(Offset.getImm()))
1986 return Error(IDLoc, "branch target out of range");
1987 if (offsetToAlignment(Offset.getImm(), Align(2)))
1988 return Error(IDLoc, "branch to misaligned address");
1989 break;
1993 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1994 // We still accept it but it is a normal nop.
1995 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1996 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1997 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1998 "nop instruction");
2001 if (hasCnMips()) {
2002 MCOperand Opnd;
2003 int Imm;
2005 switch (Opcode) {
2006 default:
2007 break;
2009 case Mips::BBIT0:
2010 case Mips::BBIT032:
2011 case Mips::BBIT1:
2012 case Mips::BBIT132:
2013 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2014 // The offset is handled above
2015 Opnd = Inst.getOperand(1);
2016 if (!Opnd.isImm())
2017 return Error(IDLoc, "expected immediate operand kind");
2018 Imm = Opnd.getImm();
2019 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2020 Opcode == Mips::BBIT1 ? 63 : 31))
2021 return Error(IDLoc, "immediate operand value out of range");
2022 if (Imm > 31) {
2023 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2024 : Mips::BBIT132);
2025 Inst.getOperand(1).setImm(Imm - 32);
2027 break;
2029 case Mips::SEQi:
2030 case Mips::SNEi:
2031 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2032 Opnd = Inst.getOperand(2);
2033 if (!Opnd.isImm())
2034 return Error(IDLoc, "expected immediate operand kind");
2035 Imm = Opnd.getImm();
2036 if (!isInt<10>(Imm))
2037 return Error(IDLoc, "immediate operand value out of range");
2038 break;
2042 // Warn on division by zero. We're checking here as all instructions get
2043 // processed here, not just the macros that need expansion.
2045 // The MIPS backend models most of the divison instructions and macros as
2046 // three operand instructions. The pre-R6 divide instructions however have
2047 // two operands and explicitly define HI/LO as part of the instruction,
2048 // not in the operands.
2049 unsigned FirstOp = 1;
2050 unsigned SecondOp = 2;
2051 switch (Opcode) {
2052 default:
2053 break;
2054 case Mips::SDivIMacro:
2055 case Mips::UDivIMacro:
2056 case Mips::DSDivIMacro:
2057 case Mips::DUDivIMacro:
2058 if (Inst.getOperand(2).getImm() == 0) {
2059 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
2060 Inst.getOperand(1).getReg() == Mips::ZERO_64)
2061 Warning(IDLoc, "dividing zero by zero");
2062 else
2063 Warning(IDLoc, "division by zero");
2065 break;
2066 case Mips::DSDIV:
2067 case Mips::SDIV:
2068 case Mips::UDIV:
2069 case Mips::DUDIV:
2070 case Mips::UDIV_MM:
2071 case Mips::SDIV_MM:
2072 FirstOp = 0;
2073 SecondOp = 1;
2074 [[fallthrough]];
2075 case Mips::SDivMacro:
2076 case Mips::DSDivMacro:
2077 case Mips::UDivMacro:
2078 case Mips::DUDivMacro:
2079 case Mips::DIV:
2080 case Mips::DIVU:
2081 case Mips::DDIV:
2082 case Mips::DDIVU:
2083 case Mips::DIVU_MMR6:
2084 case Mips::DIV_MMR6:
2085 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2086 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2087 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2088 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2089 Warning(IDLoc, "dividing zero by zero");
2090 else
2091 Warning(IDLoc, "division by zero");
2093 break;
2096 // For PIC code convert unconditional jump to unconditional branch.
2097 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2098 MCInst BInst;
2099 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2100 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2101 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2102 BInst.addOperand(Inst.getOperand(0));
2103 Inst = BInst;
2106 // This expansion is not in a function called by tryExpandInstruction()
2107 // because the pseudo-instruction doesn't have a distinct opcode.
2108 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2109 warnIfNoMacro(IDLoc);
2111 if (!Inst.getOperand(0).isExpr()) {
2112 return Error(IDLoc, "unsupported constant in relocation");
2115 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2117 // We can do this expansion if there's only 1 symbol in the argument
2118 // expression.
2119 if (countMCSymbolRefExpr(JalExpr) > 1)
2120 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2122 // FIXME: This is checking the expression can be handled by the later stages
2123 // of the assembler. We ought to leave it to those later stages.
2124 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2126 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.getOperand(0),
2127 !isGP64bit(), IDLoc, Out, STI))
2128 return true;
2130 MCInst JalrInst;
2131 if (inMicroMipsMode())
2132 JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2133 else
2134 JalrInst.setOpcode(Mips::JALR);
2135 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2136 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2138 if (isJalrRelocAvailable(JalExpr)) {
2139 // As an optimization hint for the linker, before the JALR we add:
2140 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2141 // tmplabel:
2142 MCSymbol *TmpLabel = getContext().createTempSymbol();
2143 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2144 const MCExpr *RelocJalrExpr =
2145 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2146 getContext(), IDLoc);
2148 TOut.getStreamer().emitRelocDirective(
2149 *TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2150 RelocJalrExpr, IDLoc, *STI);
2151 TOut.getStreamer().emitLabel(TmpLabel);
2154 Inst = JalrInst;
2155 ExpandedJalSym = true;
2158 if (MCID.mayLoad() || MCID.mayStore()) {
2159 // Check the offset of memory operand, if it is a symbol
2160 // reference or immediate we may have to expand instructions.
2161 if (needsExpandMemInst(Inst, MCID)) {
2162 switch (MCID.operands()[MCID.getNumOperands() - 1].OperandType) {
2163 case MipsII::OPERAND_MEM_SIMM9:
2164 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2165 break;
2166 default:
2167 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2168 break;
2170 return getParser().hasPendingError();
2174 if (inMicroMipsMode()) {
2175 if (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
2176 // Try to create 16-bit GP relative load instruction.
2177 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2178 const MCOperandInfo &OpInfo = MCID.operands()[i];
2179 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2180 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2181 MCOperand &Op = Inst.getOperand(i);
2182 if (Op.isImm()) {
2183 int MemOffset = Op.getImm();
2184 MCOperand &DstReg = Inst.getOperand(0);
2185 MCOperand &BaseReg = Inst.getOperand(1);
2186 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2187 getContext().getRegisterInfo()->getRegClass(
2188 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2189 (BaseReg.getReg() == Mips::GP ||
2190 BaseReg.getReg() == Mips::GP_64)) {
2192 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2193 IDLoc, STI);
2194 return false;
2198 } // for
2199 } // if load
2201 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2203 MCOperand Opnd;
2204 int Imm;
2206 switch (Opcode) {
2207 default:
2208 break;
2209 case Mips::ADDIUSP_MM:
2210 Opnd = Inst.getOperand(0);
2211 if (!Opnd.isImm())
2212 return Error(IDLoc, "expected immediate operand kind");
2213 Imm = Opnd.getImm();
2214 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2215 Imm % 4 != 0)
2216 return Error(IDLoc, "immediate operand value out of range");
2217 break;
2218 case Mips::SLL16_MM:
2219 case Mips::SRL16_MM:
2220 Opnd = Inst.getOperand(2);
2221 if (!Opnd.isImm())
2222 return Error(IDLoc, "expected immediate operand kind");
2223 Imm = Opnd.getImm();
2224 if (Imm < 1 || Imm > 8)
2225 return Error(IDLoc, "immediate operand value out of range");
2226 break;
2227 case Mips::LI16_MM:
2228 Opnd = Inst.getOperand(1);
2229 if (!Opnd.isImm())
2230 return Error(IDLoc, "expected immediate operand kind");
2231 Imm = Opnd.getImm();
2232 if (Imm < -1 || Imm > 126)
2233 return Error(IDLoc, "immediate operand value out of range");
2234 break;
2235 case Mips::ADDIUR2_MM:
2236 Opnd = Inst.getOperand(2);
2237 if (!Opnd.isImm())
2238 return Error(IDLoc, "expected immediate operand kind");
2239 Imm = Opnd.getImm();
2240 if (!(Imm == 1 || Imm == -1 ||
2241 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2242 return Error(IDLoc, "immediate operand value out of range");
2243 break;
2244 case Mips::ANDI16_MM:
2245 Opnd = Inst.getOperand(2);
2246 if (!Opnd.isImm())
2247 return Error(IDLoc, "expected immediate operand kind");
2248 Imm = Opnd.getImm();
2249 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2250 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2251 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2252 return Error(IDLoc, "immediate operand value out of range");
2253 break;
2254 case Mips::LBU16_MM:
2255 Opnd = Inst.getOperand(2);
2256 if (!Opnd.isImm())
2257 return Error(IDLoc, "expected immediate operand kind");
2258 Imm = Opnd.getImm();
2259 if (Imm < -1 || Imm > 14)
2260 return Error(IDLoc, "immediate operand value out of range");
2261 break;
2262 case Mips::SB16_MM:
2263 case Mips::SB16_MMR6:
2264 Opnd = Inst.getOperand(2);
2265 if (!Opnd.isImm())
2266 return Error(IDLoc, "expected immediate operand kind");
2267 Imm = Opnd.getImm();
2268 if (Imm < 0 || Imm > 15)
2269 return Error(IDLoc, "immediate operand value out of range");
2270 break;
2271 case Mips::LHU16_MM:
2272 case Mips::SH16_MM:
2273 case Mips::SH16_MMR6:
2274 Opnd = Inst.getOperand(2);
2275 if (!Opnd.isImm())
2276 return Error(IDLoc, "expected immediate operand kind");
2277 Imm = Opnd.getImm();
2278 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2279 return Error(IDLoc, "immediate operand value out of range");
2280 break;
2281 case Mips::LW16_MM:
2282 case Mips::SW16_MM:
2283 case Mips::SW16_MMR6:
2284 Opnd = Inst.getOperand(2);
2285 if (!Opnd.isImm())
2286 return Error(IDLoc, "expected immediate operand kind");
2287 Imm = Opnd.getImm();
2288 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2289 return Error(IDLoc, "immediate operand value out of range");
2290 break;
2291 case Mips::ADDIUPC_MM:
2292 Opnd = Inst.getOperand(1);
2293 if (!Opnd.isImm())
2294 return Error(IDLoc, "expected immediate operand kind");
2295 Imm = Opnd.getImm();
2296 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2297 return Error(IDLoc, "immediate operand value out of range");
2298 break;
2299 case Mips::LWP_MM:
2300 case Mips::SWP_MM:
2301 if (Inst.getOperand(0).getReg() == Mips::RA)
2302 return Error(IDLoc, "invalid operand for instruction");
2303 break;
2304 case Mips::MOVEP_MM:
2305 case Mips::MOVEP_MMR6: {
2306 unsigned R0 = Inst.getOperand(0).getReg();
2307 unsigned R1 = Inst.getOperand(1).getReg();
2308 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2309 (R0 == Mips::A1 && R1 == Mips::A3) ||
2310 (R0 == Mips::A2 && R1 == Mips::A3) ||
2311 (R0 == Mips::A0 && R1 == Mips::S5) ||
2312 (R0 == Mips::A0 && R1 == Mips::S6) ||
2313 (R0 == Mips::A0 && R1 == Mips::A1) ||
2314 (R0 == Mips::A0 && R1 == Mips::A2) ||
2315 (R0 == Mips::A0 && R1 == Mips::A3));
2316 if (!RegPair)
2317 return Error(IDLoc, "invalid operand for instruction");
2318 break;
2323 bool FillDelaySlot =
2324 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2326 // Get previous instruction`s forbidden slot attribute and
2327 // whether set reorder.
2328 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2330 // Flag represents we set reorder after nop.
2331 bool SetReorderAfterNop = false;
2333 // If previous instruction has forbidden slot and .set reorder
2334 // is active and current instruction is CTI.
2335 // Then emit a NOP after it.
2336 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2337 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2338 // When 'FillDelaySlot' is true, the existing logic will add
2339 // noreorder before instruction and reorder after it. So there
2340 // need exclude this case avoiding two '.set reorder'.
2341 // The format of the first case is:
2342 // .set noreorder
2343 // bnezc
2344 // nop
2345 // .set reorder
2346 if (AssemblerOptions.back()->isReorder() && !FillDelaySlot) {
2347 SetReorderAfterNop = true;
2348 TOut.emitDirectiveSetReorder();
2352 // Save current instruction`s forbidden slot and whether set reorder.
2353 // This is the judgment condition for whether to add nop.
2354 // We would add a couple of '.set noreorder' and '.set reorder' to
2355 // wrap the current instruction and the next instruction.
2356 CurForbiddenSlotAttr =
2357 hasForbiddenSlot(MCID) && AssemblerOptions.back()->isReorder();
2359 if (FillDelaySlot || CurForbiddenSlotAttr)
2360 TOut.emitDirectiveSetNoReorder();
2362 MacroExpanderResultTy ExpandResult =
2363 tryExpandInstruction(Inst, IDLoc, Out, STI);
2364 switch (ExpandResult) {
2365 case MER_NotAMacro:
2366 Out.emitInstruction(Inst, *STI);
2367 break;
2368 case MER_Success:
2369 break;
2370 case MER_Fail:
2371 return true;
2374 // When current instruction was not CTI, recover reorder state.
2375 // The format of the second case is:
2376 // .set noreoder
2377 // bnezc
2378 // add
2379 // .set reorder
2380 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2381 AssemblerOptions.back()->isReorder()) {
2382 TOut.emitDirectiveSetReorder();
2385 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2386 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2387 if (inMicroMipsMode()) {
2388 TOut.setUsesMicroMips();
2389 TOut.updateABIInfo(*this);
2392 // If this instruction has a delay slot and .set reorder is active,
2393 // emit a NOP after it.
2394 // The format of the third case is:
2395 // .set noreorder
2396 // bnezc
2397 // nop
2398 // .set noreorder
2399 // j
2400 // nop
2401 // .set reorder
2402 if (FillDelaySlot) {
2403 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2404 TOut.emitDirectiveSetReorder();
2407 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2408 ExpandedJalSym) &&
2409 isPicAndNotNxxAbi()) {
2410 if (IsCpRestoreSet) {
2411 // We need a NOP between the JALR and the LW:
2412 // If .set reorder has been used, we've already emitted a NOP.
2413 // If .set noreorder has been used, we need to emit a NOP at this point.
2414 if (!AssemblerOptions.back()->isReorder())
2415 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2416 STI);
2418 // Load the $gp from the stack.
2419 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2420 } else
2421 Warning(IDLoc, "no .cprestore used in PIC mode");
2424 return false;
2427 void MipsAsmParser::onEndOfFile() {
2428 MipsTargetStreamer &TOut = getTargetStreamer();
2429 SMLoc IDLoc = SMLoc();
2430 // If has pending forbidden slot, fill nop and recover reorder.
2431 if (CurForbiddenSlotAttr) {
2432 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2433 if (AssemblerOptions.back()->isReorder())
2434 TOut.emitDirectiveSetReorder();
2438 MipsAsmParser::MacroExpanderResultTy
2439 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2440 const MCSubtargetInfo *STI) {
2441 switch (Inst.getOpcode()) {
2442 default:
2443 return MER_NotAMacro;
2444 case Mips::LoadImm32:
2445 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2446 case Mips::LoadImm64:
2447 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::LoadAddrImm32:
2449 case Mips::LoadAddrImm64:
2450 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2451 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2452 "expected immediate operand kind");
2454 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2455 Inst.getOperand(1),
2456 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2457 Out, STI)
2458 ? MER_Fail
2459 : MER_Success;
2460 case Mips::LoadAddrReg32:
2461 case Mips::LoadAddrReg64:
2462 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2463 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2464 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2465 "expected immediate operand kind");
2467 return expandLoadAddress(Inst.getOperand(0).getReg(),
2468 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2469 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2470 Out, STI)
2471 ? MER_Fail
2472 : MER_Success;
2473 case Mips::B_MM_Pseudo:
2474 case Mips::B_MMR6_Pseudo:
2475 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2476 : MER_Success;
2477 case Mips::SWM_MM:
2478 case Mips::LWM_MM:
2479 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2480 : MER_Success;
2481 case Mips::JalOneReg:
2482 case Mips::JalTwoReg:
2483 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 case Mips::BneImm:
2485 case Mips::BeqImm:
2486 case Mips::BEQLImmMacro:
2487 case Mips::BNELImmMacro:
2488 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2489 case Mips::BLT:
2490 case Mips::BLE:
2491 case Mips::BGE:
2492 case Mips::BGT:
2493 case Mips::BLTU:
2494 case Mips::BLEU:
2495 case Mips::BGEU:
2496 case Mips::BGTU:
2497 case Mips::BLTL:
2498 case Mips::BLEL:
2499 case Mips::BGEL:
2500 case Mips::BGTL:
2501 case Mips::BLTUL:
2502 case Mips::BLEUL:
2503 case Mips::BGEUL:
2504 case Mips::BGTUL:
2505 case Mips::BLTImmMacro:
2506 case Mips::BLEImmMacro:
2507 case Mips::BGEImmMacro:
2508 case Mips::BGTImmMacro:
2509 case Mips::BLTUImmMacro:
2510 case Mips::BLEUImmMacro:
2511 case Mips::BGEUImmMacro:
2512 case Mips::BGTUImmMacro:
2513 case Mips::BLTLImmMacro:
2514 case Mips::BLELImmMacro:
2515 case Mips::BGELImmMacro:
2516 case Mips::BGTLImmMacro:
2517 case Mips::BLTULImmMacro:
2518 case Mips::BLEULImmMacro:
2519 case Mips::BGEULImmMacro:
2520 case Mips::BGTULImmMacro:
2521 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2522 case Mips::SDivMacro:
2523 case Mips::SDivIMacro:
2524 case Mips::SRemMacro:
2525 case Mips::SRemIMacro:
2526 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2527 : MER_Success;
2528 case Mips::DSDivMacro:
2529 case Mips::DSDivIMacro:
2530 case Mips::DSRemMacro:
2531 case Mips::DSRemIMacro:
2532 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2533 : MER_Success;
2534 case Mips::UDivMacro:
2535 case Mips::UDivIMacro:
2536 case Mips::URemMacro:
2537 case Mips::URemIMacro:
2538 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2539 : MER_Success;
2540 case Mips::DUDivMacro:
2541 case Mips::DUDivIMacro:
2542 case Mips::DURemMacro:
2543 case Mips::DURemIMacro:
2544 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2545 : MER_Success;
2546 case Mips::PseudoTRUNC_W_S:
2547 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2548 : MER_Success;
2549 case Mips::PseudoTRUNC_W_D32:
2550 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2551 : MER_Success;
2552 case Mips::PseudoTRUNC_W_D:
2553 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2554 : MER_Success;
2556 case Mips::LoadImmSingleGPR:
2557 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2558 : MER_Success;
2559 case Mips::LoadImmSingleFGR:
2560 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2561 : MER_Success;
2562 case Mips::LoadImmDoubleGPR:
2563 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2564 : MER_Success;
2565 case Mips::LoadImmDoubleFGR:
2566 return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2567 : MER_Success;
2568 case Mips::LoadImmDoubleFGR_32:
2569 return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2570 : MER_Success;
2572 case Mips::Ulh:
2573 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 case Mips::Ulhu:
2575 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2576 case Mips::Ush:
2577 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2578 case Mips::Ulw:
2579 case Mips::Usw:
2580 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2581 case Mips::NORImm:
2582 case Mips::NORImm64:
2583 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2584 case Mips::SGE:
2585 case Mips::SGEU:
2586 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2587 case Mips::SGEImm:
2588 case Mips::SGEUImm:
2589 case Mips::SGEImm64:
2590 case Mips::SGEUImm64:
2591 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2592 case Mips::SGTImm:
2593 case Mips::SGTUImm:
2594 case Mips::SGTImm64:
2595 case Mips::SGTUImm64:
2596 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2597 case Mips::SLE:
2598 case Mips::SLEU:
2599 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2600 case Mips::SLEImm:
2601 case Mips::SLEUImm:
2602 case Mips::SLEImm64:
2603 case Mips::SLEUImm64:
2604 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2605 case Mips::SLTImm64:
2606 if (isInt<16>(Inst.getOperand(2).getImm())) {
2607 Inst.setOpcode(Mips::SLTi64);
2608 return MER_NotAMacro;
2610 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 case Mips::SLTUImm64:
2612 if (isInt<16>(Inst.getOperand(2).getImm())) {
2613 Inst.setOpcode(Mips::SLTiu64);
2614 return MER_NotAMacro;
2616 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::ADDi: case Mips::ADDi_MM:
2618 case Mips::ADDiu: case Mips::ADDiu_MM:
2619 case Mips::SLTi: case Mips::SLTi_MM:
2620 case Mips::SLTiu: case Mips::SLTiu_MM:
2621 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2622 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2623 int64_t ImmValue = Inst.getOperand(2).getImm();
2624 if (isInt<16>(ImmValue))
2625 return MER_NotAMacro;
2626 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2627 : MER_Success;
2629 return MER_NotAMacro;
2630 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2631 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2632 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2633 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2634 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2635 int64_t ImmValue = Inst.getOperand(2).getImm();
2636 if (isUInt<16>(ImmValue))
2637 return MER_NotAMacro;
2638 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2639 : MER_Success;
2641 return MER_NotAMacro;
2642 case Mips::ROL:
2643 case Mips::ROR:
2644 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2645 case Mips::ROLImm:
2646 case Mips::RORImm:
2647 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2648 case Mips::DROL:
2649 case Mips::DROR:
2650 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651 case Mips::DROLImm:
2652 case Mips::DRORImm:
2653 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2654 case Mips::ABSMacro:
2655 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656 case Mips::MULImmMacro:
2657 case Mips::DMULImmMacro:
2658 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659 case Mips::MULOMacro:
2660 case Mips::DMULOMacro:
2661 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662 case Mips::MULOUMacro:
2663 case Mips::DMULOUMacro:
2664 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2665 case Mips::DMULMacro:
2666 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2667 case Mips::LDMacro:
2668 case Mips::SDMacro:
2669 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2670 Inst.getOpcode() == Mips::LDMacro)
2671 ? MER_Fail
2672 : MER_Success;
2673 case Mips::SDC1_M1:
2674 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2675 ? MER_Fail
2676 : MER_Success;
2677 case Mips::SEQMacro:
2678 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2679 case Mips::SEQIMacro:
2680 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2681 case Mips::SNEMacro:
2682 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2683 case Mips::SNEIMacro:
2684 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2685 case Mips::MFTC0: case Mips::MTTC0:
2686 case Mips::MFTGPR: case Mips::MTTGPR:
2687 case Mips::MFTLO: case Mips::MTTLO:
2688 case Mips::MFTHI: case Mips::MTTHI:
2689 case Mips::MFTACX: case Mips::MTTACX:
2690 case Mips::MFTDSP: case Mips::MTTDSP:
2691 case Mips::MFTC1: case Mips::MTTC1:
2692 case Mips::MFTHC1: case Mips::MTTHC1:
2693 case Mips::CFTC1: case Mips::CTTC1:
2694 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2695 case Mips::SaaAddr:
2696 case Mips::SaadAddr:
2697 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2701 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2702 MCStreamer &Out,
2703 const MCSubtargetInfo *STI) {
2704 MipsTargetStreamer &TOut = getTargetStreamer();
2706 // Create a JALR instruction which is going to replace the pseudo-JAL.
2707 MCInst JalrInst;
2708 JalrInst.setLoc(IDLoc);
2709 const MCOperand FirstRegOp = Inst.getOperand(0);
2710 const unsigned Opcode = Inst.getOpcode();
2712 if (Opcode == Mips::JalOneReg) {
2713 // jal $rs => jalr $rs
2714 if (IsCpRestoreSet && inMicroMipsMode()) {
2715 JalrInst.setOpcode(Mips::JALRS16_MM);
2716 JalrInst.addOperand(FirstRegOp);
2717 } else if (inMicroMipsMode()) {
2718 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2719 JalrInst.addOperand(FirstRegOp);
2720 } else {
2721 JalrInst.setOpcode(Mips::JALR);
2722 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2723 JalrInst.addOperand(FirstRegOp);
2725 } else if (Opcode == Mips::JalTwoReg) {
2726 // jal $rd, $rs => jalr $rd, $rs
2727 if (IsCpRestoreSet && inMicroMipsMode())
2728 JalrInst.setOpcode(Mips::JALRS_MM);
2729 else
2730 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2731 JalrInst.addOperand(FirstRegOp);
2732 const MCOperand SecondRegOp = Inst.getOperand(1);
2733 JalrInst.addOperand(SecondRegOp);
2735 Out.emitInstruction(JalrInst, *STI);
2737 // If .set reorder is active and branch instruction has a delay slot,
2738 // emit a NOP after it.
2739 const MCInstrDesc &MCID = MII.get(JalrInst.getOpcode());
2740 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2741 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2742 STI);
2744 return false;
2747 /// Can the value be represented by a unsigned N-bit value and a shift left?
2748 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2749 return x && isUInt<N>(x >> llvm::countr_zero(x));
2752 /// Load (or add) an immediate into a register.
2754 /// @param ImmValue The immediate to load.
2755 /// @param DstReg The register that will hold the immediate.
2756 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2757 /// for a simple initialization.
2758 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2759 /// @param IsAddress True if the immediate represents an address. False if it
2760 /// is an integer.
2761 /// @param IDLoc Location of the immediate in the source file.
2762 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2763 unsigned SrcReg, bool Is32BitImm,
2764 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2765 const MCSubtargetInfo *STI) {
2766 MipsTargetStreamer &TOut = getTargetStreamer();
2768 if (!Is32BitImm && !isGP64bit()) {
2769 Error(IDLoc, "instruction requires a 64-bit architecture");
2770 return true;
2773 if (Is32BitImm) {
2774 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2775 // Sign extend up to 64-bit so that the predicates match the hardware
2776 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2777 // true.
2778 ImmValue = SignExtend64<32>(ImmValue);
2779 } else {
2780 Error(IDLoc, "instruction requires a 32-bit immediate");
2781 return true;
2785 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2786 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2788 bool UseSrcReg = false;
2789 if (SrcReg != Mips::NoRegister)
2790 UseSrcReg = true;
2792 unsigned TmpReg = DstReg;
2793 if (UseSrcReg &&
2794 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2795 // At this point we need AT to perform the expansions and we exit if it is
2796 // not available.
2797 unsigned ATReg = getATReg(IDLoc);
2798 if (!ATReg)
2799 return true;
2800 TmpReg = ATReg;
2803 if (isInt<16>(ImmValue)) {
2804 if (!UseSrcReg)
2805 SrcReg = ZeroReg;
2807 // This doesn't quite follow the usual ABI expectations for N32 but matches
2808 // traditional assembler behaviour. N32 would normally use addiu for both
2809 // integers and addresses.
2810 if (IsAddress && !Is32BitImm) {
2811 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2812 return false;
2815 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2816 return false;
2819 if (isUInt<16>(ImmValue)) {
2820 unsigned TmpReg = DstReg;
2821 if (SrcReg == DstReg) {
2822 TmpReg = getATReg(IDLoc);
2823 if (!TmpReg)
2824 return true;
2827 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2828 if (UseSrcReg)
2829 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2830 return false;
2833 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2834 warnIfNoMacro(IDLoc);
2836 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2837 uint16_t Bits15To0 = ImmValue & 0xffff;
2838 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2839 // Traditional behaviour seems to special case this particular value. It's
2840 // not clear why other masks are handled differently.
2841 if (ImmValue == 0xffffffff) {
2842 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2843 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2844 if (UseSrcReg)
2845 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2846 return false;
2849 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2850 // upper 32 bits.
2851 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2852 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2853 if (Bits15To0)
2854 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2855 if (UseSrcReg)
2856 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2857 return false;
2860 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2861 if (Bits15To0)
2862 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2863 if (UseSrcReg)
2864 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2865 return false;
2868 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2869 if (Is32BitImm) {
2870 Error(IDLoc, "instruction requires a 32-bit immediate");
2871 return true;
2874 // We've processed ImmValue satisfying isUInt<16> above, so ImmValue must be
2875 // at least 17-bit wide here.
2876 unsigned BitWidth = llvm::bit_width((uint64_t)ImmValue);
2877 assert(BitWidth >= 17 && "ImmValue must be at least 17-bit wide");
2879 // Traditionally, these immediates are shifted as little as possible and as
2880 // such we align the most significant bit to bit 15 of our temporary.
2881 unsigned ShiftAmount = BitWidth - 16;
2882 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2883 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2884 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2886 if (UseSrcReg)
2887 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2889 return false;
2892 warnIfNoMacro(IDLoc);
2894 // The remaining case is packed with a sequence of dsll and ori with zeros
2895 // being omitted and any neighbouring dsll's being coalesced.
2896 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2898 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2899 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2900 IDLoc, Out, STI))
2901 return false;
2903 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2904 // skip it and defer the shift to the next chunk.
2905 unsigned ShiftCarriedForwards = 16;
2906 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2907 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2909 if (ImmChunk != 0) {
2910 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2911 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2912 ShiftCarriedForwards = 0;
2915 ShiftCarriedForwards += 16;
2917 ShiftCarriedForwards -= 16;
2919 // Finish any remaining shifts left by trailing zeros.
2920 if (ShiftCarriedForwards)
2921 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2923 if (UseSrcReg)
2924 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2926 return false;
2929 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2930 MCStreamer &Out, const MCSubtargetInfo *STI) {
2931 const MCOperand &ImmOp = Inst.getOperand(1);
2932 assert(ImmOp.isImm() && "expected immediate operand kind");
2933 const MCOperand &DstRegOp = Inst.getOperand(0);
2934 assert(DstRegOp.isReg() && "expected register operand kind");
2936 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2937 Is32BitImm, false, IDLoc, Out, STI))
2938 return true;
2940 return false;
2943 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2944 const MCOperand &Offset,
2945 bool Is32BitAddress, SMLoc IDLoc,
2946 MCStreamer &Out,
2947 const MCSubtargetInfo *STI) {
2948 // la can't produce a usable address when addresses are 64-bit.
2949 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2950 Warning(IDLoc, "la used to load 64-bit address");
2951 // Continue as if we had 'dla' instead.
2952 Is32BitAddress = false;
2955 // dla requires 64-bit addresses.
2956 if (!Is32BitAddress && !hasMips3()) {
2957 Error(IDLoc, "instruction requires a 64-bit architecture");
2958 return true;
2961 if (!Offset.isImm())
2962 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2963 Is32BitAddress, IDLoc, Out, STI);
2965 if (!ABI.ArePtrs64bit()) {
2966 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2967 Is32BitAddress = true;
2970 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2971 IDLoc, Out, STI);
2974 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2975 unsigned DstReg, unsigned SrcReg,
2976 bool Is32BitSym, SMLoc IDLoc,
2977 MCStreamer &Out,
2978 const MCSubtargetInfo *STI) {
2979 MipsTargetStreamer &TOut = getTargetStreamer();
2980 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2981 SrcReg != Mips::ZERO_64;
2982 warnIfNoMacro(IDLoc);
2984 if (inPicMode()) {
2985 MCValue Res;
2986 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2987 Error(IDLoc, "expected relocatable expression");
2988 return true;
2990 if (Res.getSymB() != nullptr) {
2991 Error(IDLoc, "expected relocatable expression with only one symbol");
2992 return true;
2995 bool IsPtr64 = ABI.ArePtrs64bit();
2996 bool IsLocalSym =
2997 Res.getSymA()->getSymbol().isInSection() ||
2998 Res.getSymA()->getSymbol().isTemporary() ||
2999 (Res.getSymA()->getSymbol().isELF() &&
3000 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
3001 ELF::STB_LOCAL);
3002 // For O32, "$"-prefixed symbols are recognized as temporary while
3003 // .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
3004 // manually.
3005 if (ABI.IsO32() && Res.getSymA()->getSymbol().getName().starts_with(".L"))
3006 IsLocalSym = true;
3007 bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3009 // The case where the result register is $25 is somewhat special. If the
3010 // symbol in the final relocation is external and not modified with a
3011 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
3012 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
3013 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3014 Res.getConstant() == 0 && !IsLocalSym) {
3015 if (UseXGOT) {
3016 const MCExpr *CallHiExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16,
3017 SymExpr, getContext());
3018 const MCExpr *CallLoExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16,
3019 SymExpr, getContext());
3020 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3021 STI);
3022 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3023 IDLoc, STI);
3024 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3025 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3026 } else {
3027 const MCExpr *CallExpr =
3028 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
3029 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3030 MCOperand::createExpr(CallExpr), IDLoc, STI);
3032 return false;
3035 unsigned TmpReg = DstReg;
3036 if (UseSrcReg &&
3037 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3038 SrcReg)) {
3039 // If $rs is the same as $rd, we need to use AT.
3040 // If it is not available we exit.
3041 unsigned ATReg = getATReg(IDLoc);
3042 if (!ATReg)
3043 return true;
3044 TmpReg = ATReg;
3047 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
3048 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
3049 // FIXME: Implement XGOT for microMIPS.
3050 if (UseXGOT) {
3051 // Loading address from XGOT
3052 // External GOT: lui $tmp, %got_hi(symbol)($gp)
3053 // addu $tmp, $tmp, $gp
3054 // lw $tmp, %got_lo(symbol)($tmp)
3055 // >addiu $tmp, $tmp, offset
3056 // >addiu $rd, $tmp, $rs
3057 // The addiu's marked with a '>' may be omitted if they are redundant. If
3058 // this happens then the last instruction must use $rd as the result
3059 // register.
3060 const MCExpr *CallHiExpr =
3061 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
3062 const MCExpr *CallLoExpr = MipsMCExpr::create(
3063 MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
3065 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3066 STI);
3067 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3068 IDLoc, STI);
3069 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3070 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3072 if (Res.getConstant() != 0)
3073 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3074 MCOperand::createExpr(MCConstantExpr::create(
3075 Res.getConstant(), getContext())),
3076 IDLoc, STI);
3078 if (UseSrcReg)
3079 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3080 IDLoc, STI);
3081 return false;
3084 const MipsMCExpr *GotExpr = nullptr;
3085 const MCExpr *LoExpr = nullptr;
3086 if (ABI.IsN32() || ABI.IsN64()) {
3087 // The remaining cases are:
3088 // Small offset: ld $tmp, %got_disp(symbol)($gp)
3089 // >daddiu $tmp, $tmp, offset
3090 // >daddu $rd, $tmp, $rs
3091 // The daddiu's marked with a '>' may be omitted if they are redundant. If
3092 // this happens then the last instruction must use $rd as the result
3093 // register.
3094 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, Res.getSymA(),
3095 getContext());
3096 if (Res.getConstant() != 0) {
3097 // Symbols fully resolve with just the %got_disp(symbol) but we
3098 // must still account for any offset to the symbol for
3099 // expressions like symbol+8.
3100 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3102 // FIXME: Offsets greater than 16 bits are not yet implemented.
3103 // FIXME: The correct range is a 32-bit sign-extended number.
3104 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3105 Error(IDLoc, "macro instruction uses large offset, which is not "
3106 "currently supported");
3107 return true;
3110 } else {
3111 // The remaining cases are:
3112 // External GOT: lw $tmp, %got(symbol)($gp)
3113 // >addiu $tmp, $tmp, offset
3114 // >addiu $rd, $tmp, $rs
3115 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3116 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3117 // >addiu $rd, $tmp, $rs
3118 // The addiu's marked with a '>' may be omitted if they are redundant. If
3119 // this happens then the last instruction must use $rd as the result
3120 // register.
3121 if (IsLocalSym) {
3122 GotExpr =
3123 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3124 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3125 } else {
3126 // External symbols fully resolve the symbol with just the %got(symbol)
3127 // but we must still account for any offset to the symbol for
3128 // expressions like symbol+8.
3129 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, Res.getSymA(),
3130 getContext());
3131 if (Res.getConstant() != 0)
3132 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3136 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3137 MCOperand::createExpr(GotExpr), IDLoc, STI);
3139 if (LoExpr)
3140 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3141 MCOperand::createExpr(LoExpr), IDLoc, STI);
3143 if (UseSrcReg)
3144 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3145 IDLoc, STI);
3147 return false;
3150 const MipsMCExpr *HiExpr =
3151 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3152 const MipsMCExpr *LoExpr =
3153 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3155 // This is the 64-bit symbol address expansion.
3156 if (ABI.ArePtrs64bit() && isGP64bit()) {
3157 // We need AT for the 64-bit expansion in the cases where the optional
3158 // source register is the destination register and for the superscalar
3159 // scheduled form.
3161 // If it is not available we exit if the destination is the same as the
3162 // source register.
3164 const MipsMCExpr *HighestExpr =
3165 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3166 const MipsMCExpr *HigherExpr =
3167 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3169 bool RdRegIsRsReg =
3170 UseSrcReg &&
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3173 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3174 unsigned ATReg = getATReg(IDLoc);
3176 // If $rs is the same as $rd:
3177 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3178 // daddiu $at, $at, %higher(sym)
3179 // dsll $at, $at, 16
3180 // daddiu $at, $at, %hi(sym)
3181 // dsll $at, $at, 16
3182 // daddiu $at, $at, %lo(sym)
3183 // daddu $rd, $at, $rd
3184 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3185 STI);
3186 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3187 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3188 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3189 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3190 IDLoc, STI);
3191 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3192 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3193 IDLoc, STI);
3194 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3196 return false;
3197 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3198 unsigned ATReg = getATReg(IDLoc);
3200 // If the $rs is different from $rd or if $rs isn't specified and we
3201 // have $at available:
3202 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3203 // lui $at, %hi(sym)
3204 // daddiu $rd, $rd, %higher(sym)
3205 // daddiu $at, $at, %lo(sym)
3206 // dsll32 $rd, $rd, 0
3207 // daddu $rd, $rd, $at
3208 // (daddu $rd, $rd, $rs)
3210 // Which is preferred for superscalar issue.
3211 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3212 STI);
3213 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3214 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3215 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3216 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3217 IDLoc, STI);
3218 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3219 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3220 if (UseSrcReg)
3221 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3223 return false;
3224 } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3225 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3226 // Otherwise, synthesize the address in the destination register
3227 // serially:
3228 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3229 // daddiu $rd, $rd, %higher(sym)
3230 // dsll $rd, $rd, 16
3231 // daddiu $rd, $rd, %hi(sym)
3232 // dsll $rd, $rd, 16
3233 // daddiu $rd, $rd, %lo(sym)
3234 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3235 STI);
3236 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3237 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3238 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3239 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3240 MCOperand::createExpr(HiExpr), IDLoc, STI);
3241 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3242 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3243 MCOperand::createExpr(LoExpr), IDLoc, STI);
3244 if (UseSrcReg)
3245 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3247 return false;
3248 } else {
3249 // We have a case where SrcReg == DstReg and we don't have $at
3250 // available. We can't expand this case, so error out appropriately.
3251 assert(SrcReg == DstReg && !canUseATReg() &&
3252 "Could have expanded dla but didn't?");
3253 reportParseError(IDLoc,
3254 "pseudo-instruction requires $at, which is not available");
3255 return true;
3259 // And now, the 32-bit symbol address expansion:
3260 // If $rs is the same as $rd:
3261 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3262 // ori $at, $at, %lo(sym)
3263 // addu $rd, $at, $rd
3264 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3265 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3266 // ori $rd, $rd, %lo(sym)
3267 // (addu $rd, $rd, $rs)
3268 unsigned TmpReg = DstReg;
3269 if (UseSrcReg &&
3270 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3271 // If $rs is the same as $rd, we need to use AT.
3272 // If it is not available we exit.
3273 unsigned ATReg = getATReg(IDLoc);
3274 if (!ATReg)
3275 return true;
3276 TmpReg = ATReg;
3279 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3280 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3281 IDLoc, STI);
3283 if (UseSrcReg)
3284 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3285 else
3286 assert(
3287 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3289 return false;
3292 // Each double-precision register DO-D15 overlaps with two of the single
3293 // precision registers F0-F31. As an example, all of the following hold true:
3294 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3295 static unsigned nextReg(unsigned Reg) {
3296 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3297 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3298 switch (Reg) {
3299 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3300 case Mips::ZERO: return Mips::AT;
3301 case Mips::AT: return Mips::V0;
3302 case Mips::V0: return Mips::V1;
3303 case Mips::V1: return Mips::A0;
3304 case Mips::A0: return Mips::A1;
3305 case Mips::A1: return Mips::A2;
3306 case Mips::A2: return Mips::A3;
3307 case Mips::A3: return Mips::T0;
3308 case Mips::T0: return Mips::T1;
3309 case Mips::T1: return Mips::T2;
3310 case Mips::T2: return Mips::T3;
3311 case Mips::T3: return Mips::T4;
3312 case Mips::T4: return Mips::T5;
3313 case Mips::T5: return Mips::T6;
3314 case Mips::T6: return Mips::T7;
3315 case Mips::T7: return Mips::S0;
3316 case Mips::S0: return Mips::S1;
3317 case Mips::S1: return Mips::S2;
3318 case Mips::S2: return Mips::S3;
3319 case Mips::S3: return Mips::S4;
3320 case Mips::S4: return Mips::S5;
3321 case Mips::S5: return Mips::S6;
3322 case Mips::S6: return Mips::S7;
3323 case Mips::S7: return Mips::T8;
3324 case Mips::T8: return Mips::T9;
3325 case Mips::T9: return Mips::K0;
3326 case Mips::K0: return Mips::K1;
3327 case Mips::K1: return Mips::GP;
3328 case Mips::GP: return Mips::SP;
3329 case Mips::SP: return Mips::FP;
3330 case Mips::FP: return Mips::RA;
3331 case Mips::RA: return Mips::ZERO;
3332 case Mips::D0: return Mips::F1;
3333 case Mips::D1: return Mips::F3;
3334 case Mips::D2: return Mips::F5;
3335 case Mips::D3: return Mips::F7;
3336 case Mips::D4: return Mips::F9;
3337 case Mips::D5: return Mips::F11;
3338 case Mips::D6: return Mips::F13;
3339 case Mips::D7: return Mips::F15;
3340 case Mips::D8: return Mips::F17;
3341 case Mips::D9: return Mips::F19;
3342 case Mips::D10: return Mips::F21;
3343 case Mips::D11: return Mips::F23;
3344 case Mips::D12: return Mips::F25;
3345 case Mips::D13: return Mips::F27;
3346 case Mips::D14: return Mips::F29;
3347 case Mips::D15: return Mips::F31;
3351 // FIXME: This method is too general. In principle we should compute the number
3352 // of instructions required to synthesize the immediate inline compared to
3353 // synthesizing the address inline and relying on non .text sections.
3354 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3355 // likely to yield a much larger benefit as we have to synthesize a 64bit
3356 // address to load a 64 bit value.
3357 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3358 MCSymbol *Sym) {
3359 unsigned ATReg = getATReg(IDLoc);
3360 if (!ATReg)
3361 return true;
3363 if(IsPicEnabled) {
3364 const MCExpr *GotSym =
3365 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3366 const MipsMCExpr *GotExpr =
3367 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3369 if(isABI_O32() || isABI_N32()) {
3370 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3371 IDLoc, STI);
3372 } else { //isABI_N64()
3373 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3374 IDLoc, STI);
3376 } else { //!IsPicEnabled
3377 const MCExpr *HiSym =
3378 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3379 const MipsMCExpr *HiExpr =
3380 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3382 // FIXME: This is technically correct but gives a different result to gas,
3383 // but gas is incomplete there (it has a fixme noting it doesn't work with
3384 // 64-bit addresses).
3385 // FIXME: With -msym32 option, the address expansion for N64 should probably
3386 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3387 // symbol's value is considered sign extended.
3388 if(isABI_O32() || isABI_N32()) {
3389 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3390 } else { //isABI_N64()
3391 const MCExpr *HighestSym =
3392 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3393 const MipsMCExpr *HighestExpr =
3394 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3395 const MCExpr *HigherSym =
3396 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3397 const MipsMCExpr *HigherExpr =
3398 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3400 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3401 STI);
3402 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3403 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3404 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3405 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3406 IDLoc, STI);
3407 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3410 return false;
3413 static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) {
3414 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3415 // exponent field), convert it to double (e.g. 1 to 1.0)
3416 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3417 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3418 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3420 return ImmOp64;
3423 static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) {
3424 // Conversion of a double in an uint64_t to a float in a uint32_t,
3425 // retaining the bit pattern of a float.
3426 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3427 float TmpFloat = static_cast<float>(DoubleImm);
3428 return llvm::bit_cast<uint32_t>(TmpFloat);
3431 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3432 MCStreamer &Out,
3433 const MCSubtargetInfo *STI) {
3434 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3435 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3436 "Invalid instruction operand.");
3438 unsigned FirstReg = Inst.getOperand(0).getReg();
3439 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3441 uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3443 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3444 Out, STI);
3447 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3448 MCStreamer &Out,
3449 const MCSubtargetInfo *STI) {
3450 MipsTargetStreamer &TOut = getTargetStreamer();
3451 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3452 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3453 "Invalid instruction operand.");
3455 unsigned FirstReg = Inst.getOperand(0).getReg();
3456 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3458 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3460 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3462 unsigned TmpReg = Mips::ZERO;
3463 if (ImmOp32 != 0) {
3464 TmpReg = getATReg(IDLoc);
3465 if (!TmpReg)
3466 return true;
3469 if (Lo_32(ImmOp64) == 0) {
3470 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3471 true, false, IDLoc, Out, STI))
3472 return true;
3473 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3474 return false;
3477 MCSection *CS = getStreamer().getCurrentSectionOnly();
3478 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3479 // where appropriate.
3480 MCSection *ReadOnlySection =
3481 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3483 MCSymbol *Sym = getContext().createTempSymbol();
3484 const MCExpr *LoSym =
3485 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3486 const MipsMCExpr *LoExpr =
3487 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3489 getStreamer().switchSection(ReadOnlySection);
3490 getStreamer().emitLabel(Sym, IDLoc);
3491 getStreamer().emitInt32(ImmOp32);
3492 getStreamer().switchSection(CS);
3494 if (emitPartialAddress(TOut, IDLoc, Sym))
3495 return true;
3496 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3497 IDLoc, STI);
3498 return false;
3501 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3502 MCStreamer &Out,
3503 const MCSubtargetInfo *STI) {
3504 MipsTargetStreamer &TOut = getTargetStreamer();
3505 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3506 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3507 "Invalid instruction operand.");
3509 unsigned FirstReg = Inst.getOperand(0).getReg();
3510 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3512 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3514 if (Lo_32(ImmOp64) == 0) {
3515 if (isGP64bit()) {
3516 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3517 IDLoc, Out, STI))
3518 return true;
3519 } else {
3520 if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3521 IDLoc, Out, STI))
3522 return true;
3524 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3525 IDLoc, Out, STI))
3526 return true;
3528 return false;
3531 MCSection *CS = getStreamer().getCurrentSectionOnly();
3532 MCSection *ReadOnlySection =
3533 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3535 MCSymbol *Sym = getContext().createTempSymbol();
3536 const MCExpr *LoSym =
3537 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3538 const MipsMCExpr *LoExpr =
3539 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3541 getStreamer().switchSection(ReadOnlySection);
3542 getStreamer().emitLabel(Sym, IDLoc);
3543 getStreamer().emitValueToAlignment(Align(8));
3544 getStreamer().emitIntValue(ImmOp64, 8);
3545 getStreamer().switchSection(CS);
3547 unsigned TmpReg = getATReg(IDLoc);
3548 if (!TmpReg)
3549 return true;
3551 if (emitPartialAddress(TOut, IDLoc, Sym))
3552 return true;
3554 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3555 MCOperand::createExpr(LoExpr), IDLoc, STI);
3557 if (isGP64bit())
3558 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3559 else {
3560 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3561 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3563 return false;
3566 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3567 SMLoc IDLoc, MCStreamer &Out,
3568 const MCSubtargetInfo *STI) {
3569 MipsTargetStreamer &TOut = getTargetStreamer();
3570 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3571 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3572 "Invalid instruction operand.");
3574 unsigned FirstReg = Inst.getOperand(0).getReg();
3575 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3577 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3579 unsigned TmpReg = Mips::ZERO;
3580 if (ImmOp64 != 0) {
3581 TmpReg = getATReg(IDLoc);
3582 if (!TmpReg)
3583 return true;
3586 if ((Lo_32(ImmOp64) == 0) &&
3587 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3588 if (isGP64bit()) {
3589 if (TmpReg != Mips::ZERO &&
3590 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3591 Out, STI))
3592 return true;
3593 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3594 return false;
3597 if (TmpReg != Mips::ZERO &&
3598 loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3599 IDLoc, Out, STI))
3600 return true;
3602 if (hasMips32r2()) {
3603 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3604 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3605 } else {
3606 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3607 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3609 return false;
3612 MCSection *CS = getStreamer().getCurrentSectionOnly();
3613 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3614 // where appropriate.
3615 MCSection *ReadOnlySection =
3616 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3618 MCSymbol *Sym = getContext().createTempSymbol();
3619 const MCExpr *LoSym =
3620 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3621 const MipsMCExpr *LoExpr =
3622 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3624 getStreamer().switchSection(ReadOnlySection);
3625 getStreamer().emitLabel(Sym, IDLoc);
3626 getStreamer().emitValueToAlignment(Align(8));
3627 getStreamer().emitIntValue(ImmOp64, 8);
3628 getStreamer().switchSection(CS);
3630 if (emitPartialAddress(TOut, IDLoc, Sym))
3631 return true;
3633 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3634 MCOperand::createExpr(LoExpr), IDLoc, STI);
3636 return false;
3639 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3640 MCStreamer &Out,
3641 const MCSubtargetInfo *STI) {
3642 MipsTargetStreamer &TOut = getTargetStreamer();
3644 assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 &&
3645 "unexpected number of operands");
3647 MCOperand Offset = Inst.getOperand(0);
3648 if (Offset.isExpr()) {
3649 Inst.clear();
3650 Inst.setOpcode(Mips::BEQ_MM);
3651 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3652 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3653 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3654 } else {
3655 assert(Offset.isImm() && "expected immediate operand kind");
3656 if (isInt<11>(Offset.getImm())) {
3657 // If offset fits into 11 bits then this instruction becomes microMIPS
3658 // 16-bit unconditional branch instruction.
3659 if (inMicroMipsMode())
3660 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3661 } else {
3662 if (!isInt<17>(Offset.getImm()))
3663 return Error(IDLoc, "branch target out of range");
3664 if (offsetToAlignment(Offset.getImm(), Align(2)))
3665 return Error(IDLoc, "branch to misaligned address");
3666 Inst.clear();
3667 Inst.setOpcode(Mips::BEQ_MM);
3668 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3669 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3670 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3673 Out.emitInstruction(Inst, *STI);
3675 // If .set reorder is active and branch instruction has a delay slot,
3676 // emit a NOP after it.
3677 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3678 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3679 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3681 return false;
3684 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3685 const MCSubtargetInfo *STI) {
3686 MipsTargetStreamer &TOut = getTargetStreamer();
3687 const MCOperand &DstRegOp = Inst.getOperand(0);
3688 assert(DstRegOp.isReg() && "expected register operand kind");
3690 const MCOperand &ImmOp = Inst.getOperand(1);
3691 assert(ImmOp.isImm() && "expected immediate operand kind");
3693 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3694 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3695 "expected immediate or expression operand");
3697 bool IsLikely = false;
3699 unsigned OpCode = 0;
3700 switch(Inst.getOpcode()) {
3701 case Mips::BneImm:
3702 OpCode = Mips::BNE;
3703 break;
3704 case Mips::BeqImm:
3705 OpCode = Mips::BEQ;
3706 break;
3707 case Mips::BEQLImmMacro:
3708 OpCode = Mips::BEQL;
3709 IsLikely = true;
3710 break;
3711 case Mips::BNELImmMacro:
3712 OpCode = Mips::BNEL;
3713 IsLikely = true;
3714 break;
3715 default:
3716 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3717 break;
3720 int64_t ImmValue = ImmOp.getImm();
3721 if (ImmValue == 0) {
3722 if (IsLikely) {
3723 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3724 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3725 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3726 } else
3727 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3728 STI);
3729 } else {
3730 warnIfNoMacro(IDLoc);
3732 unsigned ATReg = getATReg(IDLoc);
3733 if (!ATReg)
3734 return true;
3736 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3737 IDLoc, Out, STI))
3738 return true;
3740 if (IsLikely) {
3741 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3742 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3743 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3744 } else
3745 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3747 return false;
3750 void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3751 const MCSubtargetInfo *STI, bool IsLoad) {
3752 unsigned NumOp = Inst.getNumOperands();
3753 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3754 unsigned StartOp = NumOp == 3 ? 0 : 1;
3756 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3757 assert(DstRegOp.isReg() && "expected register operand kind");
3758 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3759 assert(BaseRegOp.isReg() && "expected register operand kind");
3760 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3762 MipsTargetStreamer &TOut = getTargetStreamer();
3763 unsigned OpCode = Inst.getOpcode();
3764 unsigned DstReg = DstRegOp.getReg();
3765 unsigned BaseReg = BaseRegOp.getReg();
3766 unsigned TmpReg = DstReg;
3768 const MCInstrDesc &Desc = MII.get(OpCode);
3769 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3770 unsigned DstRegClassID =
3771 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3772 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3773 (DstRegClassID == Mips::GPR64RegClassID);
3775 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3776 // At this point we need AT to perform the expansions
3777 // and we exit if it is not available.
3778 TmpReg = getATReg(IDLoc);
3779 if (!TmpReg)
3780 return;
3783 auto emitInstWithOffset = [&](const MCOperand &Off) {
3784 if (NumOp == 3)
3785 TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3786 else
3787 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3790 if (OffsetOp.isImm()) {
3791 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3792 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3794 // If msb of LoOffset is 1(negative number) we must increment
3795 // HiOffset to account for the sign-extension of the low part.
3796 if (LoOffset & 0x8000)
3797 HiOffset += 0x10000;
3799 bool IsLargeOffset = HiOffset != 0;
3801 if (IsLargeOffset) {
3802 bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3803 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3804 IDLoc, Out, STI))
3805 return;
3808 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3809 TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3810 TmpReg, BaseReg, IDLoc, STI);
3811 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3812 return;
3815 if (OffsetOp.isExpr()) {
3816 if (inPicMode()) {
3817 // FIXME:
3818 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3819 // do not exceed 16-bit.
3820 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3821 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3822 // of GOT entries.
3823 MCValue Res;
3824 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3825 Error(IDLoc, "expected relocatable expression");
3826 return;
3828 if (Res.getSymB() != nullptr) {
3829 Error(IDLoc, "expected relocatable expression with only one symbol");
3830 return;
3833 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3834 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3835 emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3836 } else {
3837 // FIXME: Implement 64-bit case.
3838 // 1) lw $8, sym => lui $8, %hi(sym)
3839 // lw $8, %lo(sym)($8)
3840 // 2) sw $8, sym => lui $at, %hi(sym)
3841 // sw $8, %lo(sym)($at)
3842 const MCExpr *OffExpr = OffsetOp.getExpr();
3843 MCOperand LoOperand = MCOperand::createExpr(
3844 MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
3845 MCOperand HiOperand = MCOperand::createExpr(
3846 MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
3848 if (ABI.IsN64()) {
3849 MCOperand HighestOperand = MCOperand::createExpr(
3850 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
3851 MCOperand HigherOperand = MCOperand::createExpr(
3852 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
3854 TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3855 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3856 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3857 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3858 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3859 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3860 TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3861 emitInstWithOffset(LoOperand);
3862 } else {
3863 // Generate the base address in TmpReg.
3864 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3865 if (BaseReg != Mips::ZERO)
3866 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3867 // Emit the load or store with the adjusted base and offset.
3868 emitInstWithOffset(LoOperand);
3871 return;
3874 llvm_unreachable("unexpected operand type");
3877 void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3878 const MCSubtargetInfo *STI, bool IsLoad) {
3879 unsigned NumOp = Inst.getNumOperands();
3880 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3881 unsigned StartOp = NumOp == 3 ? 0 : 1;
3883 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3884 assert(DstRegOp.isReg() && "expected register operand kind");
3885 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3886 assert(BaseRegOp.isReg() && "expected register operand kind");
3887 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3889 MipsTargetStreamer &TOut = getTargetStreamer();
3890 unsigned OpCode = Inst.getOpcode();
3891 unsigned DstReg = DstRegOp.getReg();
3892 unsigned BaseReg = BaseRegOp.getReg();
3893 unsigned TmpReg = DstReg;
3895 const MCInstrDesc &Desc = MII.get(OpCode);
3896 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3897 unsigned DstRegClassID =
3898 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3899 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3900 (DstRegClassID == Mips::GPR64RegClassID);
3902 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3903 // At this point we need AT to perform the expansions
3904 // and we exit if it is not available.
3905 TmpReg = getATReg(IDLoc);
3906 if (!TmpReg)
3907 return;
3910 auto emitInst = [&]() {
3911 if (NumOp == 3)
3912 TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3913 else
3914 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3915 IDLoc, STI);
3918 if (OffsetOp.isImm()) {
3919 loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3920 IDLoc, Out, STI);
3921 emitInst();
3922 return;
3925 if (OffsetOp.isExpr()) {
3926 loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3927 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3928 emitInst();
3929 return;
3932 llvm_unreachable("unexpected operand type");
3935 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3936 MCStreamer &Out,
3937 const MCSubtargetInfo *STI) {
3938 unsigned OpNum = Inst.getNumOperands();
3939 unsigned Opcode = Inst.getOpcode();
3940 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3942 assert(Inst.getOperand(OpNum - 1).isImm() &&
3943 Inst.getOperand(OpNum - 2).isReg() &&
3944 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3946 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3947 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3948 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3949 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3950 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3951 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3952 // It can be implemented as SWM16 or LWM16 instruction.
3953 if (inMicroMipsMode() && hasMips32r6())
3954 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3955 else
3956 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3959 Inst.setOpcode(NewOpcode);
3960 Out.emitInstruction(Inst, *STI);
3961 return false;
3964 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3965 MCStreamer &Out,
3966 const MCSubtargetInfo *STI) {
3967 MipsTargetStreamer &TOut = getTargetStreamer();
3968 bool EmittedNoMacroWarning = false;
3969 unsigned PseudoOpcode = Inst.getOpcode();
3970 unsigned SrcReg = Inst.getOperand(0).getReg();
3971 const MCOperand &TrgOp = Inst.getOperand(1);
3972 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3974 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3975 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3977 unsigned TrgReg;
3978 if (TrgOp.isReg())
3979 TrgReg = TrgOp.getReg();
3980 else if (TrgOp.isImm()) {
3981 warnIfNoMacro(IDLoc);
3982 EmittedNoMacroWarning = true;
3984 TrgReg = getATReg(IDLoc);
3985 if (!TrgReg)
3986 return true;
3988 switch(PseudoOpcode) {
3989 default:
3990 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3991 case Mips::BLTImmMacro:
3992 PseudoOpcode = Mips::BLT;
3993 break;
3994 case Mips::BLEImmMacro:
3995 PseudoOpcode = Mips::BLE;
3996 break;
3997 case Mips::BGEImmMacro:
3998 PseudoOpcode = Mips::BGE;
3999 break;
4000 case Mips::BGTImmMacro:
4001 PseudoOpcode = Mips::BGT;
4002 break;
4003 case Mips::BLTUImmMacro:
4004 PseudoOpcode = Mips::BLTU;
4005 break;
4006 case Mips::BLEUImmMacro:
4007 PseudoOpcode = Mips::BLEU;
4008 break;
4009 case Mips::BGEUImmMacro:
4010 PseudoOpcode = Mips::BGEU;
4011 break;
4012 case Mips::BGTUImmMacro:
4013 PseudoOpcode = Mips::BGTU;
4014 break;
4015 case Mips::BLTLImmMacro:
4016 PseudoOpcode = Mips::BLTL;
4017 break;
4018 case Mips::BLELImmMacro:
4019 PseudoOpcode = Mips::BLEL;
4020 break;
4021 case Mips::BGELImmMacro:
4022 PseudoOpcode = Mips::BGEL;
4023 break;
4024 case Mips::BGTLImmMacro:
4025 PseudoOpcode = Mips::BGTL;
4026 break;
4027 case Mips::BLTULImmMacro:
4028 PseudoOpcode = Mips::BLTUL;
4029 break;
4030 case Mips::BLEULImmMacro:
4031 PseudoOpcode = Mips::BLEUL;
4032 break;
4033 case Mips::BGEULImmMacro:
4034 PseudoOpcode = Mips::BGEUL;
4035 break;
4036 case Mips::BGTULImmMacro:
4037 PseudoOpcode = Mips::BGTUL;
4038 break;
4041 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4042 false, IDLoc, Out, STI))
4043 return true;
4046 switch (PseudoOpcode) {
4047 case Mips::BLT:
4048 case Mips::BLTU:
4049 case Mips::BLTL:
4050 case Mips::BLTUL:
4051 AcceptsEquality = false;
4052 ReverseOrderSLT = false;
4053 IsUnsigned =
4054 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4055 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4056 ZeroSrcOpcode = Mips::BGTZ;
4057 ZeroTrgOpcode = Mips::BLTZ;
4058 break;
4059 case Mips::BLE:
4060 case Mips::BLEU:
4061 case Mips::BLEL:
4062 case Mips::BLEUL:
4063 AcceptsEquality = true;
4064 ReverseOrderSLT = true;
4065 IsUnsigned =
4066 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4067 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4068 ZeroSrcOpcode = Mips::BGEZ;
4069 ZeroTrgOpcode = Mips::BLEZ;
4070 break;
4071 case Mips::BGE:
4072 case Mips::BGEU:
4073 case Mips::BGEL:
4074 case Mips::BGEUL:
4075 AcceptsEquality = true;
4076 ReverseOrderSLT = false;
4077 IsUnsigned =
4078 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4079 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4080 ZeroSrcOpcode = Mips::BLEZ;
4081 ZeroTrgOpcode = Mips::BGEZ;
4082 break;
4083 case Mips::BGT:
4084 case Mips::BGTU:
4085 case Mips::BGTL:
4086 case Mips::BGTUL:
4087 AcceptsEquality = false;
4088 ReverseOrderSLT = true;
4089 IsUnsigned =
4090 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4091 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4092 ZeroSrcOpcode = Mips::BLTZ;
4093 ZeroTrgOpcode = Mips::BGTZ;
4094 break;
4095 default:
4096 llvm_unreachable("unknown opcode for branch pseudo-instruction");
4099 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4100 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4101 if (IsSrcRegZero && IsTrgRegZero) {
4102 // FIXME: All of these Opcode-specific if's are needed for compatibility
4103 // with GAS' behaviour. However, they may not generate the most efficient
4104 // code in some circumstances.
4105 if (PseudoOpcode == Mips::BLT) {
4106 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4107 IDLoc, STI);
4108 return false;
4110 if (PseudoOpcode == Mips::BLE) {
4111 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4112 IDLoc, STI);
4113 Warning(IDLoc, "branch is always taken");
4114 return false;
4116 if (PseudoOpcode == Mips::BGE) {
4117 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4118 IDLoc, STI);
4119 Warning(IDLoc, "branch is always taken");
4120 return false;
4122 if (PseudoOpcode == Mips::BGT) {
4123 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4124 IDLoc, STI);
4125 return false;
4127 if (PseudoOpcode == Mips::BGTU) {
4128 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4129 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4130 return false;
4132 if (AcceptsEquality) {
4133 // If both registers are $0 and the pseudo-branch accepts equality, it
4134 // will always be taken, so we emit an unconditional branch.
4135 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4136 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4137 Warning(IDLoc, "branch is always taken");
4138 return false;
4140 // If both registers are $0 and the pseudo-branch does not accept
4141 // equality, it will never be taken, so we don't have to emit anything.
4142 return false;
4144 if (IsSrcRegZero || IsTrgRegZero) {
4145 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4146 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4147 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4148 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4149 // the pseudo-branch will never be taken, so we don't emit anything.
4150 // This only applies to unsigned pseudo-branches.
4151 return false;
4153 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4154 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4155 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4156 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4157 // the pseudo-branch will always be taken, so we emit an unconditional
4158 // branch.
4159 // This only applies to unsigned pseudo-branches.
4160 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4161 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4162 Warning(IDLoc, "branch is always taken");
4163 return false;
4165 if (IsUnsigned) {
4166 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4167 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4168 // the pseudo-branch will be taken only when the non-zero register is
4169 // different from 0, so we emit a BNEZ.
4171 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4172 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4173 // the pseudo-branch will be taken only when the non-zero register is
4174 // equal to 0, so we emit a BEQZ.
4176 // Because only BLEU and BGEU branch on equality, we can use the
4177 // AcceptsEquality variable to decide when to emit the BEQZ.
4178 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4179 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4180 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4181 return false;
4183 // If we have a signed pseudo-branch and one of the registers is $0,
4184 // we can use an appropriate compare-to-zero branch. We select which one
4185 // to use in the switch statement above.
4186 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4187 IsSrcRegZero ? TrgReg : SrcReg,
4188 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4189 return false;
4192 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4193 // expansions. If it is not available, we return.
4194 unsigned ATRegNum = getATReg(IDLoc);
4195 if (!ATRegNum)
4196 return true;
4198 if (!EmittedNoMacroWarning)
4199 warnIfNoMacro(IDLoc);
4201 // SLT fits well with 2 of our 4 pseudo-branches:
4202 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4203 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4204 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4205 // This is accomplished by using a BNEZ with the result of the SLT.
4207 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4208 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4209 // Because only BGE and BLE branch on equality, we can use the
4210 // AcceptsEquality variable to decide when to emit the BEQZ.
4211 // Note that the order of the SLT arguments doesn't change between
4212 // opposites.
4214 // The same applies to the unsigned variants, except that SLTu is used
4215 // instead of SLT.
4216 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4217 ReverseOrderSLT ? TrgReg : SrcReg,
4218 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4220 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4221 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4222 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4223 STI);
4224 return false;
4227 // Expand a integer division macro.
4229 // Notably we don't have to emit a warning when encountering $rt as the $zero
4230 // register, or 0 as an immediate. processInstruction() has already done that.
4232 // The destination register can only be $zero when expanding (S)DivIMacro or
4233 // D(S)DivMacro.
4235 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4236 const MCSubtargetInfo *STI,
4237 const bool IsMips64, const bool Signed) {
4238 MipsTargetStreamer &TOut = getTargetStreamer();
4240 warnIfNoMacro(IDLoc);
4242 const MCOperand &RdRegOp = Inst.getOperand(0);
4243 assert(RdRegOp.isReg() && "expected register operand kind");
4244 unsigned RdReg = RdRegOp.getReg();
4246 const MCOperand &RsRegOp = Inst.getOperand(1);
4247 assert(RsRegOp.isReg() && "expected register operand kind");
4248 unsigned RsReg = RsRegOp.getReg();
4250 unsigned RtReg;
4251 int64_t ImmValue;
4253 const MCOperand &RtOp = Inst.getOperand(2);
4254 assert((RtOp.isReg() || RtOp.isImm()) &&
4255 "expected register or immediate operand kind");
4256 if (RtOp.isReg())
4257 RtReg = RtOp.getReg();
4258 else
4259 ImmValue = RtOp.getImm();
4261 unsigned DivOp;
4262 unsigned ZeroReg;
4263 unsigned SubOp;
4265 if (IsMips64) {
4266 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4267 ZeroReg = Mips::ZERO_64;
4268 SubOp = Mips::DSUB;
4269 } else {
4270 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4271 ZeroReg = Mips::ZERO;
4272 SubOp = Mips::SUB;
4275 bool UseTraps = useTraps();
4277 unsigned Opcode = Inst.getOpcode();
4278 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4279 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4280 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4281 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4283 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4284 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4285 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4286 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4288 if (RtOp.isImm()) {
4289 unsigned ATReg = getATReg(IDLoc);
4290 if (!ATReg)
4291 return true;
4293 if (ImmValue == 0) {
4294 if (UseTraps)
4295 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4296 else
4297 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4298 return false;
4301 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4302 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4303 return false;
4304 } else if (isDiv && ImmValue == 1) {
4305 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4306 return false;
4307 } else if (isDiv && Signed && ImmValue == -1) {
4308 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4309 return false;
4310 } else {
4311 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4312 false, Inst.getLoc(), Out, STI))
4313 return true;
4314 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4315 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4316 return false;
4318 return true;
4321 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4322 // break, insert the trap/break and exit. This gives a different result to
4323 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4324 // are handled equivalently. As the observed behaviour is the same, we're ok.
4325 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4326 if (UseTraps) {
4327 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4328 return false;
4330 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4331 return false;
4334 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4335 // not expand to macro sequence.
4336 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4337 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4338 return false;
4341 // Temporary label for first branch traget
4342 MCContext &Context = TOut.getStreamer().getContext();
4343 MCSymbol *BrTarget;
4344 MCOperand LabelOp;
4346 if (UseTraps) {
4347 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4348 } else {
4349 // Branch to the li instruction.
4350 BrTarget = Context.createTempSymbol();
4351 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4352 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4355 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4357 if (!UseTraps)
4358 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4360 if (!Signed) {
4361 if (!UseTraps)
4362 TOut.getStreamer().emitLabel(BrTarget);
4364 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4365 return false;
4368 unsigned ATReg = getATReg(IDLoc);
4369 if (!ATReg)
4370 return true;
4372 if (!UseTraps)
4373 TOut.getStreamer().emitLabel(BrTarget);
4375 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4377 // Temporary label for the second branch target.
4378 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4379 MCOperand LabelOpEnd =
4380 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4382 // Branch to the mflo instruction.
4383 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4385 if (IsMips64) {
4386 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4387 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4388 } else {
4389 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4392 if (UseTraps)
4393 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4394 else {
4395 // Branch to the mflo instruction.
4396 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4397 TOut.emitNop(IDLoc, STI);
4398 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4401 TOut.getStreamer().emitLabel(BrTargetEnd);
4402 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4403 return false;
4406 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4407 SMLoc IDLoc, MCStreamer &Out,
4408 const MCSubtargetInfo *STI) {
4409 MipsTargetStreamer &TOut = getTargetStreamer();
4411 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4412 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4413 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4415 unsigned FirstReg = Inst.getOperand(0).getReg();
4416 unsigned SecondReg = Inst.getOperand(1).getReg();
4417 unsigned ThirdReg = Inst.getOperand(2).getReg();
4419 if (hasMips1() && !hasMips2()) {
4420 unsigned ATReg = getATReg(IDLoc);
4421 if (!ATReg)
4422 return true;
4423 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4424 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4425 TOut.emitNop(IDLoc, STI);
4426 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4427 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4428 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4429 TOut.emitNop(IDLoc, STI);
4430 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4431 : Mips::CVT_W_S,
4432 FirstReg, SecondReg, IDLoc, STI);
4433 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4434 TOut.emitNop(IDLoc, STI);
4435 return false;
4438 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4439 : Mips::TRUNC_W_S,
4440 FirstReg, SecondReg, IDLoc, STI);
4442 return false;
4445 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4446 MCStreamer &Out, const MCSubtargetInfo *STI) {
4447 if (hasMips32r6() || hasMips64r6()) {
4448 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4451 const MCOperand &DstRegOp = Inst.getOperand(0);
4452 assert(DstRegOp.isReg() && "expected register operand kind");
4453 const MCOperand &SrcRegOp = Inst.getOperand(1);
4454 assert(SrcRegOp.isReg() && "expected register operand kind");
4455 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4456 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4458 MipsTargetStreamer &TOut = getTargetStreamer();
4459 unsigned DstReg = DstRegOp.getReg();
4460 unsigned SrcReg = SrcRegOp.getReg();
4461 int64_t OffsetValue = OffsetImmOp.getImm();
4463 // NOTE: We always need AT for ULHU, as it is always used as the source
4464 // register for one of the LBu's.
4465 warnIfNoMacro(IDLoc);
4466 unsigned ATReg = getATReg(IDLoc);
4467 if (!ATReg)
4468 return true;
4470 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4471 if (IsLargeOffset) {
4472 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4473 IDLoc, Out, STI))
4474 return true;
4477 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4478 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4479 if (isLittle())
4480 std::swap(FirstOffset, SecondOffset);
4482 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4483 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4485 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4486 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4488 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4489 FirstOffset, IDLoc, STI);
4490 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4491 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4492 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4494 return false;
4497 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4498 const MCSubtargetInfo *STI) {
4499 if (hasMips32r6() || hasMips64r6()) {
4500 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4503 const MCOperand &DstRegOp = Inst.getOperand(0);
4504 assert(DstRegOp.isReg() && "expected register operand kind");
4505 const MCOperand &SrcRegOp = Inst.getOperand(1);
4506 assert(SrcRegOp.isReg() && "expected register operand kind");
4507 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4508 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4510 MipsTargetStreamer &TOut = getTargetStreamer();
4511 unsigned DstReg = DstRegOp.getReg();
4512 unsigned SrcReg = SrcRegOp.getReg();
4513 int64_t OffsetValue = OffsetImmOp.getImm();
4515 warnIfNoMacro(IDLoc);
4516 unsigned ATReg = getATReg(IDLoc);
4517 if (!ATReg)
4518 return true;
4520 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4521 if (IsLargeOffset) {
4522 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4523 IDLoc, Out, STI))
4524 return true;
4527 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4528 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4529 if (isLittle())
4530 std::swap(FirstOffset, SecondOffset);
4532 if (IsLargeOffset) {
4533 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4534 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4535 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4536 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4537 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4538 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4539 } else {
4540 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4541 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4542 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4545 return false;
4548 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4549 const MCSubtargetInfo *STI) {
4550 if (hasMips32r6() || hasMips64r6()) {
4551 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4554 const MCOperand &DstRegOp = Inst.getOperand(0);
4555 assert(DstRegOp.isReg() && "expected register operand kind");
4556 const MCOperand &SrcRegOp = Inst.getOperand(1);
4557 assert(SrcRegOp.isReg() && "expected register operand kind");
4558 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4559 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4561 MipsTargetStreamer &TOut = getTargetStreamer();
4562 unsigned DstReg = DstRegOp.getReg();
4563 unsigned SrcReg = SrcRegOp.getReg();
4564 int64_t OffsetValue = OffsetImmOp.getImm();
4566 // Compute left/right load/store offsets.
4567 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4568 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4569 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4570 if (isLittle())
4571 std::swap(LxlOffset, LxrOffset);
4573 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4574 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4575 unsigned TmpReg = SrcReg;
4576 if (IsLargeOffset || DoMove) {
4577 warnIfNoMacro(IDLoc);
4578 TmpReg = getATReg(IDLoc);
4579 if (!TmpReg)
4580 return true;
4583 if (IsLargeOffset) {
4584 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4585 IDLoc, Out, STI))
4586 return true;
4589 if (DoMove)
4590 std::swap(DstReg, TmpReg);
4592 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4593 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4594 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4595 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4597 if (DoMove)
4598 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4600 return false;
4603 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4604 const MCSubtargetInfo *STI) {
4605 MipsTargetStreamer &TOut = getTargetStreamer();
4607 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4608 assert(Inst.getOperand(0).isReg() &&
4609 Inst.getOperand(1).isReg() &&
4610 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4612 unsigned DstReg = Inst.getOperand(0).getReg();
4613 unsigned SrcReg = Inst.getOperand(1).getReg();
4614 unsigned OpReg = Inst.getOperand(2).getReg();
4615 unsigned OpCode;
4617 warnIfNoMacro(IDLoc);
4619 switch (Inst.getOpcode()) {
4620 case Mips::SGE:
4621 OpCode = Mips::SLT;
4622 break;
4623 case Mips::SGEU:
4624 OpCode = Mips::SLTu;
4625 break;
4626 default:
4627 llvm_unreachable("unexpected 'sge' opcode");
4630 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4631 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4632 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4634 return false;
4637 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4638 const MCSubtargetInfo *STI) {
4639 MipsTargetStreamer &TOut = getTargetStreamer();
4641 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4642 assert(Inst.getOperand(0).isReg() &&
4643 Inst.getOperand(1).isReg() &&
4644 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4646 unsigned DstReg = Inst.getOperand(0).getReg();
4647 unsigned SrcReg = Inst.getOperand(1).getReg();
4648 int64_t ImmValue = Inst.getOperand(2).getImm();
4649 unsigned OpRegCode, OpImmCode;
4651 warnIfNoMacro(IDLoc);
4653 switch (Inst.getOpcode()) {
4654 case Mips::SGEImm:
4655 case Mips::SGEImm64:
4656 OpRegCode = Mips::SLT;
4657 OpImmCode = Mips::SLTi;
4658 break;
4659 case Mips::SGEUImm:
4660 case Mips::SGEUImm64:
4661 OpRegCode = Mips::SLTu;
4662 OpImmCode = Mips::SLTiu;
4663 break;
4664 default:
4665 llvm_unreachable("unexpected 'sge' opcode with immediate");
4668 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4669 if (isInt<16>(ImmValue)) {
4670 // Use immediate version of STL.
4671 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4672 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4673 } else {
4674 unsigned ImmReg = DstReg;
4675 if (DstReg == SrcReg) {
4676 unsigned ATReg = getATReg(Inst.getLoc());
4677 if (!ATReg)
4678 return true;
4679 ImmReg = ATReg;
4682 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4683 false, IDLoc, Out, STI))
4684 return true;
4686 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4687 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4690 return false;
4693 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4694 const MCSubtargetInfo *STI) {
4695 MipsTargetStreamer &TOut = getTargetStreamer();
4697 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4698 assert(Inst.getOperand(0).isReg() &&
4699 Inst.getOperand(1).isReg() &&
4700 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4702 unsigned DstReg = Inst.getOperand(0).getReg();
4703 unsigned SrcReg = Inst.getOperand(1).getReg();
4704 unsigned ImmReg = DstReg;
4705 int64_t ImmValue = Inst.getOperand(2).getImm();
4706 unsigned OpCode;
4708 warnIfNoMacro(IDLoc);
4710 switch (Inst.getOpcode()) {
4711 case Mips::SGTImm:
4712 case Mips::SGTImm64:
4713 OpCode = Mips::SLT;
4714 break;
4715 case Mips::SGTUImm:
4716 case Mips::SGTUImm64:
4717 OpCode = Mips::SLTu;
4718 break;
4719 default:
4720 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4723 if (DstReg == SrcReg) {
4724 unsigned ATReg = getATReg(Inst.getLoc());
4725 if (!ATReg)
4726 return true;
4727 ImmReg = ATReg;
4730 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4731 false, IDLoc, Out, STI))
4732 return true;
4734 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4735 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4737 return false;
4740 bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4741 const MCSubtargetInfo *STI) {
4742 MipsTargetStreamer &TOut = getTargetStreamer();
4744 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4745 assert(Inst.getOperand(0).isReg() &&
4746 Inst.getOperand(1).isReg() &&
4747 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4749 unsigned DstReg = Inst.getOperand(0).getReg();
4750 unsigned SrcReg = Inst.getOperand(1).getReg();
4751 unsigned OpReg = Inst.getOperand(2).getReg();
4752 unsigned OpCode;
4754 warnIfNoMacro(IDLoc);
4756 switch (Inst.getOpcode()) {
4757 case Mips::SLE:
4758 OpCode = Mips::SLT;
4759 break;
4760 case Mips::SLEU:
4761 OpCode = Mips::SLTu;
4762 break;
4763 default:
4764 llvm_unreachable("unexpected 'sge' opcode");
4767 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4768 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4769 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4771 return false;
4774 bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4775 const MCSubtargetInfo *STI) {
4776 MipsTargetStreamer &TOut = getTargetStreamer();
4778 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4779 assert(Inst.getOperand(0).isReg() &&
4780 Inst.getOperand(1).isReg() &&
4781 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4783 unsigned DstReg = Inst.getOperand(0).getReg();
4784 unsigned SrcReg = Inst.getOperand(1).getReg();
4785 int64_t ImmValue = Inst.getOperand(2).getImm();
4786 unsigned OpRegCode;
4788 warnIfNoMacro(IDLoc);
4790 switch (Inst.getOpcode()) {
4791 case Mips::SLEImm:
4792 case Mips::SLEImm64:
4793 OpRegCode = Mips::SLT;
4794 break;
4795 case Mips::SLEUImm:
4796 case Mips::SLEUImm64:
4797 OpRegCode = Mips::SLTu;
4798 break;
4799 default:
4800 llvm_unreachable("unexpected 'sge' opcode with immediate");
4803 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4804 unsigned ImmReg = DstReg;
4805 if (DstReg == SrcReg) {
4806 unsigned ATReg = getATReg(Inst.getLoc());
4807 if (!ATReg)
4808 return true;
4809 ImmReg = ATReg;
4812 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4813 false, IDLoc, Out, STI))
4814 return true;
4816 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4817 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4819 return false;
4822 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4823 MCStreamer &Out,
4824 const MCSubtargetInfo *STI) {
4825 MipsTargetStreamer &TOut = getTargetStreamer();
4827 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4828 assert(Inst.getOperand(0).isReg() &&
4829 Inst.getOperand(1).isReg() &&
4830 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4832 unsigned ATReg = Mips::NoRegister;
4833 unsigned FinalDstReg = Mips::NoRegister;
4834 unsigned DstReg = Inst.getOperand(0).getReg();
4835 unsigned SrcReg = Inst.getOperand(1).getReg();
4836 int64_t ImmValue = Inst.getOperand(2).getImm();
4838 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4840 unsigned FinalOpcode = Inst.getOpcode();
4842 if (DstReg == SrcReg) {
4843 ATReg = getATReg(Inst.getLoc());
4844 if (!ATReg)
4845 return true;
4846 FinalDstReg = DstReg;
4847 DstReg = ATReg;
4850 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4851 Inst.getLoc(), Out, STI)) {
4852 switch (FinalOpcode) {
4853 default:
4854 llvm_unreachable("unimplemented expansion");
4855 case Mips::ADDi:
4856 FinalOpcode = Mips::ADD;
4857 break;
4858 case Mips::ADDiu:
4859 FinalOpcode = Mips::ADDu;
4860 break;
4861 case Mips::ANDi:
4862 FinalOpcode = Mips::AND;
4863 break;
4864 case Mips::NORImm:
4865 FinalOpcode = Mips::NOR;
4866 break;
4867 case Mips::ORi:
4868 FinalOpcode = Mips::OR;
4869 break;
4870 case Mips::SLTi:
4871 FinalOpcode = Mips::SLT;
4872 break;
4873 case Mips::SLTiu:
4874 FinalOpcode = Mips::SLTu;
4875 break;
4876 case Mips::XORi:
4877 FinalOpcode = Mips::XOR;
4878 break;
4879 case Mips::ADDi_MM:
4880 FinalOpcode = Mips::ADD_MM;
4881 break;
4882 case Mips::ADDiu_MM:
4883 FinalOpcode = Mips::ADDu_MM;
4884 break;
4885 case Mips::ANDi_MM:
4886 FinalOpcode = Mips::AND_MM;
4887 break;
4888 case Mips::ORi_MM:
4889 FinalOpcode = Mips::OR_MM;
4890 break;
4891 case Mips::SLTi_MM:
4892 FinalOpcode = Mips::SLT_MM;
4893 break;
4894 case Mips::SLTiu_MM:
4895 FinalOpcode = Mips::SLTu_MM;
4896 break;
4897 case Mips::XORi_MM:
4898 FinalOpcode = Mips::XOR_MM;
4899 break;
4900 case Mips::ANDi64:
4901 FinalOpcode = Mips::AND64;
4902 break;
4903 case Mips::NORImm64:
4904 FinalOpcode = Mips::NOR64;
4905 break;
4906 case Mips::ORi64:
4907 FinalOpcode = Mips::OR64;
4908 break;
4909 case Mips::SLTImm64:
4910 FinalOpcode = Mips::SLT64;
4911 break;
4912 case Mips::SLTUImm64:
4913 FinalOpcode = Mips::SLTu64;
4914 break;
4915 case Mips::XORi64:
4916 FinalOpcode = Mips::XOR64;
4917 break;
4920 if (FinalDstReg == Mips::NoRegister)
4921 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4922 else
4923 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4924 return false;
4926 return true;
4929 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4930 const MCSubtargetInfo *STI) {
4931 MipsTargetStreamer &TOut = getTargetStreamer();
4932 unsigned ATReg = Mips::NoRegister;
4933 unsigned DReg = Inst.getOperand(0).getReg();
4934 unsigned SReg = Inst.getOperand(1).getReg();
4935 unsigned TReg = Inst.getOperand(2).getReg();
4936 unsigned TmpReg = DReg;
4938 unsigned FirstShift = Mips::NOP;
4939 unsigned SecondShift = Mips::NOP;
4941 if (hasMips32r2()) {
4942 if (DReg == SReg) {
4943 TmpReg = getATReg(Inst.getLoc());
4944 if (!TmpReg)
4945 return true;
4948 if (Inst.getOpcode() == Mips::ROL) {
4949 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4950 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4951 return false;
4954 if (Inst.getOpcode() == Mips::ROR) {
4955 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4956 return false;
4959 return true;
4962 if (hasMips32()) {
4963 switch (Inst.getOpcode()) {
4964 default:
4965 llvm_unreachable("unexpected instruction opcode");
4966 case Mips::ROL:
4967 FirstShift = Mips::SRLV;
4968 SecondShift = Mips::SLLV;
4969 break;
4970 case Mips::ROR:
4971 FirstShift = Mips::SLLV;
4972 SecondShift = Mips::SRLV;
4973 break;
4976 ATReg = getATReg(Inst.getLoc());
4977 if (!ATReg)
4978 return true;
4980 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4981 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4982 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4983 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4985 return false;
4988 return true;
4991 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4992 MCStreamer &Out,
4993 const MCSubtargetInfo *STI) {
4994 MipsTargetStreamer &TOut = getTargetStreamer();
4995 unsigned ATReg = Mips::NoRegister;
4996 unsigned DReg = Inst.getOperand(0).getReg();
4997 unsigned SReg = Inst.getOperand(1).getReg();
4998 int64_t ImmValue = Inst.getOperand(2).getImm();
5000 unsigned FirstShift = Mips::NOP;
5001 unsigned SecondShift = Mips::NOP;
5003 if (hasMips32r2()) {
5004 if (Inst.getOpcode() == Mips::ROLImm) {
5005 uint64_t MaxShift = 32;
5006 uint64_t ShiftValue = ImmValue;
5007 if (ImmValue != 0)
5008 ShiftValue = MaxShift - ImmValue;
5009 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5010 return false;
5013 if (Inst.getOpcode() == Mips::RORImm) {
5014 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
5015 return false;
5018 return true;
5021 if (hasMips32()) {
5022 if (ImmValue == 0) {
5023 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
5024 return false;
5027 switch (Inst.getOpcode()) {
5028 default:
5029 llvm_unreachable("unexpected instruction opcode");
5030 case Mips::ROLImm:
5031 FirstShift = Mips::SLL;
5032 SecondShift = Mips::SRL;
5033 break;
5034 case Mips::RORImm:
5035 FirstShift = Mips::SRL;
5036 SecondShift = Mips::SLL;
5037 break;
5040 ATReg = getATReg(Inst.getLoc());
5041 if (!ATReg)
5042 return true;
5044 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
5045 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
5046 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5048 return false;
5051 return true;
5054 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5055 const MCSubtargetInfo *STI) {
5056 MipsTargetStreamer &TOut = getTargetStreamer();
5057 unsigned ATReg = Mips::NoRegister;
5058 unsigned DReg = Inst.getOperand(0).getReg();
5059 unsigned SReg = Inst.getOperand(1).getReg();
5060 unsigned TReg = Inst.getOperand(2).getReg();
5061 unsigned TmpReg = DReg;
5063 unsigned FirstShift = Mips::NOP;
5064 unsigned SecondShift = Mips::NOP;
5066 if (hasMips64r2()) {
5067 if (TmpReg == SReg) {
5068 TmpReg = getATReg(Inst.getLoc());
5069 if (!TmpReg)
5070 return true;
5073 if (Inst.getOpcode() == Mips::DROL) {
5074 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5075 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
5076 return false;
5079 if (Inst.getOpcode() == Mips::DROR) {
5080 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
5081 return false;
5084 return true;
5087 if (hasMips64()) {
5088 switch (Inst.getOpcode()) {
5089 default:
5090 llvm_unreachable("unexpected instruction opcode");
5091 case Mips::DROL:
5092 FirstShift = Mips::DSRLV;
5093 SecondShift = Mips::DSLLV;
5094 break;
5095 case Mips::DROR:
5096 FirstShift = Mips::DSLLV;
5097 SecondShift = Mips::DSRLV;
5098 break;
5101 ATReg = getATReg(Inst.getLoc());
5102 if (!ATReg)
5103 return true;
5105 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5106 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5107 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5108 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5110 return false;
5113 return true;
5116 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5117 MCStreamer &Out,
5118 const MCSubtargetInfo *STI) {
5119 MipsTargetStreamer &TOut = getTargetStreamer();
5120 unsigned ATReg = Mips::NoRegister;
5121 unsigned DReg = Inst.getOperand(0).getReg();
5122 unsigned SReg = Inst.getOperand(1).getReg();
5123 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5125 unsigned FirstShift = Mips::NOP;
5126 unsigned SecondShift = Mips::NOP;
5128 MCInst TmpInst;
5130 if (hasMips64r2()) {
5131 unsigned FinalOpcode = Mips::NOP;
5132 if (ImmValue == 0)
5133 FinalOpcode = Mips::DROTR;
5134 else if (ImmValue % 32 == 0)
5135 FinalOpcode = Mips::DROTR32;
5136 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5137 if (Inst.getOpcode() == Mips::DROLImm)
5138 FinalOpcode = Mips::DROTR32;
5139 else
5140 FinalOpcode = Mips::DROTR;
5141 } else if (ImmValue >= 33) {
5142 if (Inst.getOpcode() == Mips::DROLImm)
5143 FinalOpcode = Mips::DROTR;
5144 else
5145 FinalOpcode = Mips::DROTR32;
5148 uint64_t ShiftValue = ImmValue % 32;
5149 if (Inst.getOpcode() == Mips::DROLImm)
5150 ShiftValue = (32 - ImmValue % 32) % 32;
5152 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5154 return false;
5157 if (hasMips64()) {
5158 if (ImmValue == 0) {
5159 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5160 return false;
5163 switch (Inst.getOpcode()) {
5164 default:
5165 llvm_unreachable("unexpected instruction opcode");
5166 case Mips::DROLImm:
5167 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5168 FirstShift = Mips::DSLL;
5169 SecondShift = Mips::DSRL32;
5171 if (ImmValue == 32) {
5172 FirstShift = Mips::DSLL32;
5173 SecondShift = Mips::DSRL32;
5175 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5176 FirstShift = Mips::DSLL32;
5177 SecondShift = Mips::DSRL;
5179 break;
5180 case Mips::DRORImm:
5181 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5182 FirstShift = Mips::DSRL;
5183 SecondShift = Mips::DSLL32;
5185 if (ImmValue == 32) {
5186 FirstShift = Mips::DSRL32;
5187 SecondShift = Mips::DSLL32;
5189 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5190 FirstShift = Mips::DSRL32;
5191 SecondShift = Mips::DSLL;
5193 break;
5196 ATReg = getATReg(Inst.getLoc());
5197 if (!ATReg)
5198 return true;
5200 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5201 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5202 Inst.getLoc(), STI);
5203 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5205 return false;
5208 return true;
5211 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5212 const MCSubtargetInfo *STI) {
5213 MipsTargetStreamer &TOut = getTargetStreamer();
5214 unsigned FirstRegOp = Inst.getOperand(0).getReg();
5215 unsigned SecondRegOp = Inst.getOperand(1).getReg();
5217 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5218 if (FirstRegOp != SecondRegOp)
5219 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5220 else
5221 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5222 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5224 return false;
5227 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5228 const MCSubtargetInfo *STI) {
5229 MipsTargetStreamer &TOut = getTargetStreamer();
5230 unsigned ATReg = Mips::NoRegister;
5231 unsigned DstReg = Inst.getOperand(0).getReg();
5232 unsigned SrcReg = Inst.getOperand(1).getReg();
5233 int32_t ImmValue = Inst.getOperand(2).getImm();
5235 ATReg = getATReg(IDLoc);
5236 if (!ATReg)
5237 return true;
5239 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
5240 STI);
5242 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5243 SrcReg, ATReg, IDLoc, STI);
5245 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5247 return false;
5250 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5251 const MCSubtargetInfo *STI) {
5252 MipsTargetStreamer &TOut = getTargetStreamer();
5253 unsigned ATReg = Mips::NoRegister;
5254 unsigned DstReg = Inst.getOperand(0).getReg();
5255 unsigned SrcReg = Inst.getOperand(1).getReg();
5256 unsigned TmpReg = Inst.getOperand(2).getReg();
5258 ATReg = getATReg(Inst.getLoc());
5259 if (!ATReg)
5260 return true;
5262 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5263 SrcReg, TmpReg, IDLoc, STI);
5265 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5267 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5268 DstReg, DstReg, 0x1F, IDLoc, STI);
5270 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5272 if (useTraps()) {
5273 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5274 } else {
5275 MCContext & Context = TOut.getStreamer().getContext();
5276 MCSymbol * BrTarget = Context.createTempSymbol();
5277 MCOperand LabelOp =
5278 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5280 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5281 if (AssemblerOptions.back()->isReorder())
5282 TOut.emitNop(IDLoc, STI);
5283 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5285 TOut.getStreamer().emitLabel(BrTarget);
5287 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5289 return false;
5292 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5293 const MCSubtargetInfo *STI) {
5294 MipsTargetStreamer &TOut = getTargetStreamer();
5295 unsigned ATReg = Mips::NoRegister;
5296 unsigned DstReg = Inst.getOperand(0).getReg();
5297 unsigned SrcReg = Inst.getOperand(1).getReg();
5298 unsigned TmpReg = Inst.getOperand(2).getReg();
5300 ATReg = getATReg(IDLoc);
5301 if (!ATReg)
5302 return true;
5304 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5305 SrcReg, TmpReg, IDLoc, STI);
5307 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5308 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5309 if (useTraps()) {
5310 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5311 } else {
5312 MCContext & Context = TOut.getStreamer().getContext();
5313 MCSymbol * BrTarget = Context.createTempSymbol();
5314 MCOperand LabelOp =
5315 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5317 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5318 if (AssemblerOptions.back()->isReorder())
5319 TOut.emitNop(IDLoc, STI);
5320 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5322 TOut.getStreamer().emitLabel(BrTarget);
5325 return false;
5328 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5329 const MCSubtargetInfo *STI) {
5330 MipsTargetStreamer &TOut = getTargetStreamer();
5331 unsigned DstReg = Inst.getOperand(0).getReg();
5332 unsigned SrcReg = Inst.getOperand(1).getReg();
5333 unsigned TmpReg = Inst.getOperand(2).getReg();
5335 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5336 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5338 return false;
5341 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5342 // lw $<reg+1>>, offset+4($reg2)'
5343 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5344 // sw $<reg+1>>, offset+4($reg2)'
5345 // for O32.
5346 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5347 MCStreamer &Out,
5348 const MCSubtargetInfo *STI,
5349 bool IsLoad) {
5350 if (!isABI_O32())
5351 return true;
5353 warnIfNoMacro(IDLoc);
5355 MipsTargetStreamer &TOut = getTargetStreamer();
5356 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5357 unsigned FirstReg = Inst.getOperand(0).getReg();
5358 unsigned SecondReg = nextReg(FirstReg);
5359 unsigned BaseReg = Inst.getOperand(1).getReg();
5360 if (!SecondReg)
5361 return true;
5363 warnIfRegIndexIsAT(FirstReg, IDLoc);
5365 assert(Inst.getOperand(2).isImm() &&
5366 "Offset for load macro is not immediate!");
5368 MCOperand &FirstOffset = Inst.getOperand(2);
5369 signed NextOffset = FirstOffset.getImm() + 4;
5370 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5372 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5373 return true;
5375 // For loads, clobber the base register with the second load instead of the
5376 // first if the BaseReg == FirstReg.
5377 if (FirstReg != BaseReg || !IsLoad) {
5378 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5379 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5380 } else {
5381 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5382 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5385 return false;
5389 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5390 // swc1 $<reg>, offset+4($reg2)'
5391 // or if little endian to 'swc1 $<reg>, offset($reg2);
5392 // swc1 $<reg+1>, offset+4($reg2)'
5393 // for Mips1.
5394 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5395 MCStreamer &Out,
5396 const MCSubtargetInfo *STI) {
5397 if (!isABI_O32())
5398 return true;
5400 warnIfNoMacro(IDLoc);
5402 MipsTargetStreamer &TOut = getTargetStreamer();
5403 unsigned Opcode = Mips::SWC1;
5404 unsigned FirstReg = Inst.getOperand(0).getReg();
5405 unsigned SecondReg = nextReg(FirstReg);
5406 unsigned BaseReg = Inst.getOperand(1).getReg();
5407 if (!SecondReg)
5408 return true;
5410 warnIfRegIndexIsAT(FirstReg, IDLoc);
5412 assert(Inst.getOperand(2).isImm() &&
5413 "Offset for macro is not immediate!");
5415 MCOperand &FirstOffset = Inst.getOperand(2);
5416 signed NextOffset = FirstOffset.getImm() + 4;
5417 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5419 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5420 return true;
5422 if (!IsLittleEndian)
5423 std::swap(FirstReg, SecondReg);
5425 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5426 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5428 return false;
5431 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5432 const MCSubtargetInfo *STI) {
5433 MipsTargetStreamer &TOut = getTargetStreamer();
5435 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5436 assert(Inst.getOperand(0).isReg() &&
5437 Inst.getOperand(1).isReg() &&
5438 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5440 unsigned DstReg = Inst.getOperand(0).getReg();
5441 unsigned SrcReg = Inst.getOperand(1).getReg();
5442 unsigned OpReg = Inst.getOperand(2).getReg();
5444 warnIfNoMacro(IDLoc);
5446 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5447 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5448 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5449 return false;
5452 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5453 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5454 return false;
5457 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5458 const MCSubtargetInfo *STI) {
5459 MipsTargetStreamer &TOut = getTargetStreamer();
5461 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5462 assert(Inst.getOperand(0).isReg() &&
5463 Inst.getOperand(1).isReg() &&
5464 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5466 unsigned DstReg = Inst.getOperand(0).getReg();
5467 unsigned SrcReg = Inst.getOperand(1).getReg();
5468 int64_t Imm = Inst.getOperand(2).getImm();
5470 warnIfNoMacro(IDLoc);
5472 if (Imm == 0) {
5473 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5474 return false;
5477 if (SrcReg == Mips::ZERO) {
5478 Warning(IDLoc, "comparison is always false");
5479 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5480 DstReg, SrcReg, SrcReg, IDLoc, STI);
5481 return false;
5484 unsigned Opc;
5485 if (Imm > -0x8000 && Imm < 0) {
5486 Imm = -Imm;
5487 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5488 } else {
5489 Opc = Mips::XORi;
5492 if (!isUInt<16>(Imm)) {
5493 unsigned ATReg = getATReg(IDLoc);
5494 if (!ATReg)
5495 return true;
5497 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5498 Out, STI))
5499 return true;
5501 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5502 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5503 return false;
5506 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5507 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5508 return false;
5511 bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5512 const MCSubtargetInfo *STI) {
5514 MipsTargetStreamer &TOut = getTargetStreamer();
5516 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5517 assert(Inst.getOperand(0).isReg() &&
5518 Inst.getOperand(1).isReg() &&
5519 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5521 unsigned DstReg = Inst.getOperand(0).getReg();
5522 unsigned SrcReg = Inst.getOperand(1).getReg();
5523 unsigned OpReg = Inst.getOperand(2).getReg();
5525 warnIfNoMacro(IDLoc);
5527 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5528 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5529 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5530 return false;
5533 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5534 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5535 return false;
5538 bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5539 const MCSubtargetInfo *STI) {
5540 MipsTargetStreamer &TOut = getTargetStreamer();
5542 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5543 assert(Inst.getOperand(0).isReg() &&
5544 Inst.getOperand(1).isReg() &&
5545 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5547 unsigned DstReg = Inst.getOperand(0).getReg();
5548 unsigned SrcReg = Inst.getOperand(1).getReg();
5549 int64_t ImmValue = Inst.getOperand(2).getImm();
5551 warnIfNoMacro(IDLoc);
5553 if (ImmValue == 0) {
5554 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5555 return false;
5558 if (SrcReg == Mips::ZERO) {
5559 Warning(IDLoc, "comparison is always true");
5560 if (loadImmediate(1, DstReg, Mips::NoRegister, true, false, IDLoc, Out,
5561 STI))
5562 return true;
5563 return false;
5566 unsigned Opc;
5567 if (ImmValue > -0x8000 && ImmValue < 0) {
5568 ImmValue = -ImmValue;
5569 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5570 } else {
5571 Opc = Mips::XORi;
5574 if (isUInt<16>(ImmValue)) {
5575 TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5576 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5577 return false;
5580 unsigned ATReg = getATReg(IDLoc);
5581 if (!ATReg)
5582 return true;
5584 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
5585 false, IDLoc, Out, STI))
5586 return true;
5588 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5589 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5590 return false;
5593 // Map the DSP accumulator and control register to the corresponding gpr
5594 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5595 // do not map the DSP registers contigously to gpr registers.
5596 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5597 switch (Inst.getOpcode()) {
5598 case Mips::MFTLO:
5599 case Mips::MTTLO:
5600 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5601 case Mips::AC0:
5602 return Mips::ZERO;
5603 case Mips::AC1:
5604 return Mips::A0;
5605 case Mips::AC2:
5606 return Mips::T0;
5607 case Mips::AC3:
5608 return Mips::T4;
5609 default:
5610 llvm_unreachable("Unknown register for 'mttr' alias!");
5612 case Mips::MFTHI:
5613 case Mips::MTTHI:
5614 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5615 case Mips::AC0:
5616 return Mips::AT;
5617 case Mips::AC1:
5618 return Mips::A1;
5619 case Mips::AC2:
5620 return Mips::T1;
5621 case Mips::AC3:
5622 return Mips::T5;
5623 default:
5624 llvm_unreachable("Unknown register for 'mttr' alias!");
5626 case Mips::MFTACX:
5627 case Mips::MTTACX:
5628 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5629 case Mips::AC0:
5630 return Mips::V0;
5631 case Mips::AC1:
5632 return Mips::A2;
5633 case Mips::AC2:
5634 return Mips::T2;
5635 case Mips::AC3:
5636 return Mips::T6;
5637 default:
5638 llvm_unreachable("Unknown register for 'mttr' alias!");
5640 case Mips::MFTDSP:
5641 case Mips::MTTDSP:
5642 return Mips::S0;
5643 default:
5644 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5648 // Map the floating point register operand to the corresponding register
5649 // operand.
5650 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5651 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5652 case Mips::F0: return Mips::ZERO;
5653 case Mips::F1: return Mips::AT;
5654 case Mips::F2: return Mips::V0;
5655 case Mips::F3: return Mips::V1;
5656 case Mips::F4: return Mips::A0;
5657 case Mips::F5: return Mips::A1;
5658 case Mips::F6: return Mips::A2;
5659 case Mips::F7: return Mips::A3;
5660 case Mips::F8: return Mips::T0;
5661 case Mips::F9: return Mips::T1;
5662 case Mips::F10: return Mips::T2;
5663 case Mips::F11: return Mips::T3;
5664 case Mips::F12: return Mips::T4;
5665 case Mips::F13: return Mips::T5;
5666 case Mips::F14: return Mips::T6;
5667 case Mips::F15: return Mips::T7;
5668 case Mips::F16: return Mips::S0;
5669 case Mips::F17: return Mips::S1;
5670 case Mips::F18: return Mips::S2;
5671 case Mips::F19: return Mips::S3;
5672 case Mips::F20: return Mips::S4;
5673 case Mips::F21: return Mips::S5;
5674 case Mips::F22: return Mips::S6;
5675 case Mips::F23: return Mips::S7;
5676 case Mips::F24: return Mips::T8;
5677 case Mips::F25: return Mips::T9;
5678 case Mips::F26: return Mips::K0;
5679 case Mips::F27: return Mips::K1;
5680 case Mips::F28: return Mips::GP;
5681 case Mips::F29: return Mips::SP;
5682 case Mips::F30: return Mips::FP;
5683 case Mips::F31: return Mips::RA;
5684 default: llvm_unreachable("Unknown register for mttc1 alias!");
5688 // Map the coprocessor operand the corresponding gpr register operand.
5689 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5690 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5691 case Mips::COP00: return Mips::ZERO;
5692 case Mips::COP01: return Mips::AT;
5693 case Mips::COP02: return Mips::V0;
5694 case Mips::COP03: return Mips::V1;
5695 case Mips::COP04: return Mips::A0;
5696 case Mips::COP05: return Mips::A1;
5697 case Mips::COP06: return Mips::A2;
5698 case Mips::COP07: return Mips::A3;
5699 case Mips::COP08: return Mips::T0;
5700 case Mips::COP09: return Mips::T1;
5701 case Mips::COP010: return Mips::T2;
5702 case Mips::COP011: return Mips::T3;
5703 case Mips::COP012: return Mips::T4;
5704 case Mips::COP013: return Mips::T5;
5705 case Mips::COP014: return Mips::T6;
5706 case Mips::COP015: return Mips::T7;
5707 case Mips::COP016: return Mips::S0;
5708 case Mips::COP017: return Mips::S1;
5709 case Mips::COP018: return Mips::S2;
5710 case Mips::COP019: return Mips::S3;
5711 case Mips::COP020: return Mips::S4;
5712 case Mips::COP021: return Mips::S5;
5713 case Mips::COP022: return Mips::S6;
5714 case Mips::COP023: return Mips::S7;
5715 case Mips::COP024: return Mips::T8;
5716 case Mips::COP025: return Mips::T9;
5717 case Mips::COP026: return Mips::K0;
5718 case Mips::COP027: return Mips::K1;
5719 case Mips::COP028: return Mips::GP;
5720 case Mips::COP029: return Mips::SP;
5721 case Mips::COP030: return Mips::FP;
5722 case Mips::COP031: return Mips::RA;
5723 default: llvm_unreachable("Unknown register for mttc0 alias!");
5727 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5728 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5729 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5730 const MCSubtargetInfo *STI) {
5731 MipsTargetStreamer &TOut = getTargetStreamer();
5732 unsigned rd = 0;
5733 unsigned u = 1;
5734 unsigned sel = 0;
5735 unsigned h = 0;
5736 bool IsMFTR = false;
5737 switch (Inst.getOpcode()) {
5738 case Mips::MFTC0:
5739 IsMFTR = true;
5740 [[fallthrough]];
5741 case Mips::MTTC0:
5742 u = 0;
5743 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5744 sel = Inst.getOperand(2).getImm();
5745 break;
5746 case Mips::MFTGPR:
5747 IsMFTR = true;
5748 [[fallthrough]];
5749 case Mips::MTTGPR:
5750 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5751 break;
5752 case Mips::MFTLO:
5753 case Mips::MFTHI:
5754 case Mips::MFTACX:
5755 case Mips::MFTDSP:
5756 IsMFTR = true;
5757 [[fallthrough]];
5758 case Mips::MTTLO:
5759 case Mips::MTTHI:
5760 case Mips::MTTACX:
5761 case Mips::MTTDSP:
5762 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5763 sel = 1;
5764 break;
5765 case Mips::MFTHC1:
5766 h = 1;
5767 [[fallthrough]];
5768 case Mips::MFTC1:
5769 IsMFTR = true;
5770 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5771 sel = 2;
5772 break;
5773 case Mips::MTTHC1:
5774 h = 1;
5775 [[fallthrough]];
5776 case Mips::MTTC1:
5777 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5778 sel = 2;
5779 break;
5780 case Mips::CFTC1:
5781 IsMFTR = true;
5782 [[fallthrough]];
5783 case Mips::CTTC1:
5784 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5785 sel = 3;
5786 break;
5788 MCRegister Op0 = IsMFTR ? Inst.getOperand(0).getReg() : MCRegister(rd);
5789 MCRegister Op1 =
5790 IsMFTR ? MCRegister(rd)
5791 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5792 : Inst.getOperand(0).getReg());
5794 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5795 STI);
5796 return false;
5799 bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5800 const MCSubtargetInfo *STI) {
5801 assert(Inst.getNumOperands() == 3 && "expected three operands");
5802 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5803 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5805 warnIfNoMacro(IDLoc);
5807 MipsTargetStreamer &TOut = getTargetStreamer();
5808 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5809 unsigned RtReg = Inst.getOperand(0).getReg();
5810 unsigned BaseReg = Inst.getOperand(1).getReg();
5811 const MCOperand &BaseOp = Inst.getOperand(2);
5813 if (BaseOp.isImm()) {
5814 int64_t ImmValue = BaseOp.getImm();
5815 if (ImmValue == 0) {
5816 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5817 return false;
5821 unsigned ATReg = getATReg(IDLoc);
5822 if (!ATReg)
5823 return true;
5825 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5826 return true;
5828 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5829 return false;
5832 unsigned
5833 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5834 const OperandVector &Operands) {
5835 switch (Inst.getOpcode()) {
5836 default:
5837 return Match_Success;
5838 case Mips::DATI:
5839 case Mips::DAHI:
5840 if (static_cast<MipsOperand &>(*Operands[1])
5841 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5842 return Match_Success;
5843 return Match_RequiresSameSrcAndDst;
5847 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5848 switch (Inst.getOpcode()) {
5849 // As described by the MIPSR6 spec, daui must not use the zero operand for
5850 // its source operand.
5851 case Mips::DAUI:
5852 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5853 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5854 return Match_RequiresNoZeroRegister;
5855 return Match_Success;
5856 // As described by the Mips32r2 spec, the registers Rd and Rs for
5857 // jalr.hb must be different.
5858 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5859 // and registers Rd and Base for microMIPS lwp instruction
5860 case Mips::JALR_HB:
5861 case Mips::JALR_HB64:
5862 case Mips::JALRC_HB_MMR6:
5863 case Mips::JALRC_MMR6:
5864 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5865 return Match_RequiresDifferentSrcAndDst;
5866 return Match_Success;
5867 case Mips::LWP_MM:
5868 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5869 return Match_RequiresDifferentSrcAndDst;
5870 return Match_Success;
5871 case Mips::SYNC:
5872 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5873 return Match_NonZeroOperandForSync;
5874 return Match_Success;
5875 case Mips::MFC0:
5876 case Mips::MTC0:
5877 case Mips::MTC2:
5878 case Mips::MFC2:
5879 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5880 return Match_NonZeroOperandForMTCX;
5881 return Match_Success;
5882 // As described the MIPSR6 spec, the compact branches that compare registers
5883 // must:
5884 // a) Not use the zero register.
5885 // b) Not use the same register twice.
5886 // c) rs < rt for bnec, beqc.
5887 // NB: For this case, the encoding will swap the operands as their
5888 // ordering doesn't matter. GAS performs this transformation too.
5889 // Hence, that constraint does not have to be enforced.
5891 // The compact branches that branch iff the signed addition of two registers
5892 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5893 // operand swapping. They do not have restriction of using the zero register.
5894 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5895 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5896 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5897 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5898 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5899 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5900 case Mips::BLEZC64:
5901 case Mips::BGEZC64:
5902 case Mips::BGTZC64:
5903 case Mips::BLTZC64:
5904 case Mips::BEQZC64:
5905 case Mips::BNEZC64:
5906 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5907 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5908 return Match_RequiresNoZeroRegister;
5909 return Match_Success;
5910 case Mips::BGEC: case Mips::BGEC_MMR6:
5911 case Mips::BLTC: case Mips::BLTC_MMR6:
5912 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5913 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5914 case Mips::BEQC: case Mips::BEQC_MMR6:
5915 case Mips::BNEC: case Mips::BNEC_MMR6:
5916 case Mips::BGEC64:
5917 case Mips::BLTC64:
5918 case Mips::BGEUC64:
5919 case Mips::BLTUC64:
5920 case Mips::BEQC64:
5921 case Mips::BNEC64:
5922 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5923 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5924 return Match_RequiresNoZeroRegister;
5925 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5926 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5927 return Match_RequiresNoZeroRegister;
5928 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5929 return Match_RequiresDifferentOperands;
5930 return Match_Success;
5931 case Mips::DINS: {
5932 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5933 "Operands must be immediates for dins!");
5934 const signed Pos = Inst.getOperand(2).getImm();
5935 const signed Size = Inst.getOperand(3).getImm();
5936 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5937 return Match_RequiresPosSizeRange0_32;
5938 return Match_Success;
5940 case Mips::DINSM:
5941 case Mips::DINSU: {
5942 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5943 "Operands must be immediates for dinsm/dinsu!");
5944 const signed Pos = Inst.getOperand(2).getImm();
5945 const signed Size = Inst.getOperand(3).getImm();
5946 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5947 return Match_RequiresPosSizeRange33_64;
5948 return Match_Success;
5950 case Mips::DEXT: {
5951 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5952 "Operands must be immediates for DEXTM!");
5953 const signed Pos = Inst.getOperand(2).getImm();
5954 const signed Size = Inst.getOperand(3).getImm();
5955 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5956 return Match_RequiresPosSizeUImm6;
5957 return Match_Success;
5959 case Mips::DEXTM:
5960 case Mips::DEXTU: {
5961 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5962 "Operands must be immediates for dextm/dextu!");
5963 const signed Pos = Inst.getOperand(2).getImm();
5964 const signed Size = Inst.getOperand(3).getImm();
5965 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5966 return Match_RequiresPosSizeRange33_64;
5967 return Match_Success;
5969 case Mips::CRC32B: case Mips::CRC32CB:
5970 case Mips::CRC32H: case Mips::CRC32CH:
5971 case Mips::CRC32W: case Mips::CRC32CW:
5972 case Mips::CRC32D: case Mips::CRC32CD:
5973 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5974 return Match_RequiresSameSrcAndDst;
5975 return Match_Success;
5978 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5979 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5980 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5981 return Match_NoFCCRegisterForCurrentISA;
5983 return Match_Success;
5987 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5988 uint64_t ErrorInfo) {
5989 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5990 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5991 if (ErrorLoc == SMLoc())
5992 return Loc;
5993 return ErrorLoc;
5995 return Loc;
5998 bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5999 OperandVector &Operands,
6000 MCStreamer &Out,
6001 uint64_t &ErrorInfo,
6002 bool MatchingInlineAsm) {
6003 MCInst Inst;
6004 unsigned MatchResult =
6005 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
6007 switch (MatchResult) {
6008 case Match_Success:
6009 if (processInstruction(Inst, IDLoc, Out, STI))
6010 return true;
6011 return false;
6012 case Match_MissingFeature:
6013 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
6014 return true;
6015 case Match_InvalidTiedOperand:
6016 Error(IDLoc, "operand must match destination register");
6017 return true;
6018 case Match_InvalidOperand: {
6019 SMLoc ErrorLoc = IDLoc;
6020 if (ErrorInfo != ~0ULL) {
6021 if (ErrorInfo >= Operands.size())
6022 return Error(IDLoc, "too few operands for instruction");
6024 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
6025 if (ErrorLoc == SMLoc())
6026 ErrorLoc = IDLoc;
6029 return Error(ErrorLoc, "invalid operand for instruction");
6031 case Match_NonZeroOperandForSync:
6032 return Error(IDLoc,
6033 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6034 case Match_NonZeroOperandForMTCX:
6035 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
6036 case Match_MnemonicFail:
6037 return Error(IDLoc, "invalid instruction");
6038 case Match_RequiresDifferentSrcAndDst:
6039 return Error(IDLoc, "source and destination must be different");
6040 case Match_RequiresDifferentOperands:
6041 return Error(IDLoc, "registers must be different");
6042 case Match_RequiresNoZeroRegister:
6043 return Error(IDLoc, "invalid operand ($zero) for instruction");
6044 case Match_RequiresSameSrcAndDst:
6045 return Error(IDLoc, "source and destination must match");
6046 case Match_NoFCCRegisterForCurrentISA:
6047 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6048 "non-zero fcc register doesn't exist in current ISA level");
6049 case Match_Immz:
6050 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
6051 case Match_UImm1_0:
6052 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6053 "expected 1-bit unsigned immediate");
6054 case Match_UImm2_0:
6055 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6056 "expected 2-bit unsigned immediate");
6057 case Match_UImm2_1:
6058 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6059 "expected immediate in range 1 .. 4");
6060 case Match_UImm3_0:
6061 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6062 "expected 3-bit unsigned immediate");
6063 case Match_UImm4_0:
6064 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6065 "expected 4-bit unsigned immediate");
6066 case Match_SImm4_0:
6067 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6068 "expected 4-bit signed immediate");
6069 case Match_UImm5_0:
6070 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6071 "expected 5-bit unsigned immediate");
6072 case Match_SImm5_0:
6073 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6074 "expected 5-bit signed immediate");
6075 case Match_UImm5_1:
6076 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6077 "expected immediate in range 1 .. 32");
6078 case Match_UImm5_32:
6079 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6080 "expected immediate in range 32 .. 63");
6081 case Match_UImm5_33:
6082 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6083 "expected immediate in range 33 .. 64");
6084 case Match_UImm5_0_Report_UImm6:
6085 // This is used on UImm5 operands that have a corresponding UImm5_32
6086 // operand to avoid confusing the user.
6087 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6088 "expected 6-bit unsigned immediate");
6089 case Match_UImm5_Lsl2:
6090 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6091 "expected both 7-bit unsigned immediate and multiple of 4");
6092 case Match_UImmRange2_64:
6093 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6094 "expected immediate in range 2 .. 64");
6095 case Match_UImm6_0:
6096 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6097 "expected 6-bit unsigned immediate");
6098 case Match_UImm6_Lsl2:
6099 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6100 "expected both 8-bit unsigned immediate and multiple of 4");
6101 case Match_SImm6_0:
6102 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6103 "expected 6-bit signed immediate");
6104 case Match_UImm7_0:
6105 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6106 "expected 7-bit unsigned immediate");
6107 case Match_UImm7_N1:
6108 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6109 "expected immediate in range -1 .. 126");
6110 case Match_SImm7_Lsl2:
6111 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6112 "expected both 9-bit signed immediate and multiple of 4");
6113 case Match_UImm8_0:
6114 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6115 "expected 8-bit unsigned immediate");
6116 case Match_UImm10_0:
6117 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6118 "expected 10-bit unsigned immediate");
6119 case Match_SImm10_0:
6120 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6121 "expected 10-bit signed immediate");
6122 case Match_SImm11_0:
6123 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6124 "expected 11-bit signed immediate");
6125 case Match_UImm16:
6126 case Match_UImm16_Relaxed:
6127 case Match_UImm16_AltRelaxed:
6128 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6129 "expected 16-bit unsigned immediate");
6130 case Match_SImm16:
6131 case Match_SImm16_Relaxed:
6132 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6133 "expected 16-bit signed immediate");
6134 case Match_SImm19_Lsl2:
6135 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6136 "expected both 19-bit signed immediate and multiple of 4");
6137 case Match_UImm20_0:
6138 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6139 "expected 20-bit unsigned immediate");
6140 case Match_UImm26_0:
6141 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6142 "expected 26-bit unsigned immediate");
6143 case Match_SImm32:
6144 case Match_SImm32_Relaxed:
6145 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6146 "expected 32-bit signed immediate");
6147 case Match_UImm32_Coerced:
6148 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6149 "expected 32-bit immediate");
6150 case Match_MemSImm9:
6151 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6152 "expected memory with 9-bit signed offset");
6153 case Match_MemSImm10:
6154 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6155 "expected memory with 10-bit signed offset");
6156 case Match_MemSImm10Lsl1:
6157 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6158 "expected memory with 11-bit signed offset and multiple of 2");
6159 case Match_MemSImm10Lsl2:
6160 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6161 "expected memory with 12-bit signed offset and multiple of 4");
6162 case Match_MemSImm10Lsl3:
6163 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6164 "expected memory with 13-bit signed offset and multiple of 8");
6165 case Match_MemSImm11:
6166 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6167 "expected memory with 11-bit signed offset");
6168 case Match_MemSImm12:
6169 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6170 "expected memory with 12-bit signed offset");
6171 case Match_MemSImm16:
6172 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6173 "expected memory with 16-bit signed offset");
6174 case Match_MemSImmPtr:
6175 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6176 "expected memory with 32-bit signed offset");
6177 case Match_RequiresPosSizeRange0_32: {
6178 SMLoc ErrorStart = Operands[3]->getStartLoc();
6179 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6180 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6181 SMRange(ErrorStart, ErrorEnd));
6183 case Match_RequiresPosSizeUImm6: {
6184 SMLoc ErrorStart = Operands[3]->getStartLoc();
6185 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6186 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6187 SMRange(ErrorStart, ErrorEnd));
6189 case Match_RequiresPosSizeRange33_64: {
6190 SMLoc ErrorStart = Operands[3]->getStartLoc();
6191 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6192 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6193 SMRange(ErrorStart, ErrorEnd));
6197 llvm_unreachable("Implement any new match types added!");
6200 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
6201 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6202 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
6203 ") without \".set noat\"");
6206 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6207 if (!AssemblerOptions.back()->isMacro())
6208 Warning(Loc, "macro instruction expanded into multiple instructions");
6211 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6212 const OperandVector &Operands) {
6213 assert(
6214 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
6215 "Unexpected instruction!");
6216 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6217 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6218 Inst.addOperand(MCOperand::createReg(NextReg));
6219 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6222 void
6223 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6224 SMRange Range, bool ShowColors) {
6225 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6226 Range, SMFixIt(Range, FixMsg),
6227 ShowColors);
6230 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6231 int CC;
6233 CC = StringSwitch<unsigned>(Name)
6234 .Case("zero", 0)
6235 .Cases("at", "AT", 1)
6236 .Case("a0", 4)
6237 .Case("a1", 5)
6238 .Case("a2", 6)
6239 .Case("a3", 7)
6240 .Case("v0", 2)
6241 .Case("v1", 3)
6242 .Case("s0", 16)
6243 .Case("s1", 17)
6244 .Case("s2", 18)
6245 .Case("s3", 19)
6246 .Case("s4", 20)
6247 .Case("s5", 21)
6248 .Case("s6", 22)
6249 .Case("s7", 23)
6250 .Case("k0", 26)
6251 .Case("k1", 27)
6252 .Case("gp", 28)
6253 .Case("sp", 29)
6254 .Case("fp", 30)
6255 .Case("s8", 30)
6256 .Case("ra", 31)
6257 .Case("t0", 8)
6258 .Case("t1", 9)
6259 .Case("t2", 10)
6260 .Case("t3", 11)
6261 .Case("t4", 12)
6262 .Case("t5", 13)
6263 .Case("t6", 14)
6264 .Case("t7", 15)
6265 .Case("t8", 24)
6266 .Case("t9", 25)
6267 .Default(-1);
6269 if (!(isABI_N32() || isABI_N64()))
6270 return CC;
6272 if (12 <= CC && CC <= 15) {
6273 // Name is one of t4-t7
6274 AsmToken RegTok = getLexer().peekTok();
6275 SMRange RegRange = RegTok.getLocRange();
6277 StringRef FixedName = StringSwitch<StringRef>(Name)
6278 .Case("t4", "t0")
6279 .Case("t5", "t1")
6280 .Case("t6", "t2")
6281 .Case("t7", "t3")
6282 .Default("");
6283 assert(FixedName != "" && "Register name is not one of t4-t7.");
6285 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6286 "Did you mean $" + FixedName + "?", RegRange);
6289 // Although SGI documentation just cuts out t0-t3 for n32/n64,
6290 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
6291 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
6292 if (8 <= CC && CC <= 11)
6293 CC += 4;
6295 if (CC == -1)
6296 CC = StringSwitch<unsigned>(Name)
6297 .Case("a4", 8)
6298 .Case("a5", 9)
6299 .Case("a6", 10)
6300 .Case("a7", 11)
6301 .Case("kt0", 26)
6302 .Case("kt1", 27)
6303 .Default(-1);
6305 return CC;
6308 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6309 int CC;
6311 CC = StringSwitch<unsigned>(Name)
6312 .Case("hwr_cpunum", 0)
6313 .Case("hwr_synci_step", 1)
6314 .Case("hwr_cc", 2)
6315 .Case("hwr_ccres", 3)
6316 .Case("hwr_ulr", 29)
6317 .Default(-1);
6319 return CC;
6322 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6323 if (Name[0] == 'f') {
6324 StringRef NumString = Name.substr(1);
6325 unsigned IntVal;
6326 if (NumString.getAsInteger(10, IntVal))
6327 return -1; // This is not an integer.
6328 if (IntVal > 31) // Maximum index for fpu register.
6329 return -1;
6330 return IntVal;
6332 return -1;
6335 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6336 if (Name.starts_with("fcc")) {
6337 StringRef NumString = Name.substr(3);
6338 unsigned IntVal;
6339 if (NumString.getAsInteger(10, IntVal))
6340 return -1; // This is not an integer.
6341 if (IntVal > 7) // There are only 8 fcc registers.
6342 return -1;
6343 return IntVal;
6345 return -1;
6348 int MipsAsmParser::matchACRegisterName(StringRef Name) {
6349 if (Name.starts_with("ac")) {
6350 StringRef NumString = Name.substr(2);
6351 unsigned IntVal;
6352 if (NumString.getAsInteger(10, IntVal))
6353 return -1; // This is not an integer.
6354 if (IntVal > 3) // There are only 3 acc registers.
6355 return -1;
6356 return IntVal;
6358 return -1;
6361 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6362 unsigned IntVal;
6364 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6365 return -1;
6367 if (IntVal > 31)
6368 return -1;
6370 return IntVal;
6373 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6374 int CC;
6376 CC = StringSwitch<unsigned>(Name)
6377 .Case("msair", 0)
6378 .Case("msacsr", 1)
6379 .Case("msaaccess", 2)
6380 .Case("msasave", 3)
6381 .Case("msamodify", 4)
6382 .Case("msarequest", 5)
6383 .Case("msamap", 6)
6384 .Case("msaunmap", 7)
6385 .Default(-1);
6387 return CC;
6390 bool MipsAsmParser::canUseATReg() {
6391 return AssemblerOptions.back()->getATRegIndex() != 0;
6394 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
6395 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6396 if (ATIndex == 0) {
6397 reportParseError(Loc,
6398 "pseudo-instruction requires $at, which is not available");
6399 return 0;
6401 unsigned AT = getReg(
6402 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6403 return AT;
6406 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
6407 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6410 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6411 MCAsmParser &Parser = getParser();
6412 LLVM_DEBUG(dbgs() << "parseOperand\n");
6414 // Check if the current operand has a custom associated parser, if so, try to
6415 // custom parse the operand, or fallback to the general approach.
6416 // Setting the third parameter to true tells the parser to keep parsing even
6417 // if the operands are not supported with the current feature set. In this
6418 // case, the instruction matcher will output a "instruction requires a CPU
6419 // feature not currently enabled" error. If this were false, the parser would
6420 // stop here and output a less useful "invalid operand" error.
6421 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic, true);
6422 if (Res.isSuccess())
6423 return false;
6424 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6425 // there was a match, but an error occurred, in which case, just return that
6426 // the operand parsing failed.
6427 if (Res.isFailure())
6428 return true;
6430 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6432 switch (getLexer().getKind()) {
6433 case AsmToken::Dollar: {
6434 // Parse the register.
6435 SMLoc S = Parser.getTok().getLoc();
6437 // Almost all registers have been parsed by custom parsers. There is only
6438 // one exception to this. $zero (and it's alias $0) will reach this point
6439 // for div, divu, and similar instructions because it is not an operand
6440 // to the instruction definition but an explicit register. Special case
6441 // this situation for now.
6442 if (!parseAnyRegister(Operands).isNoMatch())
6443 return false;
6445 // Maybe it is a symbol reference.
6446 StringRef Identifier;
6447 if (Parser.parseIdentifier(Identifier))
6448 return true;
6450 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6451 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
6452 // Otherwise create a symbol reference.
6453 const MCExpr *SymRef =
6454 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
6456 Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this));
6457 return false;
6459 default: {
6460 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6462 const MCExpr *Expr;
6463 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6464 if (getParser().parseExpression(Expr))
6465 return true;
6467 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6469 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6470 return false;
6472 } // switch(getLexer().getKind())
6473 return true;
6476 bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
6477 SMLoc &EndLoc) {
6478 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6481 ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6482 SMLoc &EndLoc) {
6483 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6484 ParseStatus Res = parseAnyRegister(Operands);
6485 if (Res.isSuccess()) {
6486 assert(Operands.size() == 1);
6487 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6488 StartLoc = Operand.getStartLoc();
6489 EndLoc = Operand.getEndLoc();
6491 // AFAIK, we only support numeric registers and named GPR's in CFI
6492 // directives.
6493 // Don't worry about eating tokens before failing. Using an unrecognised
6494 // register is a parse error.
6495 if (Operand.isGPRAsmReg()) {
6496 // Resolve to GPR32 or GPR64 appropriately.
6497 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6500 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6503 assert(Operands.size() == 0);
6504 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6507 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
6508 SMLoc S;
6510 if (isParenExpr)
6511 return getParser().parseParenExprOfDepth(0, Res, S);
6512 return getParser().parseExpression(Res);
6515 ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6516 MCAsmParser &Parser = getParser();
6517 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6518 const MCExpr *IdVal = nullptr;
6519 SMLoc S;
6520 bool isParenExpr = false;
6521 ParseStatus Res = ParseStatus::NoMatch;
6522 // First operand is the offset.
6523 S = Parser.getTok().getLoc();
6525 if (getLexer().getKind() == AsmToken::LParen) {
6526 Parser.Lex();
6527 isParenExpr = true;
6530 if (getLexer().getKind() != AsmToken::Dollar) {
6531 if (parseMemOffset(IdVal, isParenExpr))
6532 return ParseStatus::Failure;
6534 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6535 if (Tok.isNot(AsmToken::LParen)) {
6536 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6537 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6538 SMLoc E =
6539 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6540 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6541 return ParseStatus::Success;
6543 if (Tok.is(AsmToken::EndOfStatement)) {
6544 SMLoc E =
6545 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6547 // Zero register assumed, add a memory operand with ZERO as its base.
6548 // "Base" will be managed by k_Memory.
6549 auto Base = MipsOperand::createGPRReg(
6550 0, "0", getContext().getRegisterInfo(), S, E, *this);
6551 Operands.push_back(
6552 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6553 return ParseStatus::Success;
6555 MCBinaryExpr::Opcode Opcode;
6556 // GAS and LLVM treat comparison operators different. GAS will generate -1
6557 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6558 // highly unlikely to be found in a memory offset expression, we don't
6559 // handle them.
6560 switch (Tok.getKind()) {
6561 case AsmToken::Plus:
6562 Opcode = MCBinaryExpr::Add;
6563 Parser.Lex();
6564 break;
6565 case AsmToken::Minus:
6566 Opcode = MCBinaryExpr::Sub;
6567 Parser.Lex();
6568 break;
6569 case AsmToken::Star:
6570 Opcode = MCBinaryExpr::Mul;
6571 Parser.Lex();
6572 break;
6573 case AsmToken::Pipe:
6574 Opcode = MCBinaryExpr::Or;
6575 Parser.Lex();
6576 break;
6577 case AsmToken::Amp:
6578 Opcode = MCBinaryExpr::And;
6579 Parser.Lex();
6580 break;
6581 case AsmToken::LessLess:
6582 Opcode = MCBinaryExpr::Shl;
6583 Parser.Lex();
6584 break;
6585 case AsmToken::GreaterGreater:
6586 Opcode = MCBinaryExpr::LShr;
6587 Parser.Lex();
6588 break;
6589 case AsmToken::Caret:
6590 Opcode = MCBinaryExpr::Xor;
6591 Parser.Lex();
6592 break;
6593 case AsmToken::Slash:
6594 Opcode = MCBinaryExpr::Div;
6595 Parser.Lex();
6596 break;
6597 case AsmToken::Percent:
6598 Opcode = MCBinaryExpr::Mod;
6599 Parser.Lex();
6600 break;
6601 default:
6602 return Error(Parser.getTok().getLoc(), "'(' or expression expected");
6604 const MCExpr * NextExpr;
6605 if (getParser().parseExpression(NextExpr))
6606 return ParseStatus::Failure;
6607 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6610 Parser.Lex(); // Eat the '(' token.
6613 Res = parseAnyRegister(Operands);
6614 if (!Res.isSuccess())
6615 return Res;
6617 if (Parser.getTok().isNot(AsmToken::RParen))
6618 return Error(Parser.getTok().getLoc(), "')' expected");
6620 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6622 Parser.Lex(); // Eat the ')' token.
6624 if (!IdVal)
6625 IdVal = MCConstantExpr::create(0, getContext());
6627 // Replace the register operand with the memory operand.
6628 std::unique_ptr<MipsOperand> op(
6629 static_cast<MipsOperand *>(Operands.back().release()));
6630 // Remove the register from the operands.
6631 // "op" will be managed by k_Memory.
6632 Operands.pop_back();
6633 // Add the memory operand.
6634 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6635 int64_t Imm;
6636 if (IdVal->evaluateAsAbsolute(Imm))
6637 IdVal = MCConstantExpr::create(Imm, getContext());
6638 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6639 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6640 getContext());
6643 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6644 return ParseStatus::Success;
6647 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6648 MCAsmParser &Parser = getParser();
6649 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6650 if (!Sym)
6651 return false;
6653 SMLoc S = Parser.getTok().getLoc();
6654 if (Sym->isVariable()) {
6655 const MCExpr *Expr = Sym->getVariableValue();
6656 if (Expr->getKind() == MCExpr::SymbolRef) {
6657 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6658 StringRef DefSymbol = Ref->getSymbol().getName();
6659 if (DefSymbol.starts_with("$")) {
6660 ParseStatus Res =
6661 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6662 if (Res.isSuccess()) {
6663 Parser.Lex();
6664 return true;
6666 if (Res.isFailure())
6667 llvm_unreachable("Should never fail");
6670 } else if (Sym->isUnset()) {
6671 // If symbol is unset, it might be created in the `parseSetAssignment`
6672 // routine as an alias for a numeric register name.
6673 // Lookup in the aliases list.
6674 auto Entry = RegisterSets.find(Sym->getName());
6675 if (Entry != RegisterSets.end()) {
6676 ParseStatus Res =
6677 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6678 if (Res.isSuccess()) {
6679 Parser.Lex();
6680 return true;
6685 return false;
6688 ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6689 OperandVector &Operands, StringRef Identifier, SMLoc S) {
6690 int Index = matchCPURegisterName(Identifier);
6691 if (Index != -1) {
6692 Operands.push_back(MipsOperand::createGPRReg(
6693 Index, Identifier, getContext().getRegisterInfo(), S,
6694 getLexer().getLoc(), *this));
6695 return ParseStatus::Success;
6698 Index = matchHWRegsRegisterName(Identifier);
6699 if (Index != -1) {
6700 Operands.push_back(MipsOperand::createHWRegsReg(
6701 Index, Identifier, getContext().getRegisterInfo(), S,
6702 getLexer().getLoc(), *this));
6703 return ParseStatus::Success;
6706 Index = matchFPURegisterName(Identifier);
6707 if (Index != -1) {
6708 Operands.push_back(MipsOperand::createFGRReg(
6709 Index, Identifier, getContext().getRegisterInfo(), S,
6710 getLexer().getLoc(), *this));
6711 return ParseStatus::Success;
6714 Index = matchFCCRegisterName(Identifier);
6715 if (Index != -1) {
6716 Operands.push_back(MipsOperand::createFCCReg(
6717 Index, Identifier, getContext().getRegisterInfo(), S,
6718 getLexer().getLoc(), *this));
6719 return ParseStatus::Success;
6722 Index = matchACRegisterName(Identifier);
6723 if (Index != -1) {
6724 Operands.push_back(MipsOperand::createACCReg(
6725 Index, Identifier, getContext().getRegisterInfo(), S,
6726 getLexer().getLoc(), *this));
6727 return ParseStatus::Success;
6730 Index = matchMSA128RegisterName(Identifier);
6731 if (Index != -1) {
6732 Operands.push_back(MipsOperand::createMSA128Reg(
6733 Index, Identifier, getContext().getRegisterInfo(), S,
6734 getLexer().getLoc(), *this));
6735 return ParseStatus::Success;
6738 Index = matchMSA128CtrlRegisterName(Identifier);
6739 if (Index != -1) {
6740 Operands.push_back(MipsOperand::createMSACtrlReg(
6741 Index, Identifier, getContext().getRegisterInfo(), S,
6742 getLexer().getLoc(), *this));
6743 return ParseStatus::Success;
6746 return ParseStatus::NoMatch;
6749 ParseStatus
6750 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6751 const AsmToken &Token, SMLoc S) {
6752 if (Token.is(AsmToken::Identifier)) {
6753 LLVM_DEBUG(dbgs() << ".. identifier\n");
6754 StringRef Identifier = Token.getIdentifier();
6755 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6757 if (Token.is(AsmToken::Integer)) {
6758 LLVM_DEBUG(dbgs() << ".. integer\n");
6759 int64_t RegNum = Token.getIntVal();
6760 if (RegNum < 0 || RegNum > 31) {
6761 // Show the error, but treat invalid register
6762 // number as a normal one to continue parsing
6763 // and catch other possible errors.
6764 Error(getLexer().getLoc(), "invalid register number");
6766 Operands.push_back(MipsOperand::createNumericReg(
6767 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6768 Token.getLoc(), *this));
6769 return ParseStatus::Success;
6772 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6774 return ParseStatus::NoMatch;
6777 ParseStatus
6778 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6779 auto Token = getLexer().peekTok(false);
6780 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6783 ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6784 MCAsmParser &Parser = getParser();
6785 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6787 auto Token = Parser.getTok();
6789 SMLoc S = Token.getLoc();
6791 if (Token.isNot(AsmToken::Dollar)) {
6792 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6793 if (Token.is(AsmToken::Identifier)) {
6794 if (searchSymbolAlias(Operands))
6795 return ParseStatus::Success;
6797 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6798 return ParseStatus::NoMatch;
6800 LLVM_DEBUG(dbgs() << ".. $\n");
6802 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6803 if (Res.isSuccess()) {
6804 Parser.Lex(); // $
6805 Parser.Lex(); // identifier
6807 return Res;
6810 ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6811 MCAsmParser &Parser = getParser();
6812 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6814 SMLoc S = getLexer().getLoc();
6816 // Registers are a valid target and have priority over symbols.
6817 ParseStatus Res = parseAnyRegister(Operands);
6818 if (!Res.isNoMatch())
6819 return Res;
6821 // Integers and expressions are acceptable
6822 const MCExpr *Expr = nullptr;
6823 if (Parser.parseExpression(Expr)) {
6824 // We have no way of knowing if a symbol was consumed so we must ParseFail
6825 return ParseStatus::Failure;
6827 Operands.push_back(
6828 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6829 return ParseStatus::Success;
6832 ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) {
6833 MCAsmParser &Parser = getParser();
6834 const MCExpr *IdVal;
6835 // If the first token is '$' we may have register operand. We have to reject
6836 // cases where it is not a register. Complicating the matter is that
6837 // register names are not reserved across all ABIs.
6838 // Peek past the dollar to see if it's a register name for this ABI.
6839 SMLoc S = Parser.getTok().getLoc();
6840 if (Parser.getTok().is(AsmToken::Dollar)) {
6841 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6842 ? ParseStatus::Failure
6843 : ParseStatus::NoMatch;
6845 if (getParser().parseExpression(IdVal))
6846 return ParseStatus::Failure;
6847 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6848 if (!MCE)
6849 return ParseStatus::NoMatch;
6850 int64_t Val = MCE->getValue();
6851 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6852 Operands.push_back(MipsOperand::CreateImm(
6853 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6854 return ParseStatus::Success;
6857 ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6858 MCAsmParser &Parser = getParser();
6859 SmallVector<unsigned, 10> Regs;
6860 unsigned RegNo;
6861 unsigned PrevReg = Mips::NoRegister;
6862 bool RegRange = false;
6863 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6865 if (Parser.getTok().isNot(AsmToken::Dollar))
6866 return ParseStatus::Failure;
6868 SMLoc S = Parser.getTok().getLoc();
6869 while (parseAnyRegister(TmpOperands).isSuccess()) {
6870 SMLoc E = getLexer().getLoc();
6871 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6872 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6873 if (RegRange) {
6874 // Remove last register operand because registers from register range
6875 // should be inserted first.
6876 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6877 (!isGP64bit() && RegNo == Mips::RA)) {
6878 Regs.push_back(RegNo);
6879 } else {
6880 unsigned TmpReg = PrevReg + 1;
6881 while (TmpReg <= RegNo) {
6882 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6883 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6884 isGP64bit()))
6885 return Error(E, "invalid register operand");
6887 PrevReg = TmpReg;
6888 Regs.push_back(TmpReg++);
6892 RegRange = false;
6893 } else {
6894 if ((PrevReg == Mips::NoRegister) &&
6895 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6896 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6897 return Error(E, "$16 or $31 expected");
6898 if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6899 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6900 !isGP64bit()) ||
6901 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6902 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6903 isGP64bit())))
6904 return Error(E, "invalid register operand");
6905 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6906 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6907 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6908 return Error(E, "consecutive register numbers expected");
6910 Regs.push_back(RegNo);
6913 if (Parser.getTok().is(AsmToken::Minus))
6914 RegRange = true;
6916 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6917 !Parser.getTok().isNot(AsmToken::Comma))
6918 return Error(E, "',' or '-' expected");
6920 Lex(); // Consume comma or minus
6921 if (Parser.getTok().isNot(AsmToken::Dollar))
6922 break;
6924 PrevReg = RegNo;
6927 SMLoc E = Parser.getTok().getLoc();
6928 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6929 parseMemOperand(Operands);
6930 return ParseStatus::Success;
6933 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6934 /// either this.
6935 /// ::= '(', register, ')'
6936 /// handle it before we iterate so we don't get tripped up by the lack of
6937 /// a comma.
6938 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6939 MCAsmParser &Parser = getParser();
6940 if (getLexer().is(AsmToken::LParen)) {
6941 Operands.push_back(
6942 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6943 Parser.Lex();
6944 if (parseOperand(Operands, Name)) {
6945 SMLoc Loc = getLexer().getLoc();
6946 return Error(Loc, "unexpected token in argument list");
6948 if (Parser.getTok().isNot(AsmToken::RParen)) {
6949 SMLoc Loc = getLexer().getLoc();
6950 return Error(Loc, "unexpected token, expected ')'");
6952 Operands.push_back(
6953 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6954 Parser.Lex();
6956 return false;
6959 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6960 /// either one of these.
6961 /// ::= '[', register, ']'
6962 /// ::= '[', integer, ']'
6963 /// handle it before we iterate so we don't get tripped up by the lack of
6964 /// a comma.
6965 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6966 OperandVector &Operands) {
6967 MCAsmParser &Parser = getParser();
6968 if (getLexer().is(AsmToken::LBrac)) {
6969 Operands.push_back(
6970 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6971 Parser.Lex();
6972 if (parseOperand(Operands, Name)) {
6973 SMLoc Loc = getLexer().getLoc();
6974 return Error(Loc, "unexpected token in argument list");
6976 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6977 SMLoc Loc = getLexer().getLoc();
6978 return Error(Loc, "unexpected token, expected ']'");
6980 Operands.push_back(
6981 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6982 Parser.Lex();
6984 return false;
6987 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6988 unsigned VariantID = 0);
6990 bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6991 const MCParsedAsmOperand &Op2) const {
6992 // This target-overriden function exists to maintain current behaviour for
6993 // e.g.
6994 // dahi $3, $3, 0x5678
6995 // as tested in test/MC/Mips/mips64r6/valid.s.
6996 // FIXME: Should this test actually fail with an error? If so, then remove
6997 // this overloaded method.
6998 if (!Op1.isReg() || !Op2.isReg())
6999 return true;
7000 return Op1.getReg() == Op2.getReg();
7003 bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7004 SMLoc NameLoc, OperandVector &Operands) {
7005 MCAsmParser &Parser = getParser();
7006 LLVM_DEBUG(dbgs() << "parseInstruction\n");
7008 // We have reached first instruction, module directive are now forbidden.
7009 getTargetStreamer().forbidModuleDirective();
7011 // Check if we have valid mnemonic
7012 if (!mnemonicIsValid(Name, 0)) {
7013 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7014 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
7015 return Error(NameLoc, "unknown instruction" + Suggestion);
7017 // First operand in MCInst is instruction mnemonic.
7018 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
7020 // Read the remaining operands.
7021 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7022 // Read the first operand.
7023 if (parseOperand(Operands, Name)) {
7024 SMLoc Loc = getLexer().getLoc();
7025 return Error(Loc, "unexpected token in argument list");
7027 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7028 return true;
7029 // AFAIK, parenthesis suffixes are never on the first operand
7031 while (getLexer().is(AsmToken::Comma)) {
7032 Parser.Lex(); // Eat the comma.
7033 // Parse and remember the operand.
7034 if (parseOperand(Operands, Name)) {
7035 SMLoc Loc = getLexer().getLoc();
7036 return Error(Loc, "unexpected token in argument list");
7038 // Parse bracket and parenthesis suffixes before we iterate
7039 if (getLexer().is(AsmToken::LBrac)) {
7040 if (parseBracketSuffix(Name, Operands))
7041 return true;
7042 } else if (getLexer().is(AsmToken::LParen) &&
7043 parseParenSuffix(Name, Operands))
7044 return true;
7047 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7048 SMLoc Loc = getLexer().getLoc();
7049 return Error(Loc, "unexpected token in argument list");
7051 Parser.Lex(); // Consume the EndOfStatement.
7052 return false;
7055 // FIXME: Given that these have the same name, these should both be
7056 // consistent on affecting the Parser.
7057 bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
7058 SMLoc Loc = getLexer().getLoc();
7059 return Error(Loc, ErrorMsg);
7062 bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
7063 return Error(Loc, ErrorMsg);
7066 bool MipsAsmParser::parseSetNoAtDirective() {
7067 MCAsmParser &Parser = getParser();
7068 // Line should look like: ".set noat".
7070 // Set the $at register to $0.
7071 AssemblerOptions.back()->setATRegIndex(0);
7073 Parser.Lex(); // Eat "noat".
7075 // If this is not the end of the statement, report an error.
7076 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7077 reportParseError("unexpected token, expected end of statement");
7078 return false;
7081 getTargetStreamer().emitDirectiveSetNoAt();
7082 Parser.Lex(); // Consume the EndOfStatement.
7083 return false;
7086 bool MipsAsmParser::parseSetAtDirective() {
7087 // Line can be: ".set at", which sets $at to $1
7088 // or ".set at=$reg", which sets $at to $reg.
7089 MCAsmParser &Parser = getParser();
7090 Parser.Lex(); // Eat "at".
7092 if (getLexer().is(AsmToken::EndOfStatement)) {
7093 // No register was specified, so we set $at to $1.
7094 AssemblerOptions.back()->setATRegIndex(1);
7096 getTargetStreamer().emitDirectiveSetAt();
7097 Parser.Lex(); // Consume the EndOfStatement.
7098 return false;
7101 if (getLexer().isNot(AsmToken::Equal)) {
7102 reportParseError("unexpected token, expected equals sign");
7103 return false;
7105 Parser.Lex(); // Eat "=".
7107 if (getLexer().isNot(AsmToken::Dollar)) {
7108 if (getLexer().is(AsmToken::EndOfStatement)) {
7109 reportParseError("no register specified");
7110 return false;
7111 } else {
7112 reportParseError("unexpected token, expected dollar sign '$'");
7113 return false;
7116 Parser.Lex(); // Eat "$".
7118 // Find out what "reg" is.
7119 unsigned AtRegNo;
7120 const AsmToken &Reg = Parser.getTok();
7121 if (Reg.is(AsmToken::Identifier)) {
7122 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7123 } else if (Reg.is(AsmToken::Integer)) {
7124 AtRegNo = Reg.getIntVal();
7125 } else {
7126 reportParseError("unexpected token, expected identifier or integer");
7127 return false;
7130 // Check if $reg is a valid register. If it is, set $at to $reg.
7131 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7132 reportParseError("invalid register");
7133 return false;
7135 Parser.Lex(); // Eat "reg".
7137 // If this is not the end of the statement, report an error.
7138 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7139 reportParseError("unexpected token, expected end of statement");
7140 return false;
7143 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7145 Parser.Lex(); // Consume the EndOfStatement.
7146 return false;
7149 bool MipsAsmParser::parseSetReorderDirective() {
7150 MCAsmParser &Parser = getParser();
7151 Parser.Lex();
7152 // If this is not the end of the statement, report an error.
7153 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7154 reportParseError("unexpected token, expected end of statement");
7155 return false;
7157 AssemblerOptions.back()->setReorder();
7158 getTargetStreamer().emitDirectiveSetReorder();
7159 Parser.Lex(); // Consume the EndOfStatement.
7160 return false;
7163 bool MipsAsmParser::parseSetNoReorderDirective() {
7164 MCAsmParser &Parser = getParser();
7165 Parser.Lex();
7166 // If this is not the end of the statement, report an error.
7167 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7168 reportParseError("unexpected token, expected end of statement");
7169 return false;
7171 AssemblerOptions.back()->setNoReorder();
7172 getTargetStreamer().emitDirectiveSetNoReorder();
7173 Parser.Lex(); // Consume the EndOfStatement.
7174 return false;
7177 bool MipsAsmParser::parseSetMacroDirective() {
7178 MCAsmParser &Parser = getParser();
7179 Parser.Lex();
7180 // If this is not the end of the statement, report an error.
7181 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7182 reportParseError("unexpected token, expected end of statement");
7183 return false;
7185 AssemblerOptions.back()->setMacro();
7186 getTargetStreamer().emitDirectiveSetMacro();
7187 Parser.Lex(); // Consume the EndOfStatement.
7188 return false;
7191 bool MipsAsmParser::parseSetNoMacroDirective() {
7192 MCAsmParser &Parser = getParser();
7193 Parser.Lex();
7194 // If this is not the end of the statement, report an error.
7195 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7196 reportParseError("unexpected token, expected end of statement");
7197 return false;
7199 if (AssemblerOptions.back()->isReorder()) {
7200 reportParseError("`noreorder' must be set before `nomacro'");
7201 return false;
7203 AssemblerOptions.back()->setNoMacro();
7204 getTargetStreamer().emitDirectiveSetNoMacro();
7205 Parser.Lex(); // Consume the EndOfStatement.
7206 return false;
7209 bool MipsAsmParser::parseSetMsaDirective() {
7210 MCAsmParser &Parser = getParser();
7211 Parser.Lex();
7213 // If this is not the end of the statement, report an error.
7214 if (getLexer().isNot(AsmToken::EndOfStatement))
7215 return reportParseError("unexpected token, expected end of statement");
7217 setFeatureBits(Mips::FeatureMSA, "msa");
7218 getTargetStreamer().emitDirectiveSetMsa();
7219 return false;
7222 bool MipsAsmParser::parseSetNoMsaDirective() {
7223 MCAsmParser &Parser = getParser();
7224 Parser.Lex();
7226 // If this is not the end of the statement, report an error.
7227 if (getLexer().isNot(AsmToken::EndOfStatement))
7228 return reportParseError("unexpected token, expected end of statement");
7230 clearFeatureBits(Mips::FeatureMSA, "msa");
7231 getTargetStreamer().emitDirectiveSetNoMsa();
7232 return false;
7235 bool MipsAsmParser::parseSetNoDspDirective() {
7236 MCAsmParser &Parser = getParser();
7237 Parser.Lex(); // Eat "nodsp".
7239 // If this is not the end of the statement, report an error.
7240 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7241 reportParseError("unexpected token, expected end of statement");
7242 return false;
7245 clearFeatureBits(Mips::FeatureDSP, "dsp");
7246 getTargetStreamer().emitDirectiveSetNoDsp();
7247 return false;
7250 bool MipsAsmParser::parseSetNoMips3DDirective() {
7251 MCAsmParser &Parser = getParser();
7252 Parser.Lex(); // Eat "nomips3d".
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");
7257 return false;
7260 clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7261 getTargetStreamer().emitDirectiveSetNoMips3D();
7262 return false;
7265 bool MipsAsmParser::parseSetMips16Directive() {
7266 MCAsmParser &Parser = getParser();
7267 Parser.Lex(); // Eat "mips16".
7269 // If this is not the end of the statement, report an error.
7270 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7271 reportParseError("unexpected token, expected end of statement");
7272 return false;
7275 setFeatureBits(Mips::FeatureMips16, "mips16");
7276 getTargetStreamer().emitDirectiveSetMips16();
7277 Parser.Lex(); // Consume the EndOfStatement.
7278 return false;
7281 bool MipsAsmParser::parseSetNoMips16Directive() {
7282 MCAsmParser &Parser = getParser();
7283 Parser.Lex(); // Eat "nomips16".
7285 // If this is not the end of the statement, report an error.
7286 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7287 reportParseError("unexpected token, expected end of statement");
7288 return false;
7291 clearFeatureBits(Mips::FeatureMips16, "mips16");
7292 getTargetStreamer().emitDirectiveSetNoMips16();
7293 Parser.Lex(); // Consume the EndOfStatement.
7294 return false;
7297 bool MipsAsmParser::parseSetFpDirective() {
7298 MCAsmParser &Parser = getParser();
7299 MipsABIFlagsSection::FpABIKind FpAbiVal;
7300 // Line can be: .set fp=32
7301 // .set fp=xx
7302 // .set fp=64
7303 Parser.Lex(); // Eat fp token
7304 AsmToken Tok = Parser.getTok();
7305 if (Tok.isNot(AsmToken::Equal)) {
7306 reportParseError("unexpected token, expected equals sign '='");
7307 return false;
7309 Parser.Lex(); // Eat '=' token.
7310 Tok = Parser.getTok();
7312 if (!parseFpABIValue(FpAbiVal, ".set"))
7313 return false;
7315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7316 reportParseError("unexpected token, expected end of statement");
7317 return false;
7319 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7320 Parser.Lex(); // Consume the EndOfStatement.
7321 return false;
7324 bool MipsAsmParser::parseSetOddSPRegDirective() {
7325 MCAsmParser &Parser = getParser();
7327 Parser.Lex(); // Eat "oddspreg".
7328 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7329 reportParseError("unexpected token, expected end of statement");
7330 return false;
7333 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7334 getTargetStreamer().emitDirectiveSetOddSPReg();
7335 return false;
7338 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7339 MCAsmParser &Parser = getParser();
7341 Parser.Lex(); // Eat "nooddspreg".
7342 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7343 reportParseError("unexpected token, expected end of statement");
7344 return false;
7347 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7348 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7349 return false;
7352 bool MipsAsmParser::parseSetMtDirective() {
7353 MCAsmParser &Parser = getParser();
7354 Parser.Lex(); // Eat "mt".
7356 // If this is not the end of the statement, report an error.
7357 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7358 reportParseError("unexpected token, expected end of statement");
7359 return false;
7362 setFeatureBits(Mips::FeatureMT, "mt");
7363 getTargetStreamer().emitDirectiveSetMt();
7364 Parser.Lex(); // Consume the EndOfStatement.
7365 return false;
7368 bool MipsAsmParser::parseSetNoMtDirective() {
7369 MCAsmParser &Parser = getParser();
7370 Parser.Lex(); // Eat "nomt".
7372 // If this is not the end of the statement, report an error.
7373 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7374 reportParseError("unexpected token, expected end of statement");
7375 return false;
7378 clearFeatureBits(Mips::FeatureMT, "mt");
7380 getTargetStreamer().emitDirectiveSetNoMt();
7381 Parser.Lex(); // Consume the EndOfStatement.
7382 return false;
7385 bool MipsAsmParser::parseSetNoCRCDirective() {
7386 MCAsmParser &Parser = getParser();
7387 Parser.Lex(); // Eat "nocrc".
7389 // If this is not the end of the statement, report an error.
7390 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7391 reportParseError("unexpected token, expected end of statement");
7392 return false;
7395 clearFeatureBits(Mips::FeatureCRC, "crc");
7397 getTargetStreamer().emitDirectiveSetNoCRC();
7398 Parser.Lex(); // Consume the EndOfStatement.
7399 return false;
7402 bool MipsAsmParser::parseSetNoVirtDirective() {
7403 MCAsmParser &Parser = getParser();
7404 Parser.Lex(); // Eat "novirt".
7406 // If this is not the end of the statement, report an error.
7407 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7408 reportParseError("unexpected token, expected end of statement");
7409 return false;
7412 clearFeatureBits(Mips::FeatureVirt, "virt");
7414 getTargetStreamer().emitDirectiveSetNoVirt();
7415 Parser.Lex(); // Consume the EndOfStatement.
7416 return false;
7419 bool MipsAsmParser::parseSetNoGINVDirective() {
7420 MCAsmParser &Parser = getParser();
7421 Parser.Lex(); // Eat "noginv".
7423 // If this is not the end of the statement, report an error.
7424 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7425 reportParseError("unexpected token, expected end of statement");
7426 return false;
7429 clearFeatureBits(Mips::FeatureGINV, "ginv");
7431 getTargetStreamer().emitDirectiveSetNoGINV();
7432 Parser.Lex(); // Consume the EndOfStatement.
7433 return false;
7436 bool MipsAsmParser::parseSetPopDirective() {
7437 MCAsmParser &Parser = getParser();
7438 SMLoc Loc = getLexer().getLoc();
7440 Parser.Lex();
7441 if (getLexer().isNot(AsmToken::EndOfStatement))
7442 return reportParseError("unexpected token, expected end of statement");
7444 // Always keep an element on the options "stack" to prevent the user
7445 // from changing the initial options. This is how we remember them.
7446 if (AssemblerOptions.size() == 2)
7447 return reportParseError(Loc, ".set pop with no .set push");
7449 MCSubtargetInfo &STI = copySTI();
7450 AssemblerOptions.pop_back();
7451 setAvailableFeatures(
7452 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7453 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7455 getTargetStreamer().emitDirectiveSetPop();
7456 return false;
7459 bool MipsAsmParser::parseSetPushDirective() {
7460 MCAsmParser &Parser = getParser();
7461 Parser.Lex();
7462 if (getLexer().isNot(AsmToken::EndOfStatement))
7463 return reportParseError("unexpected token, expected end of statement");
7465 // Create a copy of the current assembler options environment and push it.
7466 AssemblerOptions.push_back(
7467 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7469 getTargetStreamer().emitDirectiveSetPush();
7470 return false;
7473 bool MipsAsmParser::parseSetSoftFloatDirective() {
7474 MCAsmParser &Parser = getParser();
7475 Parser.Lex();
7476 if (getLexer().isNot(AsmToken::EndOfStatement))
7477 return reportParseError("unexpected token, expected end of statement");
7479 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7480 getTargetStreamer().emitDirectiveSetSoftFloat();
7481 return false;
7484 bool MipsAsmParser::parseSetHardFloatDirective() {
7485 MCAsmParser &Parser = getParser();
7486 Parser.Lex();
7487 if (getLexer().isNot(AsmToken::EndOfStatement))
7488 return reportParseError("unexpected token, expected end of statement");
7490 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7491 getTargetStreamer().emitDirectiveSetHardFloat();
7492 return false;
7495 bool MipsAsmParser::parseSetAssignment() {
7496 StringRef Name;
7497 MCAsmParser &Parser = getParser();
7499 if (Parser.parseIdentifier(Name))
7500 return reportParseError("expected identifier after .set");
7502 if (getLexer().isNot(AsmToken::Comma))
7503 return reportParseError("unexpected token, expected comma");
7504 Lex(); // Eat comma
7506 if (getLexer().is(AsmToken::Dollar) &&
7507 getLexer().peekTok().is(AsmToken::Integer)) {
7508 // Parse assignment of a numeric register:
7509 // .set r1,$1
7510 Parser.Lex(); // Eat $.
7511 RegisterSets[Name] = Parser.getTok();
7512 Parser.Lex(); // Eat identifier.
7513 getContext().getOrCreateSymbol(Name);
7514 return false;
7517 MCSymbol *Sym;
7518 const MCExpr *Value;
7519 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7520 Parser, Sym, Value))
7521 return true;
7522 Sym->setVariableValue(Value);
7524 return false;
7527 bool MipsAsmParser::parseSetMips0Directive() {
7528 MCAsmParser &Parser = getParser();
7529 Parser.Lex();
7530 if (getLexer().isNot(AsmToken::EndOfStatement))
7531 return reportParseError("unexpected token, expected end of statement");
7533 // Reset assembler options to their initial values.
7534 MCSubtargetInfo &STI = copySTI();
7535 setAvailableFeatures(
7536 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7537 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7538 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7540 getTargetStreamer().emitDirectiveSetMips0();
7541 return false;
7544 bool MipsAsmParser::parseSetArchDirective() {
7545 MCAsmParser &Parser = getParser();
7546 Parser.Lex();
7547 if (getLexer().isNot(AsmToken::Equal))
7548 return reportParseError("unexpected token, expected equals sign");
7550 Parser.Lex();
7551 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7552 if (Arch.empty())
7553 return reportParseError("expected arch identifier");
7555 StringRef ArchFeatureName =
7556 StringSwitch<StringRef>(Arch)
7557 .Case("mips1", "mips1")
7558 .Case("mips2", "mips2")
7559 .Case("mips3", "mips3")
7560 .Case("mips4", "mips4")
7561 .Case("mips5", "mips5")
7562 .Case("mips32", "mips32")
7563 .Case("mips32r2", "mips32r2")
7564 .Case("mips32r3", "mips32r3")
7565 .Case("mips32r5", "mips32r5")
7566 .Case("mips32r6", "mips32r6")
7567 .Case("mips64", "mips64")
7568 .Case("mips64r2", "mips64r2")
7569 .Case("mips64r3", "mips64r3")
7570 .Case("mips64r5", "mips64r5")
7571 .Case("mips64r6", "mips64r6")
7572 .Case("octeon", "cnmips")
7573 .Case("octeon+", "cnmipsp")
7574 .Case("r4000", "mips3") // This is an implementation of Mips3.
7575 .Default("");
7577 if (ArchFeatureName.empty())
7578 return reportParseError("unsupported architecture");
7580 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7581 return reportParseError("mips64r6 does not support microMIPS");
7583 selectArch(ArchFeatureName);
7584 getTargetStreamer().emitDirectiveSetArch(Arch);
7585 return false;
7588 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7589 MCAsmParser &Parser = getParser();
7590 Parser.Lex();
7591 if (getLexer().isNot(AsmToken::EndOfStatement))
7592 return reportParseError("unexpected token, expected end of statement");
7594 switch (Feature) {
7595 default:
7596 llvm_unreachable("Unimplemented feature");
7597 case Mips::FeatureMips3D:
7598 setFeatureBits(Mips::FeatureMips3D, "mips3d");
7599 getTargetStreamer().emitDirectiveSetMips3D();
7600 break;
7601 case Mips::FeatureDSP:
7602 setFeatureBits(Mips::FeatureDSP, "dsp");
7603 getTargetStreamer().emitDirectiveSetDsp();
7604 break;
7605 case Mips::FeatureDSPR2:
7606 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7607 getTargetStreamer().emitDirectiveSetDspr2();
7608 break;
7609 case Mips::FeatureMicroMips:
7610 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7611 getTargetStreamer().emitDirectiveSetMicroMips();
7612 break;
7613 case Mips::FeatureMips1:
7614 selectArch("mips1");
7615 getTargetStreamer().emitDirectiveSetMips1();
7616 break;
7617 case Mips::FeatureMips2:
7618 selectArch("mips2");
7619 getTargetStreamer().emitDirectiveSetMips2();
7620 break;
7621 case Mips::FeatureMips3:
7622 selectArch("mips3");
7623 getTargetStreamer().emitDirectiveSetMips3();
7624 break;
7625 case Mips::FeatureMips4:
7626 selectArch("mips4");
7627 getTargetStreamer().emitDirectiveSetMips4();
7628 break;
7629 case Mips::FeatureMips5:
7630 selectArch("mips5");
7631 getTargetStreamer().emitDirectiveSetMips5();
7632 break;
7633 case Mips::FeatureMips32:
7634 selectArch("mips32");
7635 getTargetStreamer().emitDirectiveSetMips32();
7636 break;
7637 case Mips::FeatureMips32r2:
7638 selectArch("mips32r2");
7639 getTargetStreamer().emitDirectiveSetMips32R2();
7640 break;
7641 case Mips::FeatureMips32r3:
7642 selectArch("mips32r3");
7643 getTargetStreamer().emitDirectiveSetMips32R3();
7644 break;
7645 case Mips::FeatureMips32r5:
7646 selectArch("mips32r5");
7647 getTargetStreamer().emitDirectiveSetMips32R5();
7648 break;
7649 case Mips::FeatureMips32r6:
7650 selectArch("mips32r6");
7651 getTargetStreamer().emitDirectiveSetMips32R6();
7652 break;
7653 case Mips::FeatureMips64:
7654 selectArch("mips64");
7655 getTargetStreamer().emitDirectiveSetMips64();
7656 break;
7657 case Mips::FeatureMips64r2:
7658 selectArch("mips64r2");
7659 getTargetStreamer().emitDirectiveSetMips64R2();
7660 break;
7661 case Mips::FeatureMips64r3:
7662 selectArch("mips64r3");
7663 getTargetStreamer().emitDirectiveSetMips64R3();
7664 break;
7665 case Mips::FeatureMips64r5:
7666 selectArch("mips64r5");
7667 getTargetStreamer().emitDirectiveSetMips64R5();
7668 break;
7669 case Mips::FeatureMips64r6:
7670 selectArch("mips64r6");
7671 getTargetStreamer().emitDirectiveSetMips64R6();
7672 break;
7673 case Mips::FeatureCRC:
7674 setFeatureBits(Mips::FeatureCRC, "crc");
7675 getTargetStreamer().emitDirectiveSetCRC();
7676 break;
7677 case Mips::FeatureVirt:
7678 setFeatureBits(Mips::FeatureVirt, "virt");
7679 getTargetStreamer().emitDirectiveSetVirt();
7680 break;
7681 case Mips::FeatureGINV:
7682 setFeatureBits(Mips::FeatureGINV, "ginv");
7683 getTargetStreamer().emitDirectiveSetGINV();
7684 break;
7686 return false;
7689 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7690 MCAsmParser &Parser = getParser();
7691 if (getLexer().isNot(AsmToken::Comma)) {
7692 SMLoc Loc = getLexer().getLoc();
7693 return Error(Loc, ErrorStr);
7696 Parser.Lex(); // Eat the comma.
7697 return true;
7700 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7701 // In this class, it is only used for .cprestore.
7702 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7703 // MipsTargetELFStreamer and MipsAsmParser.
7704 bool MipsAsmParser::isPicAndNotNxxAbi() {
7705 return inPicMode() && !(isABI_N32() || isABI_N64());
7708 bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7709 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7710 ParseStatus Res = parseAnyRegister(Reg);
7711 if (Res.isNoMatch() || Res.isFailure()) {
7712 reportParseError("expected register");
7713 return false;
7716 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7717 if (!RegOpnd.isGPRAsmReg()) {
7718 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7719 return false;
7722 // If this is not the end of the statement, report an error.
7723 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7724 reportParseError("unexpected token, expected end of statement");
7725 return false;
7727 getParser().Lex(); // Consume the EndOfStatement.
7729 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7730 return false;
7733 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7734 if (AssemblerOptions.back()->isReorder())
7735 Warning(Loc, ".cpload should be inside a noreorder section");
7737 if (inMips16Mode()) {
7738 reportParseError(".cpload is not supported in Mips16 mode");
7739 return false;
7742 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7743 ParseStatus Res = parseAnyRegister(Reg);
7744 if (Res.isNoMatch() || Res.isFailure()) {
7745 reportParseError("expected register containing function address");
7746 return false;
7749 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7750 if (!RegOpnd.isGPRAsmReg()) {
7751 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7752 return false;
7755 // If this is not the end of the statement, report an error.
7756 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7757 reportParseError("unexpected token, expected end of statement");
7758 return false;
7761 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7762 return false;
7765 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7766 if (!isABI_N32() && !isABI_N64()) {
7767 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7768 return false;
7771 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7772 ParseStatus Res = parseAnyRegister(Reg);
7773 if (Res.isNoMatch() || Res.isFailure()) {
7774 reportParseError("expected register containing global pointer");
7775 return false;
7778 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7779 if (!RegOpnd.isGPRAsmReg()) {
7780 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7781 return false;
7784 // If this is not the end of the statement, report an error.
7785 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7786 reportParseError("unexpected token, expected end of statement");
7787 return false;
7789 getParser().Lex(); // Consume the EndOfStatement.
7791 unsigned NewReg = RegOpnd.getGPR32Reg();
7792 if (IsPicEnabled)
7793 GPReg = NewReg;
7795 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7796 return false;
7799 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7800 MCAsmParser &Parser = getParser();
7802 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7803 // is used in non-PIC mode.
7805 if (inMips16Mode()) {
7806 reportParseError(".cprestore is not supported in Mips16 mode");
7807 return false;
7810 // Get the stack offset value.
7811 const MCExpr *StackOffset;
7812 int64_t StackOffsetVal;
7813 if (Parser.parseExpression(StackOffset)) {
7814 reportParseError("expected stack offset value");
7815 return false;
7818 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7819 reportParseError("stack offset is not an absolute expression");
7820 return false;
7823 if (StackOffsetVal < 0) {
7824 Warning(Loc, ".cprestore with negative stack offset has no effect");
7825 IsCpRestoreSet = false;
7826 } else {
7827 IsCpRestoreSet = true;
7828 CpRestoreOffset = StackOffsetVal;
7831 // If this is not the end of the statement, report an error.
7832 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7833 reportParseError("unexpected token, expected end of statement");
7834 return false;
7837 if (!getTargetStreamer().emitDirectiveCpRestore(
7838 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7839 return true;
7840 Parser.Lex(); // Consume the EndOfStatement.
7841 return false;
7844 bool MipsAsmParser::parseDirectiveCPSetup() {
7845 MCAsmParser &Parser = getParser();
7846 unsigned FuncReg;
7847 unsigned Save;
7848 bool SaveIsReg = true;
7850 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7851 ParseStatus Res = parseAnyRegister(TmpReg);
7852 if (Res.isNoMatch()) {
7853 reportParseError("expected register containing function address");
7854 return false;
7857 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7858 if (!FuncRegOpnd.isGPRAsmReg()) {
7859 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7860 return false;
7863 FuncReg = FuncRegOpnd.getGPR32Reg();
7864 TmpReg.clear();
7866 if (!eatComma("unexpected token, expected comma"))
7867 return true;
7869 Res = parseAnyRegister(TmpReg);
7870 if (Res.isNoMatch()) {
7871 const MCExpr *OffsetExpr;
7872 int64_t OffsetVal;
7873 SMLoc ExprLoc = getLexer().getLoc();
7875 if (Parser.parseExpression(OffsetExpr) ||
7876 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7877 reportParseError(ExprLoc, "expected save register or stack offset");
7878 return false;
7881 Save = OffsetVal;
7882 SaveIsReg = false;
7883 } else {
7884 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7885 if (!SaveOpnd.isGPRAsmReg()) {
7886 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7887 return false;
7889 Save = SaveOpnd.getGPR32Reg();
7892 if (!eatComma("unexpected token, expected comma"))
7893 return true;
7895 const MCExpr *Expr;
7896 if (Parser.parseExpression(Expr)) {
7897 reportParseError("expected expression");
7898 return false;
7901 if (Expr->getKind() != MCExpr::SymbolRef) {
7902 reportParseError("expected symbol");
7903 return false;
7905 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7907 CpSaveLocation = Save;
7908 CpSaveLocationIsRegister = SaveIsReg;
7910 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7911 SaveIsReg);
7912 return false;
7915 bool MipsAsmParser::parseDirectiveCPReturn() {
7916 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7917 CpSaveLocationIsRegister);
7918 return false;
7921 bool MipsAsmParser::parseDirectiveNaN() {
7922 MCAsmParser &Parser = getParser();
7923 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7924 const AsmToken &Tok = Parser.getTok();
7926 if (Tok.getString() == "2008") {
7927 Parser.Lex();
7928 getTargetStreamer().emitDirectiveNaN2008();
7929 return false;
7930 } else if (Tok.getString() == "legacy") {
7931 Parser.Lex();
7932 getTargetStreamer().emitDirectiveNaNLegacy();
7933 return false;
7936 // If we don't recognize the option passed to the .nan
7937 // directive (e.g. no option or unknown option), emit an error.
7938 reportParseError("invalid option in .nan directive");
7939 return false;
7942 bool MipsAsmParser::parseDirectiveSet() {
7943 const AsmToken &Tok = getParser().getTok();
7944 StringRef IdVal = Tok.getString();
7945 SMLoc Loc = Tok.getLoc();
7947 if (IdVal == "noat")
7948 return parseSetNoAtDirective();
7949 if (IdVal == "at")
7950 return parseSetAtDirective();
7951 if (IdVal == "arch")
7952 return parseSetArchDirective();
7953 if (IdVal == "bopt") {
7954 Warning(Loc, "'bopt' feature is unsupported");
7955 getParser().Lex();
7956 return false;
7958 if (IdVal == "nobopt") {
7959 // We're already running in nobopt mode, so nothing to do.
7960 getParser().Lex();
7961 return false;
7963 if (IdVal == "fp")
7964 return parseSetFpDirective();
7965 if (IdVal == "oddspreg")
7966 return parseSetOddSPRegDirective();
7967 if (IdVal == "nooddspreg")
7968 return parseSetNoOddSPRegDirective();
7969 if (IdVal == "pop")
7970 return parseSetPopDirective();
7971 if (IdVal == "push")
7972 return parseSetPushDirective();
7973 if (IdVal == "reorder")
7974 return parseSetReorderDirective();
7975 if (IdVal == "noreorder")
7976 return parseSetNoReorderDirective();
7977 if (IdVal == "macro")
7978 return parseSetMacroDirective();
7979 if (IdVal == "nomacro")
7980 return parseSetNoMacroDirective();
7981 if (IdVal == "mips16")
7982 return parseSetMips16Directive();
7983 if (IdVal == "nomips16")
7984 return parseSetNoMips16Directive();
7985 if (IdVal == "nomicromips") {
7986 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7987 getTargetStreamer().emitDirectiveSetNoMicroMips();
7988 getParser().eatToEndOfStatement();
7989 return false;
7991 if (IdVal == "micromips") {
7992 if (hasMips64r6()) {
7993 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7994 return false;
7996 return parseSetFeature(Mips::FeatureMicroMips);
7998 if (IdVal == "mips0")
7999 return parseSetMips0Directive();
8000 if (IdVal == "mips1")
8001 return parseSetFeature(Mips::FeatureMips1);
8002 if (IdVal == "mips2")
8003 return parseSetFeature(Mips::FeatureMips2);
8004 if (IdVal == "mips3")
8005 return parseSetFeature(Mips::FeatureMips3);
8006 if (IdVal == "mips4")
8007 return parseSetFeature(Mips::FeatureMips4);
8008 if (IdVal == "mips5")
8009 return parseSetFeature(Mips::FeatureMips5);
8010 if (IdVal == "mips32")
8011 return parseSetFeature(Mips::FeatureMips32);
8012 if (IdVal == "mips32r2")
8013 return parseSetFeature(Mips::FeatureMips32r2);
8014 if (IdVal == "mips32r3")
8015 return parseSetFeature(Mips::FeatureMips32r3);
8016 if (IdVal == "mips32r5")
8017 return parseSetFeature(Mips::FeatureMips32r5);
8018 if (IdVal == "mips32r6")
8019 return parseSetFeature(Mips::FeatureMips32r6);
8020 if (IdVal == "mips64")
8021 return parseSetFeature(Mips::FeatureMips64);
8022 if (IdVal == "mips64r2")
8023 return parseSetFeature(Mips::FeatureMips64r2);
8024 if (IdVal == "mips64r3")
8025 return parseSetFeature(Mips::FeatureMips64r3);
8026 if (IdVal == "mips64r5")
8027 return parseSetFeature(Mips::FeatureMips64r5);
8028 if (IdVal == "mips64r6") {
8029 if (inMicroMipsMode()) {
8030 Error(Loc, "MIPS64R6 is not supported with microMIPS");
8031 return false;
8033 return parseSetFeature(Mips::FeatureMips64r6);
8035 if (IdVal == "dsp")
8036 return parseSetFeature(Mips::FeatureDSP);
8037 if (IdVal == "dspr2")
8038 return parseSetFeature(Mips::FeatureDSPR2);
8039 if (IdVal == "nodsp")
8040 return parseSetNoDspDirective();
8041 if (IdVal == "mips3d")
8042 return parseSetFeature(Mips::FeatureMips3D);
8043 if (IdVal == "nomips3d")
8044 return parseSetNoMips3DDirective();
8045 if (IdVal == "msa")
8046 return parseSetMsaDirective();
8047 if (IdVal == "nomsa")
8048 return parseSetNoMsaDirective();
8049 if (IdVal == "mt")
8050 return parseSetMtDirective();
8051 if (IdVal == "nomt")
8052 return parseSetNoMtDirective();
8053 if (IdVal == "softfloat")
8054 return parseSetSoftFloatDirective();
8055 if (IdVal == "hardfloat")
8056 return parseSetHardFloatDirective();
8057 if (IdVal == "crc")
8058 return parseSetFeature(Mips::FeatureCRC);
8059 if (IdVal == "nocrc")
8060 return parseSetNoCRCDirective();
8061 if (IdVal == "virt")
8062 return parseSetFeature(Mips::FeatureVirt);
8063 if (IdVal == "novirt")
8064 return parseSetNoVirtDirective();
8065 if (IdVal == "ginv")
8066 return parseSetFeature(Mips::FeatureGINV);
8067 if (IdVal == "noginv")
8068 return parseSetNoGINVDirective();
8070 // It is just an identifier, look for an assignment.
8071 return parseSetAssignment();
8074 /// parseDirectiveGpWord
8075 /// ::= .gpword local_sym
8076 bool MipsAsmParser::parseDirectiveGpWord() {
8077 MCAsmParser &Parser = getParser();
8078 const MCExpr *Value;
8079 // EmitGPRel32Value requires an expression, so we are using base class
8080 // method to evaluate the expression.
8081 if (getParser().parseExpression(Value))
8082 return true;
8083 getParser().getStreamer().emitGPRel32Value(Value);
8085 if (getLexer().isNot(AsmToken::EndOfStatement))
8086 return Error(getLexer().getLoc(),
8087 "unexpected token, expected end of statement");
8088 Parser.Lex(); // Eat EndOfStatement token.
8089 return false;
8092 /// parseDirectiveGpDWord
8093 /// ::= .gpdword local_sym
8094 bool MipsAsmParser::parseDirectiveGpDWord() {
8095 MCAsmParser &Parser = getParser();
8096 const MCExpr *Value;
8097 // EmitGPRel64Value requires an expression, so we are using base class
8098 // method to evaluate the expression.
8099 if (getParser().parseExpression(Value))
8100 return true;
8101 getParser().getStreamer().emitGPRel64Value(Value);
8103 if (getLexer().isNot(AsmToken::EndOfStatement))
8104 return Error(getLexer().getLoc(),
8105 "unexpected token, expected end of statement");
8106 Parser.Lex(); // Eat EndOfStatement token.
8107 return false;
8110 /// parseDirectiveDtpRelWord
8111 /// ::= .dtprelword tls_sym
8112 bool MipsAsmParser::parseDirectiveDtpRelWord() {
8113 MCAsmParser &Parser = getParser();
8114 const MCExpr *Value;
8115 // EmitDTPRel32Value requires an expression, so we are using base class
8116 // method to evaluate the expression.
8117 if (getParser().parseExpression(Value))
8118 return true;
8119 getParser().getStreamer().emitDTPRel32Value(Value);
8121 if (getLexer().isNot(AsmToken::EndOfStatement))
8122 return Error(getLexer().getLoc(),
8123 "unexpected token, expected end of statement");
8124 Parser.Lex(); // Eat EndOfStatement token.
8125 return false;
8128 /// parseDirectiveDtpRelDWord
8129 /// ::= .dtpreldword tls_sym
8130 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8131 MCAsmParser &Parser = getParser();
8132 const MCExpr *Value;
8133 // EmitDTPRel64Value requires an expression, so we are using base class
8134 // method to evaluate the expression.
8135 if (getParser().parseExpression(Value))
8136 return true;
8137 getParser().getStreamer().emitDTPRel64Value(Value);
8139 if (getLexer().isNot(AsmToken::EndOfStatement))
8140 return Error(getLexer().getLoc(),
8141 "unexpected token, expected end of statement");
8142 Parser.Lex(); // Eat EndOfStatement token.
8143 return false;
8146 /// parseDirectiveTpRelWord
8147 /// ::= .tprelword tls_sym
8148 bool MipsAsmParser::parseDirectiveTpRelWord() {
8149 MCAsmParser &Parser = getParser();
8150 const MCExpr *Value;
8151 // EmitTPRel32Value requires an expression, so we are using base class
8152 // method to evaluate the expression.
8153 if (getParser().parseExpression(Value))
8154 return true;
8155 getParser().getStreamer().emitTPRel32Value(Value);
8157 if (getLexer().isNot(AsmToken::EndOfStatement))
8158 return Error(getLexer().getLoc(),
8159 "unexpected token, expected end of statement");
8160 Parser.Lex(); // Eat EndOfStatement token.
8161 return false;
8164 /// parseDirectiveTpRelDWord
8165 /// ::= .tpreldword tls_sym
8166 bool MipsAsmParser::parseDirectiveTpRelDWord() {
8167 MCAsmParser &Parser = getParser();
8168 const MCExpr *Value;
8169 // EmitTPRel64Value requires an expression, so we are using base class
8170 // method to evaluate the expression.
8171 if (getParser().parseExpression(Value))
8172 return true;
8173 getParser().getStreamer().emitTPRel64Value(Value);
8175 if (getLexer().isNot(AsmToken::EndOfStatement))
8176 return Error(getLexer().getLoc(),
8177 "unexpected token, expected end of statement");
8178 Parser.Lex(); // Eat EndOfStatement token.
8179 return false;
8182 bool MipsAsmParser::parseDirectiveOption() {
8183 MCAsmParser &Parser = getParser();
8184 // Get the option token.
8185 AsmToken Tok = Parser.getTok();
8186 // At the moment only identifiers are supported.
8187 if (Tok.isNot(AsmToken::Identifier)) {
8188 return Error(Parser.getTok().getLoc(),
8189 "unexpected token, expected identifier");
8192 StringRef Option = Tok.getIdentifier();
8194 if (Option == "pic0") {
8195 // MipsAsmParser needs to know if the current PIC mode changes.
8196 IsPicEnabled = false;
8198 getTargetStreamer().emitDirectiveOptionPic0();
8199 Parser.Lex();
8200 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8201 return Error(Parser.getTok().getLoc(),
8202 "unexpected token, expected end of statement");
8204 return false;
8207 if (Option == "pic2") {
8208 // MipsAsmParser needs to know if the current PIC mode changes.
8209 IsPicEnabled = true;
8211 getTargetStreamer().emitDirectiveOptionPic2();
8212 Parser.Lex();
8213 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8214 return Error(Parser.getTok().getLoc(),
8215 "unexpected token, expected end of statement");
8217 return false;
8220 // Unknown option.
8221 Warning(Parser.getTok().getLoc(),
8222 "unknown option, expected 'pic0' or 'pic2'");
8223 Parser.eatToEndOfStatement();
8224 return false;
8227 /// parseInsnDirective
8228 /// ::= .insn
8229 bool MipsAsmParser::parseInsnDirective() {
8230 // If this is not the end of the statement, report an error.
8231 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8232 reportParseError("unexpected token, expected end of statement");
8233 return false;
8236 // The actual label marking happens in
8237 // MipsELFStreamer::createPendingLabelRelocs().
8238 getTargetStreamer().emitDirectiveInsn();
8240 getParser().Lex(); // Eat EndOfStatement token.
8241 return false;
8244 /// parseRSectionDirective
8245 /// ::= .rdata
8246 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8247 // If this is not the end of the statement, report an error.
8248 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8249 reportParseError("unexpected token, expected end of statement");
8250 return false;
8253 MCSection *ELFSection = getContext().getELFSection(
8254 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
8255 getParser().getStreamer().switchSection(ELFSection);
8257 getParser().Lex(); // Eat EndOfStatement token.
8258 return false;
8261 /// parseSSectionDirective
8262 /// ::= .sbss
8263 /// ::= .sdata
8264 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8265 // If this is not the end of the statement, report an error.
8266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8267 reportParseError("unexpected token, expected end of statement");
8268 return false;
8271 MCSection *ELFSection = getContext().getELFSection(
8272 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
8273 getParser().getStreamer().switchSection(ELFSection);
8275 getParser().Lex(); // Eat EndOfStatement token.
8276 return false;
8279 /// parseDirectiveModule
8280 /// ::= .module oddspreg
8281 /// ::= .module nooddspreg
8282 /// ::= .module fp=value
8283 /// ::= .module softfloat
8284 /// ::= .module hardfloat
8285 /// ::= .module mt
8286 /// ::= .module crc
8287 /// ::= .module nocrc
8288 /// ::= .module virt
8289 /// ::= .module novirt
8290 /// ::= .module ginv
8291 /// ::= .module noginv
8292 bool MipsAsmParser::parseDirectiveModule() {
8293 MCAsmParser &Parser = getParser();
8294 MCAsmLexer &Lexer = getLexer();
8295 SMLoc L = Lexer.getLoc();
8297 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8298 // TODO : get a better message.
8299 reportParseError(".module directive must appear before any code");
8300 return false;
8303 StringRef Option;
8304 if (Parser.parseIdentifier(Option)) {
8305 reportParseError("expected .module option identifier");
8306 return false;
8309 if (Option == "oddspreg") {
8310 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8312 // Synchronize the abiflags information with the FeatureBits information we
8313 // changed above.
8314 getTargetStreamer().updateABIInfo(*this);
8316 // If printing assembly, use the recently updated abiflags information.
8317 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8318 // emitted at the end).
8319 getTargetStreamer().emitDirectiveModuleOddSPReg();
8321 // If this is not the end of the statement, report an error.
8322 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8323 reportParseError("unexpected token, expected end of statement");
8324 return false;
8327 return false; // parseDirectiveModule has finished successfully.
8328 } else if (Option == "nooddspreg") {
8329 if (!isABI_O32()) {
8330 return Error(L, "'.module nooddspreg' requires the O32 ABI");
8333 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8335 // Synchronize the abiflags information with the FeatureBits information we
8336 // changed above.
8337 getTargetStreamer().updateABIInfo(*this);
8339 // If printing assembly, use the recently updated abiflags information.
8340 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8341 // emitted at the end).
8342 getTargetStreamer().emitDirectiveModuleOddSPReg();
8344 // If this is not the end of the statement, report an error.
8345 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8346 reportParseError("unexpected token, expected end of statement");
8347 return false;
8350 return false; // parseDirectiveModule has finished successfully.
8351 } else if (Option == "fp") {
8352 return parseDirectiveModuleFP();
8353 } else if (Option == "softfloat") {
8354 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8356 // Synchronize the ABI Flags information with the FeatureBits information we
8357 // updated above.
8358 getTargetStreamer().updateABIInfo(*this);
8360 // If printing assembly, use the recently updated ABI Flags information.
8361 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8362 // emitted later).
8363 getTargetStreamer().emitDirectiveModuleSoftFloat();
8365 // If this is not the end of the statement, report an error.
8366 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8367 reportParseError("unexpected token, expected end of statement");
8368 return false;
8371 return false; // parseDirectiveModule has finished successfully.
8372 } else if (Option == "hardfloat") {
8373 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8375 // Synchronize the ABI Flags information with the FeatureBits information we
8376 // updated above.
8377 getTargetStreamer().updateABIInfo(*this);
8379 // If printing assembly, use the recently updated ABI Flags information.
8380 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8381 // emitted later).
8382 getTargetStreamer().emitDirectiveModuleHardFloat();
8384 // If this is not the end of the statement, report an error.
8385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8386 reportParseError("unexpected token, expected end of statement");
8387 return false;
8390 return false; // parseDirectiveModule has finished successfully.
8391 } else if (Option == "mt") {
8392 setModuleFeatureBits(Mips::FeatureMT, "mt");
8394 // Synchronize the ABI Flags information with the FeatureBits information we
8395 // updated above.
8396 getTargetStreamer().updateABIInfo(*this);
8398 // If printing assembly, use the recently updated ABI Flags information.
8399 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8400 // emitted later).
8401 getTargetStreamer().emitDirectiveModuleMT();
8403 // If this is not the end of the statement, report an error.
8404 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8405 reportParseError("unexpected token, expected end of statement");
8406 return false;
8409 return false; // parseDirectiveModule has finished successfully.
8410 } else if (Option == "crc") {
8411 setModuleFeatureBits(Mips::FeatureCRC, "crc");
8413 // Synchronize the ABI Flags information with the FeatureBits information we
8414 // updated above.
8415 getTargetStreamer().updateABIInfo(*this);
8417 // If printing assembly, use the recently updated ABI Flags information.
8418 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8419 // emitted later).
8420 getTargetStreamer().emitDirectiveModuleCRC();
8422 // If this is not the end of the statement, report an error.
8423 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8424 reportParseError("unexpected token, expected end of statement");
8425 return false;
8428 return false; // parseDirectiveModule has finished successfully.
8429 } else if (Option == "nocrc") {
8430 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8432 // Synchronize the ABI Flags information with the FeatureBits information we
8433 // updated above.
8434 getTargetStreamer().updateABIInfo(*this);
8436 // If printing assembly, use the recently updated ABI Flags information.
8437 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8438 // emitted later).
8439 getTargetStreamer().emitDirectiveModuleNoCRC();
8441 // If this is not the end of the statement, report an error.
8442 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8443 reportParseError("unexpected token, expected end of statement");
8444 return false;
8447 return false; // parseDirectiveModule has finished successfully.
8448 } else if (Option == "virt") {
8449 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8451 // Synchronize the ABI Flags information with the FeatureBits information we
8452 // updated above.
8453 getTargetStreamer().updateABIInfo(*this);
8455 // If printing assembly, use the recently updated ABI Flags information.
8456 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8457 // emitted later).
8458 getTargetStreamer().emitDirectiveModuleVirt();
8460 // If this is not the end of the statement, report an error.
8461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8462 reportParseError("unexpected token, expected end of statement");
8463 return false;
8466 return false; // parseDirectiveModule has finished successfully.
8467 } else if (Option == "novirt") {
8468 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8470 // Synchronize the ABI Flags information with the FeatureBits information we
8471 // updated above.
8472 getTargetStreamer().updateABIInfo(*this);
8474 // If printing assembly, use the recently updated ABI Flags information.
8475 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8476 // emitted later).
8477 getTargetStreamer().emitDirectiveModuleNoVirt();
8479 // If this is not the end of the statement, report an error.
8480 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8481 reportParseError("unexpected token, expected end of statement");
8482 return false;
8485 return false; // parseDirectiveModule has finished successfully.
8486 } else if (Option == "ginv") {
8487 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8489 // Synchronize the ABI Flags information with the FeatureBits information we
8490 // updated above.
8491 getTargetStreamer().updateABIInfo(*this);
8493 // If printing assembly, use the recently updated ABI Flags information.
8494 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8495 // emitted later).
8496 getTargetStreamer().emitDirectiveModuleGINV();
8498 // If this is not the end of the statement, report an error.
8499 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8500 reportParseError("unexpected token, expected end of statement");
8501 return false;
8504 return false; // parseDirectiveModule has finished successfully.
8505 } else if (Option == "noginv") {
8506 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8508 // Synchronize the ABI Flags information with the FeatureBits information we
8509 // updated above.
8510 getTargetStreamer().updateABIInfo(*this);
8512 // If printing assembly, use the recently updated ABI Flags information.
8513 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8514 // emitted later).
8515 getTargetStreamer().emitDirectiveModuleNoGINV();
8517 // If this is not the end of the statement, report an error.
8518 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8519 reportParseError("unexpected token, expected end of statement");
8520 return false;
8523 return false; // parseDirectiveModule has finished successfully.
8524 } else {
8525 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8529 /// parseDirectiveModuleFP
8530 /// ::= =32
8531 /// ::= =xx
8532 /// ::= =64
8533 bool MipsAsmParser::parseDirectiveModuleFP() {
8534 MCAsmParser &Parser = getParser();
8535 MCAsmLexer &Lexer = getLexer();
8537 if (Lexer.isNot(AsmToken::Equal)) {
8538 reportParseError("unexpected token, expected equals sign '='");
8539 return false;
8541 Parser.Lex(); // Eat '=' token.
8543 MipsABIFlagsSection::FpABIKind FpABI;
8544 if (!parseFpABIValue(FpABI, ".module"))
8545 return false;
8547 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8548 reportParseError("unexpected token, expected end of statement");
8549 return false;
8552 // Synchronize the abiflags information with the FeatureBits information we
8553 // changed above.
8554 getTargetStreamer().updateABIInfo(*this);
8556 // If printing assembly, use the recently updated abiflags information.
8557 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8558 // emitted at the end).
8559 getTargetStreamer().emitDirectiveModuleFP();
8561 Parser.Lex(); // Consume the EndOfStatement.
8562 return false;
8565 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8566 StringRef Directive) {
8567 MCAsmParser &Parser = getParser();
8568 MCAsmLexer &Lexer = getLexer();
8569 bool ModuleLevelOptions = Directive == ".module";
8571 if (Lexer.is(AsmToken::Identifier)) {
8572 StringRef Value = Parser.getTok().getString();
8573 Parser.Lex();
8575 if (Value != "xx") {
8576 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8577 return false;
8580 if (!isABI_O32()) {
8581 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8582 return false;
8585 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8586 if (ModuleLevelOptions) {
8587 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8588 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8589 } else {
8590 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8591 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8593 return true;
8596 if (Lexer.is(AsmToken::Integer)) {
8597 unsigned Value = Parser.getTok().getIntVal();
8598 Parser.Lex();
8600 if (Value != 32 && Value != 64) {
8601 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8602 return false;
8605 if (Value == 32) {
8606 if (!isABI_O32()) {
8607 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8608 return false;
8611 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8612 if (ModuleLevelOptions) {
8613 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8614 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8615 } else {
8616 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8617 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8619 } else {
8620 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8621 if (ModuleLevelOptions) {
8622 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8623 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8624 } else {
8625 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8626 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8630 return true;
8633 return false;
8636 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8637 // This returns false if this function recognizes the directive
8638 // regardless of whether it is successfully handles or reports an
8639 // error. Otherwise it returns true to give the generic parser a
8640 // chance at recognizing it.
8642 MCAsmParser &Parser = getParser();
8643 StringRef IDVal = DirectiveID.getString();
8645 if (IDVal == ".cpadd") {
8646 parseDirectiveCpAdd(DirectiveID.getLoc());
8647 return false;
8649 if (IDVal == ".cpload") {
8650 parseDirectiveCpLoad(DirectiveID.getLoc());
8651 return false;
8653 if (IDVal == ".cprestore") {
8654 parseDirectiveCpRestore(DirectiveID.getLoc());
8655 return false;
8657 if (IDVal == ".cplocal") {
8658 parseDirectiveCpLocal(DirectiveID.getLoc());
8659 return false;
8661 if (IDVal == ".ent") {
8662 StringRef SymbolName;
8664 if (Parser.parseIdentifier(SymbolName)) {
8665 reportParseError("expected identifier after .ent");
8666 return false;
8669 // There's an undocumented extension that allows an integer to
8670 // follow the name of the procedure which AFAICS is ignored by GAS.
8671 // Example: .ent foo,2
8672 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8673 if (getLexer().isNot(AsmToken::Comma)) {
8674 // Even though we accept this undocumented extension for compatibility
8675 // reasons, the additional integer argument does not actually change
8676 // the behaviour of the '.ent' directive, so we would like to discourage
8677 // its use. We do this by not referring to the extended version in
8678 // error messages which are not directly related to its use.
8679 reportParseError("unexpected token, expected end of statement");
8680 return false;
8682 Parser.Lex(); // Eat the comma.
8683 const MCExpr *DummyNumber;
8684 int64_t DummyNumberVal;
8685 // If the user was explicitly trying to use the extended version,
8686 // we still give helpful extension-related error messages.
8687 if (Parser.parseExpression(DummyNumber)) {
8688 reportParseError("expected number after comma");
8689 return false;
8691 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8692 reportParseError("expected an absolute expression after comma");
8693 return false;
8697 // If this is not the end of the statement, report an error.
8698 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8699 reportParseError("unexpected token, expected end of statement");
8700 return false;
8703 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8705 getTargetStreamer().emitDirectiveEnt(*Sym);
8706 CurrentFn = Sym;
8707 IsCpRestoreSet = false;
8708 return false;
8711 if (IDVal == ".end") {
8712 StringRef SymbolName;
8714 if (Parser.parseIdentifier(SymbolName)) {
8715 reportParseError("expected identifier after .end");
8716 return false;
8719 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8720 reportParseError("unexpected token, expected end of statement");
8721 return false;
8724 if (CurrentFn == nullptr) {
8725 reportParseError(".end used without .ent");
8726 return false;
8729 if ((SymbolName != CurrentFn->getName())) {
8730 reportParseError(".end symbol does not match .ent symbol");
8731 return false;
8734 getTargetStreamer().emitDirectiveEnd(SymbolName);
8735 CurrentFn = nullptr;
8736 IsCpRestoreSet = false;
8737 return false;
8740 if (IDVal == ".frame") {
8741 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8742 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8743 ParseStatus Res = parseAnyRegister(TmpReg);
8744 if (Res.isNoMatch() || Res.isFailure()) {
8745 reportParseError("expected stack register");
8746 return false;
8749 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8750 if (!StackRegOpnd.isGPRAsmReg()) {
8751 reportParseError(StackRegOpnd.getStartLoc(),
8752 "expected general purpose register");
8753 return false;
8755 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8757 if (Parser.getTok().is(AsmToken::Comma))
8758 Parser.Lex();
8759 else {
8760 reportParseError("unexpected token, expected comma");
8761 return false;
8764 // Parse the frame size.
8765 const MCExpr *FrameSize;
8766 int64_t FrameSizeVal;
8768 if (Parser.parseExpression(FrameSize)) {
8769 reportParseError("expected frame size value");
8770 return false;
8773 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8774 reportParseError("frame size not an absolute expression");
8775 return false;
8778 if (Parser.getTok().is(AsmToken::Comma))
8779 Parser.Lex();
8780 else {
8781 reportParseError("unexpected token, expected comma");
8782 return false;
8785 // Parse the return register.
8786 TmpReg.clear();
8787 Res = parseAnyRegister(TmpReg);
8788 if (Res.isNoMatch() || Res.isFailure()) {
8789 reportParseError("expected return register");
8790 return false;
8793 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8794 if (!ReturnRegOpnd.isGPRAsmReg()) {
8795 reportParseError(ReturnRegOpnd.getStartLoc(),
8796 "expected general purpose register");
8797 return false;
8800 // If this is not the end of the statement, report an error.
8801 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8802 reportParseError("unexpected token, expected end of statement");
8803 return false;
8806 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8807 ReturnRegOpnd.getGPR32Reg());
8808 IsCpRestoreSet = false;
8809 return false;
8812 if (IDVal == ".set") {
8813 parseDirectiveSet();
8814 return false;
8817 if (IDVal == ".mask" || IDVal == ".fmask") {
8818 // .mask bitmask, frame_offset
8819 // bitmask: One bit for each register used.
8820 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8821 // first register is expected to be saved.
8822 // Examples:
8823 // .mask 0x80000000, -4
8824 // .fmask 0x80000000, -4
8827 // Parse the bitmask
8828 const MCExpr *BitMask;
8829 int64_t BitMaskVal;
8831 if (Parser.parseExpression(BitMask)) {
8832 reportParseError("expected bitmask value");
8833 return false;
8836 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8837 reportParseError("bitmask not an absolute expression");
8838 return false;
8841 if (Parser.getTok().is(AsmToken::Comma))
8842 Parser.Lex();
8843 else {
8844 reportParseError("unexpected token, expected comma");
8845 return false;
8848 // Parse the frame_offset
8849 const MCExpr *FrameOffset;
8850 int64_t FrameOffsetVal;
8852 if (Parser.parseExpression(FrameOffset)) {
8853 reportParseError("expected frame offset value");
8854 return false;
8857 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8858 reportParseError("frame offset not an absolute expression");
8859 return false;
8862 // If this is not the end of the statement, report an error.
8863 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8864 reportParseError("unexpected token, expected end of statement");
8865 return false;
8868 if (IDVal == ".mask")
8869 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8870 else
8871 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8872 return false;
8875 if (IDVal == ".nan")
8876 return parseDirectiveNaN();
8878 if (IDVal == ".gpword") {
8879 parseDirectiveGpWord();
8880 return false;
8883 if (IDVal == ".gpdword") {
8884 parseDirectiveGpDWord();
8885 return false;
8888 if (IDVal == ".dtprelword") {
8889 parseDirectiveDtpRelWord();
8890 return false;
8893 if (IDVal == ".dtpreldword") {
8894 parseDirectiveDtpRelDWord();
8895 return false;
8898 if (IDVal == ".tprelword") {
8899 parseDirectiveTpRelWord();
8900 return false;
8903 if (IDVal == ".tpreldword") {
8904 parseDirectiveTpRelDWord();
8905 return false;
8908 if (IDVal == ".option") {
8909 parseDirectiveOption();
8910 return false;
8913 if (IDVal == ".abicalls") {
8914 getTargetStreamer().emitDirectiveAbiCalls();
8915 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8916 Error(Parser.getTok().getLoc(),
8917 "unexpected token, expected end of statement");
8919 return false;
8922 if (IDVal == ".cpsetup") {
8923 parseDirectiveCPSetup();
8924 return false;
8926 if (IDVal == ".cpreturn") {
8927 parseDirectiveCPReturn();
8928 return false;
8930 if (IDVal == ".module") {
8931 parseDirectiveModule();
8932 return false;
8934 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8935 parseInternalDirectiveReallowModule();
8936 return false;
8938 if (IDVal == ".insn") {
8939 parseInsnDirective();
8940 return false;
8942 if (IDVal == ".rdata") {
8943 parseRSectionDirective(".rodata");
8944 return false;
8946 if (IDVal == ".sbss") {
8947 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8948 return false;
8950 if (IDVal == ".sdata") {
8951 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8952 return false;
8955 return true;
8958 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8959 // If this is not the end of the statement, report an error.
8960 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8961 reportParseError("unexpected token, expected end of statement");
8962 return false;
8965 getTargetStreamer().reallowModuleDirective();
8967 getParser().Lex(); // Eat EndOfStatement token.
8968 return false;
8971 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser() {
8972 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8973 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8974 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8975 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8978 #define GET_REGISTER_MATCHER
8979 #define GET_MATCHER_IMPLEMENTATION
8980 #define GET_MNEMONIC_SPELL_CHECKER
8981 #include "MipsGenAsmMatcher.inc"
8983 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8984 // Find the appropriate table for this asm variant.
8985 const MatchEntry *Start, *End;
8986 switch (VariantID) {
8987 default: llvm_unreachable("invalid variant!");
8988 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8990 // Search the table.
8991 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8992 return MnemonicRange.first != MnemonicRange.second;