LLVM 22.0.0git
MipsAsmParser.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
8
16#include "llvm/ADT/APFloat.h"
18#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/Twine.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"
35#include "llvm/MC/MCStreamer.h"
37#include "llvm/MC/MCSymbol.h"
38#include "llvm/MC/MCSymbolELF.h"
39#include "llvm/MC/MCValue.h"
45#include "llvm/Support/Debug.h"
48#include "llvm/Support/SMLoc.h"
53#include <algorithm>
54#include <cassert>
55#include <cstdint>
56#include <memory>
57#include <string>
58#include <utility>
59
60using namespace llvm;
61
62#define DEBUG_TYPE "mips-asm-parser"
63
64namespace llvm {
65
66class MCInstrInfo;
67
68} // end namespace llvm
69
71
72namespace {
73
74class MipsAssemblerOptions {
75public:
76 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
77
78 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
83 }
84
85 unsigned getATRegIndex() const { return ATReg; }
86 bool setATRegIndex(unsigned Reg) {
87 if (Reg > 31)
88 return false;
89
90 ATReg = Reg;
91 return true;
92 }
93
94 bool isReorder() const { return Reorder; }
95 void setReorder() { Reorder = true; }
96 void setNoReorder() { Reorder = false; }
97
98 bool isMacro() const { return Macro; }
99 void setMacro() { Macro = true; }
100 void setNoMacro() { Macro = false; }
101
102 const FeatureBitset &getFeatures() const { return Features; }
103 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
104
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;
111
112private:
113 unsigned ATReg = 1;
114 bool Reorder = true;
115 bool Macro = true;
116 FeatureBitset Features;
117};
118
119} // end anonymous namespace
120
121const 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
131};
132
133namespace {
134
135class 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);
141 }
142
143 MipsABIInfo ABI;
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;
158
159 // Map of register aliases created via the .set directive.
160 StringMap<AsmToken> RegisterSets;
161
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);
165
166 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
167
168#define GET_ASSEMBLER_HEADER
169#include "MipsGenAsmMatcher.inc"
170
171 unsigned
172 checkEarlyTargetMatchPredicate(MCInst &Inst,
173 const OperandVector &Operands) override;
174 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
175
176 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
179 bool MatchingInlineAsm) override;
180
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;
185
186 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
187
188 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
189
190 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
191
192 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
193 SMLoc NameLoc, OperandVector &Operands) override;
194
195 bool ParseDirective(AsmToken DirectiveID) override;
196
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);
205 ParseStatus parseJumpTarget(OperandVector &Operands);
206 ParseStatus parseInvNum(OperandVector &Operands);
207 ParseStatus parseRegisterList(OperandVector &Operands);
208 const MCExpr *parseRelocExpr();
209
210 bool searchSymbolAlias(OperandVector &Operands);
211
212 bool parseOperand(OperandVector &, StringRef Mnemonic);
213
214 enum MacroExpanderResultTy {
215 MER_NotAMacro,
216 MER_Success,
217 MER_Fail,
218 };
219
220 // Expands assembly pseudo instructions.
221 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
222 MCStreamer &Out,
223 const MCSubtargetInfo *STI);
224
225 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
226 const MCSubtargetInfo *STI);
227
228 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
229 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
230 MCStreamer &Out, const MCSubtargetInfo *STI);
231
232 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, MCRegister DstReg,
233 MCRegister SrcReg, bool Is32BitSym, SMLoc IDLoc,
234 MCStreamer &Out, const MCSubtargetInfo *STI);
235
236 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
237
238 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
239 MCStreamer &Out, const MCSubtargetInfo *STI);
240
241 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
242 const MCSubtargetInfo *STI);
243 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
247 bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
248 MCStreamer &Out, const MCSubtargetInfo *STI);
249
250 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
251 const MCOperand &Offset, bool Is32BitAddress,
252 SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
254
255 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
257
258 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI, bool IsLoad);
260 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI, bool IsLoad);
262
263 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264 const MCSubtargetInfo *STI);
265
266 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
267 const MCSubtargetInfo *STI);
268
269 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270 const MCSubtargetInfo *STI);
271
272 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
273 const MCSubtargetInfo *STI);
274
275 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
276 const MCSubtargetInfo *STI, const bool IsMips64,
277 const bool Signed);
278
279 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
280 MCStreamer &Out, const MCSubtargetInfo *STI);
281
282 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
284
285 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
287
288 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289 const MCSubtargetInfo *STI);
290
291 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292 const MCSubtargetInfo *STI);
293
294 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295 const MCSubtargetInfo *STI);
296
297 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298 const MCSubtargetInfo *STI);
299
300 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301 const MCSubtargetInfo *STI);
302
303 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304 const MCSubtargetInfo *STI);
305
306 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
307 MCStreamer &Out, const MCSubtargetInfo *STI);
308 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
309 const MCSubtargetInfo *STI);
310 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
312 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI);
314
315 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316 const MCSubtargetInfo *STI);
317
318 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319 const MCSubtargetInfo *STI);
320
321 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322 const MCSubtargetInfo *STI);
323
324 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325 const MCSubtargetInfo *STI);
326
327 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
328 const MCSubtargetInfo *STI);
329
330 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
331 const MCSubtargetInfo *STI, bool IsLoad);
332
333 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
334 const MCSubtargetInfo *STI);
335
336 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
337 const MCSubtargetInfo *STI);
338
339 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
340 const MCSubtargetInfo *STI);
341
342 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
343 const MCSubtargetInfo *STI);
344
345 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
346 const MCSubtargetInfo *STI);
347
348 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
349 const MCSubtargetInfo *STI);
350
351 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
352 const MCSubtargetInfo *STI);
353
354 bool reportParseError(const Twine &ErrorMsg);
355 bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
356
357 bool parseSetMips0Directive();
358 bool parseSetArchDirective();
359 bool parseSetFeature(uint64_t Feature);
360 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
361 bool parseDirectiveCpAdd(SMLoc Loc);
362 bool parseDirectiveCpLoad(SMLoc Loc);
363 bool parseDirectiveCpLocal(SMLoc Loc);
364 bool parseDirectiveCpRestore(SMLoc Loc);
365 bool parseDirectiveCPSetup();
366 bool parseDirectiveCPReturn();
367 bool parseDirectiveNaN();
368 bool parseDirectiveSet();
369 bool parseDirectiveOption();
370 bool parseInsnDirective();
371 bool parseRSectionDirective(StringRef Section);
372 bool parseSSectionDirective(StringRef Section, unsigned Type);
373
374 bool parseSetAtDirective();
375 bool parseSetNoAtDirective();
376 bool parseSetMacroDirective();
377 bool parseSetNoMacroDirective();
378 bool parseSetMsaDirective();
379 bool parseSetNoMsaDirective();
380 bool parseSetNoDspDirective();
381 bool parseSetNoMips3DDirective();
382 bool parseSetReorderDirective();
383 bool parseSetNoReorderDirective();
384 bool parseSetMips16Directive();
385 bool parseSetNoMips16Directive();
386 bool parseSetFpDirective();
387 bool parseSetOddSPRegDirective();
388 bool parseSetNoOddSPRegDirective();
389 bool parseSetPopDirective();
390 bool parseSetPushDirective();
391 bool parseSetSoftFloatDirective();
392 bool parseSetHardFloatDirective();
393 bool parseSetMtDirective();
394 bool parseSetNoMtDirective();
395 bool parseSetNoCRCDirective();
396 bool parseSetNoVirtDirective();
397 bool parseSetNoGINVDirective();
398
399 bool parseSetAssignment();
400
401 bool parseDirectiveGpWord();
402 bool parseDirectiveGpDWord();
403 bool parseDirectiveDtpRelWord();
404 bool parseDirectiveDtpRelDWord();
405 bool parseDirectiveTpRelWord();
406 bool parseDirectiveTpRelDWord();
407 bool parseDirectiveModule();
408 bool parseDirectiveModuleFP();
409 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
410 StringRef Directive);
411
412 bool parseInternalDirectiveReallowModule();
413
414 bool eatComma(StringRef ErrorStr);
415
416 int matchCPURegisterName(StringRef Symbol);
417
418 int matchHWRegsRegisterName(StringRef Symbol);
419
420 int matchFPURegisterName(StringRef Name);
421
422 int matchFCCRegisterName(StringRef Name);
423
424 int matchACRegisterName(StringRef Name);
425
426 int matchMSA128RegisterName(StringRef Name);
427
428 int matchMSA128CtrlRegisterName(StringRef Name);
429
430 MCRegister getReg(int RC, int RegNo);
431
432 /// Returns the internal register number for the current AT. Also checks if
433 /// the current AT is unavailable (set to $0) and gives an error if it is.
434 /// This should be used in pseudo-instruction expansions which need AT.
435 MCRegister getATReg(SMLoc Loc);
436
437 bool canUseATReg();
438
439 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
440 const MCSubtargetInfo *STI);
441
442 // Helper function that checks if the value of a vector index is within the
443 // boundaries of accepted values for each RegisterKind
444 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
445 bool validateMSAIndex(int Val, int RegKind);
446
447 // Selects a new architecture by updating the FeatureBits with the necessary
448 // info including implied dependencies.
449 // Internally, it clears all the feature bits related to *any* architecture
450 // and selects the new one using the ToggleFeature functionality of the
451 // MCSubtargetInfo object that handles implied dependencies. The reason we
452 // clear all the arch related bits manually is because ToggleFeature only
453 // clears the features that imply the feature being cleared and not the
454 // features implied by the feature being cleared. This is easier to see
455 // with an example:
456 // --------------------------------------------------
457 // | Feature | Implies |
458 // | -------------------------------------------------|
459 // | FeatureMips1 | None |
460 // | FeatureMips2 | FeatureMips1 |
461 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
462 // | FeatureMips4 | FeatureMips3 |
463 // | ... | |
464 // --------------------------------------------------
465 //
466 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
467 // FeatureMipsGP64 | FeatureMips1)
468 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
469 void selectArch(StringRef ArchFeature) {
470 MCSubtargetInfo &STI = copySTI();
471 FeatureBitset FeatureBits = STI.getFeatureBits();
472 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
473 STI.setFeatureBits(FeatureBits);
474 setAvailableFeatures(
475 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
476 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
477 }
478
479 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
480 if (!(getSTI().hasFeature(Feature))) {
481 MCSubtargetInfo &STI = copySTI();
482 setAvailableFeatures(
483 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
484 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
485 }
486 }
487
488 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
489 if (getSTI().hasFeature(Feature)) {
490 MCSubtargetInfo &STI = copySTI();
491 setAvailableFeatures(
492 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
493 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
494 }
495 }
496
497 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
498 setFeatureBits(Feature, FeatureString);
499 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
500 }
501
502 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
503 clearFeatureBits(Feature, FeatureString);
504 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
505 }
506
507public:
508 enum MipsMatchResultTy {
509 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
510 Match_RequiresDifferentOperands,
511 Match_RequiresNoZeroRegister,
512 Match_RequiresSameSrcAndDst,
513 Match_NoFCCRegisterForCurrentISA,
514 Match_NonZeroOperandForSync,
515 Match_NonZeroOperandForMTCX,
516 Match_RequiresPosSizeRange0_32,
517 Match_RequiresPosSizeRange33_64,
518 Match_RequiresPosSizeUImm6,
519#define GET_OPERAND_DIAGNOSTIC_TYPES
520#include "MipsGenAsmMatcher.inc"
521#undef GET_OPERAND_DIAGNOSTIC_TYPES
522 };
523
524 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
525 const MCInstrInfo &MII, const MCTargetOptions &Options)
526 : MCTargetAsmParser(Options, sti, MII),
527 ABI(MipsABIInfo::computeTargetABI(sti.getTargetTriple(), sti.getCPU(),
528 Options)) {
530
531 parser.addAliasForDirective(".asciiz", ".asciz");
532 parser.addAliasForDirective(".hword", ".2byte");
533 parser.addAliasForDirective(".word", ".4byte");
534 parser.addAliasForDirective(".dword", ".8byte");
535
536 // Initialize the set of available features.
537 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
538
539 // Remember the initial assembler options. The user can not modify these.
540 AssemblerOptions.push_back(
541 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
542
543 // Create an assembler options environment for the user to modify.
544 AssemblerOptions.push_back(
545 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
546
547 getTargetStreamer().updateABIInfo(*this);
548
549 if (!isABI_O32() && !useOddSPReg() != 0)
550 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
551
552 CurrentFn = nullptr;
553
554 CurForbiddenSlotAttr = false;
555 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
556
557 IsCpRestoreSet = false;
558 CpRestoreOffset = -1;
559 GPReg = ABI.GetGlobalPtr();
560
561 const Triple &TheTriple = sti.getTargetTriple();
562 IsLittleEndian = TheTriple.isLittleEndian();
563
564 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
565 report_fatal_error("microMIPS64R6 is not supported", false);
566
567 if (!isABI_O32() && inMicroMipsMode())
568 report_fatal_error("microMIPS64 is not supported", false);
569 }
570
571 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
572 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
573
574 bool isGP64bit() const {
575 return getSTI().hasFeature(Mips::FeatureGP64Bit);
576 }
577
578 bool isFP64bit() const {
579 return getSTI().hasFeature(Mips::FeatureFP64Bit);
580 }
581
582 bool isJalrRelocAvailable(const MCExpr *JalExpr) {
583 if (!EmitJalrReloc)
584 return false;
585 MCValue Res;
586 if (!JalExpr->evaluateAsRelocatable(Res, nullptr))
587 return false;
588 if (Res.getSubSym())
589 return false;
590 if (Res.getConstant() != 0)
591 return ABI.IsN32() || ABI.IsN64();
592 return true;
593 }
594
595 const MipsABIInfo &getABI() const { return ABI; }
596 bool isABI_N32() const { return ABI.IsN32(); }
597 bool isABI_N64() const { return ABI.IsN64(); }
598 bool isABI_O32() const { return ABI.IsO32(); }
599 bool isABI_FPXX() const {
600 return getSTI().hasFeature(Mips::FeatureFPXX);
601 }
602
603 bool useOddSPReg() const {
604 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
605 }
606
607 bool inMicroMipsMode() const {
608 return getSTI().hasFeature(Mips::FeatureMicroMips);
609 }
610
611 bool hasMips1() const {
612 return getSTI().hasFeature(Mips::FeatureMips1);
613 }
614
615 bool hasMips2() const {
616 return getSTI().hasFeature(Mips::FeatureMips2);
617 }
618
619 bool hasMips3() const {
620 return getSTI().hasFeature(Mips::FeatureMips3);
621 }
622
623 bool hasMips4() const {
624 return getSTI().hasFeature(Mips::FeatureMips4);
625 }
626
627 bool hasMips5() const {
628 return getSTI().hasFeature(Mips::FeatureMips5);
629 }
630
631 bool hasMips32() const {
632 return getSTI().hasFeature(Mips::FeatureMips32);
633 }
634
635 bool hasMips64() const {
636 return getSTI().hasFeature(Mips::FeatureMips64);
637 }
638
639 bool hasMips32r2() const {
640 return getSTI().hasFeature(Mips::FeatureMips32r2);
641 }
642
643 bool hasMips64r2() const {
644 return getSTI().hasFeature(Mips::FeatureMips64r2);
645 }
646
647 bool hasMips32r3() const {
648 return (getSTI().hasFeature(Mips::FeatureMips32r3));
649 }
650
651 bool hasMips64r3() const {
652 return (getSTI().hasFeature(Mips::FeatureMips64r3));
653 }
654
655 bool hasMips32r5() const {
656 return (getSTI().hasFeature(Mips::FeatureMips32r5));
657 }
658
659 bool hasMips64r5() const {
660 return (getSTI().hasFeature(Mips::FeatureMips64r5));
661 }
662
663 bool hasMips32r6() const {
664 return getSTI().hasFeature(Mips::FeatureMips32r6);
665 }
666
667 bool hasMips64r6() const {
668 return getSTI().hasFeature(Mips::FeatureMips64r6);
669 }
670
671 bool hasDSP() const {
672 return getSTI().hasFeature(Mips::FeatureDSP);
673 }
674
675 bool hasDSPR2() const {
676 return getSTI().hasFeature(Mips::FeatureDSPR2);
677 }
678
679 bool hasDSPR3() const {
680 return getSTI().hasFeature(Mips::FeatureDSPR3);
681 }
682
683 bool hasMSA() const {
684 return getSTI().hasFeature(Mips::FeatureMSA);
685 }
686
687 bool hasCnMips() const {
688 return (getSTI().hasFeature(Mips::FeatureCnMips));
689 }
690
691 bool hasCnMipsP() const {
692 return (getSTI().hasFeature(Mips::FeatureCnMipsP));
693 }
694
695 bool inPicMode() {
696 return IsPicEnabled;
697 }
698
699 bool inMips16Mode() const {
700 return getSTI().hasFeature(Mips::FeatureMips16);
701 }
702
703 bool useTraps() const {
704 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
705 }
706
707 bool useSoftFloat() const {
708 return getSTI().hasFeature(Mips::FeatureSoftFloat);
709 }
710 bool hasMT() const {
711 return getSTI().hasFeature(Mips::FeatureMT);
712 }
713
714 bool hasCRC() const {
715 return getSTI().hasFeature(Mips::FeatureCRC);
716 }
717
718 bool hasVirt() const {
719 return getSTI().hasFeature(Mips::FeatureVirt);
720 }
721
722 bool hasGINV() const {
723 return getSTI().hasFeature(Mips::FeatureGINV);
724 }
725
726 bool hasForbiddenSlot(const MCInstrDesc &MCID) const {
727 return !inMicroMipsMode() && (MCID.TSFlags & MipsII::HasForbiddenSlot);
728 }
729
730 bool SafeInForbiddenSlot(const MCInstrDesc &MCID) const {
731 return !(MCID.TSFlags & MipsII::IsCTI);
732 }
733
734 void onEndOfFile() override;
735
736 /// Warn if RegIndex is the same as the current AT.
737 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
738
739 void warnIfNoMacro(SMLoc Loc);
740
741 bool isLittle() const { return IsLittleEndian; }
742
743 bool areEqualRegs(const MCParsedAsmOperand &Op1,
744 const MCParsedAsmOperand &Op2) const override;
745};
746
747/// MipsOperand - Instances of this class represent a parsed Mips machine
748/// instruction.
749class MipsOperand : public MCParsedAsmOperand {
750public:
751 /// Broad categories of register classes
752 /// The exact class is finalized by the render method.
753 enum RegKind {
754 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
755 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
756 /// isFP64bit())
757 RegKind_FCC = 4, /// FCC
758 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
759 RegKind_MSACtrl = 16, /// MSA control registers
760 RegKind_COP2 = 32, /// COP2
761 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
762 /// context).
763 RegKind_CCR = 128, /// CCR
764 RegKind_HWRegs = 256, /// HWRegs
765 RegKind_COP3 = 512, /// COP3
766 RegKind_COP0 = 1024, /// COP0
767 /// Potentially any (e.g. $1)
768 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
769 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
770 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
771 };
772
773private:
774 enum KindTy {
775 k_Immediate, /// An immediate (possibly involving symbol references)
776 k_Memory, /// Base + Offset Memory Address
777 k_RegisterIndex, /// A register index in one or more RegKind.
778 k_Token, /// A simple token
779 k_RegList, /// A physical register list
780 } Kind;
781
782public:
783 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(K), AsmParser(Parser) {}
784
785 ~MipsOperand() override {
786 switch (Kind) {
787 case k_Memory:
788 delete Mem.Base;
789 break;
790 case k_RegList:
791 delete RegList.List;
792 break;
793 case k_Immediate:
794 case k_RegisterIndex:
795 case k_Token:
796 break;
797 }
798 }
799
800private:
801 /// For diagnostics, and checking the assembler temporary
802 MipsAsmParser &AsmParser;
803
804 struct Token {
805 const char *Data;
806 unsigned Length;
807 };
808
809 struct RegIdxOp {
810 unsigned Index; /// Index into the register class
811 RegKind Kind; /// Bitfield of the kinds it could possibly be
812 struct Token Tok; /// The input token this operand originated from.
813 const MCRegisterInfo *RegInfo;
814 };
815
816 struct ImmOp {
817 const MCExpr *Val;
818 };
819
820 struct MemOp {
821 MipsOperand *Base;
822 const MCExpr *Off;
823 };
824
825 struct RegListOp {
827 };
828
829 union {
830 struct Token Tok;
831 struct RegIdxOp RegIdx;
832 struct ImmOp Imm;
833 struct MemOp Mem;
834 struct RegListOp RegList;
835 };
836
837 SMLoc StartLoc, EndLoc;
838
839 /// Internal constructor for register kinds
840 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
841 RegKind RegKind,
842 const MCRegisterInfo *RegInfo,
843 SMLoc S, SMLoc E,
844 MipsAsmParser &Parser) {
845 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
846 Op->RegIdx.Index = Index;
847 Op->RegIdx.RegInfo = RegInfo;
848 Op->RegIdx.Kind = RegKind;
849 Op->RegIdx.Tok.Data = Str.data();
850 Op->RegIdx.Tok.Length = Str.size();
851 Op->StartLoc = S;
852 Op->EndLoc = E;
853 return Op;
854 }
855
856public:
857 /// Coerce the register to GPR32 and return the real register for the current
858 /// target.
859 MCRegister getGPR32Reg() const {
860 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
861 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
862 unsigned ClassID = Mips::GPR32RegClassID;
863 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
864 }
865
866 /// Coerce the register to GPR32 and return the real register for the current
867 /// target.
868 MCRegister getGPRMM16Reg() const {
869 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
870 unsigned ClassID = Mips::GPR32RegClassID;
871 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
872 }
873
874 /// Coerce the register to GPR64 and return the real register for the current
875 /// target.
876 MCRegister getGPR64Reg() const {
877 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
878 unsigned ClassID = Mips::GPR64RegClassID;
879 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
880 }
881
882private:
883 /// Coerce the register to AFGR64 and return the real register for the current
884 /// target.
885 MCRegister getAFGR64Reg() const {
886 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
887 if (RegIdx.Index % 2 != 0)
888 AsmParser.Warning(StartLoc, "Float register should be even.");
889 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
890 .getRegister(RegIdx.Index / 2);
891 }
892
893 /// Coerce the register to FGR64 and return the real register for the current
894 /// target.
895 MCRegister getFGR64Reg() const {
896 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
897 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
898 .getRegister(RegIdx.Index);
899 }
900
901 /// Coerce the register to FGR32 and return the real register for the current
902 /// target.
903 MCRegister getFGR32Reg() const {
904 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
905 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
906 .getRegister(RegIdx.Index);
907 }
908
909 /// Coerce the register to FCC and return the real register for the current
910 /// target.
911 MCRegister getFCCReg() const {
912 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
913 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
914 .getRegister(RegIdx.Index);
915 }
916
917 /// Coerce the register to MSA128 and return the real register for the current
918 /// target.
919 MCRegister getMSA128Reg() const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
921 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
922 // identical
923 unsigned ClassID = Mips::MSA128BRegClassID;
924 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
925 }
926
927 /// Coerce the register to MSACtrl and return the real register for the
928 /// current target.
929 MCRegister getMSACtrlReg() const {
930 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
931 unsigned ClassID = Mips::MSACtrlRegClassID;
932 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
933 }
934
935 /// Coerce the register to COP0 and return the real register for the
936 /// current target.
937 MCRegister getCOP0Reg() const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
939 unsigned ClassID = Mips::COP0RegClassID;
940 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
941 }
942
943 /// Coerce the register to COP2 and return the real register for the
944 /// current target.
945 MCRegister getCOP2Reg() const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
947 unsigned ClassID = Mips::COP2RegClassID;
948 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
949 }
950
951 /// Coerce the register to COP3 and return the real register for the
952 /// current target.
953 MCRegister getCOP3Reg() const {
954 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
955 unsigned ClassID = Mips::COP3RegClassID;
956 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
957 }
958
959 /// Coerce the register to ACC64DSP and return the real register for the
960 /// current target.
961 MCRegister getACC64DSPReg() const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
963 unsigned ClassID = Mips::ACC64DSPRegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
965 }
966
967 /// Coerce the register to HI32DSP and return the real register for the
968 /// current target.
969 MCRegister getHI32DSPReg() const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
971 unsigned ClassID = Mips::HI32DSPRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
973 }
974
975 /// Coerce the register to LO32DSP and return the real register for the
976 /// current target.
977 MCRegister getLO32DSPReg() const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
979 unsigned ClassID = Mips::LO32DSPRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
981 }
982
983 /// Coerce the register to CCR and return the real register for the
984 /// current target.
985 MCRegister getCCRReg() const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
987 unsigned ClassID = Mips::CCRRegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
989 }
990
991 /// Coerce the register to HWRegs and return the real register for the
992 /// current target.
993 MCRegister getHWRegsReg() const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
995 unsigned ClassID = Mips::HWRegsRegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
997 }
998
999public:
1000 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1001 // Add as immediate when possible. Null MCExpr = 0.
1002 if (!Expr)
1004 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1005 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1006 else
1008 }
1009
1010 void addRegOperands(MCInst &Inst, unsigned N) const {
1011 llvm_unreachable("Use a custom parser instead");
1012 }
1013
1014 /// Render the operand to an MCInst as a GPR32
1015 /// Asserts if the wrong number of operands are requested, or the operand
1016 /// is not a k_RegisterIndex compatible with RegKind_GPR
1017 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1018 assert(N == 1 && "Invalid number of operands!");
1019 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1020 }
1021
1022 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1023 assert(N == 1 && "Invalid number of operands!");
1024 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1025 }
1026
1027 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1028 assert(N == 1 && "Invalid number of operands!");
1029 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1030 }
1031
1032 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1033 assert(N == 1 && "Invalid number of operands!");
1034 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1035 }
1036
1037 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1038 assert(N == 1 && "Invalid number of operands!");
1039 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1040 }
1041
1042 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1043 assert(N == 1 && "Invalid number of operands!");
1044 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1045 }
1046
1047 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1048 assert(N == 1 && "Invalid number of operands!");
1049 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1050 }
1051
1052 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1053 unsigned N) const {
1054 assert(N == 1 && "Invalid number of operands!");
1055 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1056 }
1057
1058 /// Render the operand to an MCInst as a GPR64
1059 /// Asserts if the wrong number of operands are requested, or the operand
1060 /// is not a k_RegisterIndex compatible with RegKind_GPR
1061 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1062 assert(N == 1 && "Invalid number of operands!");
1063 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1064 }
1065
1066 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1067 assert(N == 1 && "Invalid number of operands!");
1068 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1069 }
1070
1071 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1072 assert(N == 1 && "Invalid number of operands!");
1073 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1074 }
1075
1076 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1077 assert(N == 1 && "Invalid number of operands!");
1078 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1079 }
1080
1081 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1082 assert(N == 1 && "Invalid number of operands!");
1083 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1084 }
1085
1086 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1087 assert(N == 1 && "Invalid number of operands!");
1088 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1089 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1090 // FIXME: This should propagate failure up to parseStatement.
1091 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1092 AsmParser.getParser().printError(
1093 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1094 "registers");
1095 }
1096
1097 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1098 assert(N == 1 && "Invalid number of operands!");
1099 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1100 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1101 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1102 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1103 "registers");
1104 }
1105
1106 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1107 assert(N == 1 && "Invalid number of operands!");
1108 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1109 }
1110
1111 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1112 assert(N == 1 && "Invalid number of operands!");
1113 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1114 }
1115
1116 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1117 assert(N == 1 && "Invalid number of operands!");
1118 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1119 }
1120
1121 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1122 assert(N == 1 && "Invalid number of operands!");
1123 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1124 }
1125
1126 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1127 assert(N == 1 && "Invalid number of operands!");
1128 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1129 }
1130
1131 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1132 assert(N == 1 && "Invalid number of operands!");
1133 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1134 }
1135
1136 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1137 assert(N == 1 && "Invalid number of operands!");
1138 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1139 }
1140
1141 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1142 assert(N == 1 && "Invalid number of operands!");
1143 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1144 }
1145
1146 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1147 assert(N == 1 && "Invalid number of operands!");
1148 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1149 }
1150
1151 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1152 assert(N == 1 && "Invalid number of operands!");
1153 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1154 }
1155
1156 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1157 assert(N == 1 && "Invalid number of operands!");
1158 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1159 }
1160
1161 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1162 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1163 assert(N == 1 && "Invalid number of operands!");
1164 uint64_t Imm = getConstantImm() - Offset;
1165 Imm &= (1ULL << Bits) - 1;
1166 Imm += Offset;
1167 Imm += AdjustOffset;
1169 }
1170
1171 template <unsigned Bits>
1172 void addSImmOperands(MCInst &Inst, unsigned N) const {
1173 if (isImm() && !isConstantImm()) {
1174 addExpr(Inst, getImm());
1175 return;
1176 }
1177 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1178 }
1179
1180 template <unsigned Bits>
1181 void addUImmOperands(MCInst &Inst, unsigned N) const {
1182 if (isImm() && !isConstantImm()) {
1183 addExpr(Inst, getImm());
1184 return;
1185 }
1186 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1187 }
1188
1189 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1190 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1191 assert(N == 1 && "Invalid number of operands!");
1192 int64_t Imm = getConstantImm() - Offset;
1193 Imm = SignExtend64<Bits>(Imm);
1194 Imm += Offset;
1195 Imm += AdjustOffset;
1197 }
1198
1199 void addImmOperands(MCInst &Inst, unsigned N) const {
1200 assert(N == 1 && "Invalid number of operands!");
1201 const MCExpr *Expr = getImm();
1202 addExpr(Inst, Expr);
1203 }
1204
1205 void addMemOperands(MCInst &Inst, unsigned N) const {
1206 assert(N == 2 && "Invalid number of operands!");
1207
1208 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1209 ? getMemBase()->getGPR64Reg()
1210 : getMemBase()->getGPR32Reg()));
1211
1212 const MCExpr *Expr = getMemOff();
1213 addExpr(Inst, Expr);
1214 }
1215
1216 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1217 assert(N == 2 && "Invalid number of operands!");
1218
1219 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1220
1221 const MCExpr *Expr = getMemOff();
1222 addExpr(Inst, Expr);
1223 }
1224
1225 void addRegListOperands(MCInst &Inst, unsigned N) const {
1226 assert(N == 1 && "Invalid number of operands!");
1227
1228 for (auto RegNo : getRegList())
1229 Inst.addOperand(MCOperand::createReg(RegNo));
1230 }
1231
1232 bool isReg() const override {
1233 // As a special case until we sort out the definition of div/divu, accept
1234 // $0/$zero here so that MCK_ZERO works correctly.
1235 return isGPRAsmReg() && RegIdx.Index == 0;
1236 }
1237
1238 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1239 bool isImm() const override { return Kind == k_Immediate; }
1240
1241 bool isConstantImm() const {
1242 int64_t Res;
1243 return isImm() && getImm()->evaluateAsAbsolute(Res);
1244 }
1245
1246 bool isConstantImmz() const {
1247 return isConstantImm() && getConstantImm() == 0;
1248 }
1249
1250 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1251 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1252 }
1253
1254 template <unsigned Bits> bool isSImm() const {
1255 if (!isImm())
1256 return false;
1257 int64_t Res;
1258 if (getImm()->evaluateAsAbsolute(Res))
1259 return isInt<Bits>(Res);
1260 // Allow conservatively if not a parse-time constant.
1261 return true;
1262 }
1263
1264 template <unsigned Bits> bool isUImm() const {
1265 if (!isImm())
1266 return false;
1267 int64_t Res;
1268 if (getImm()->evaluateAsAbsolute(Res))
1269 return isUInt<Bits>(Res);
1270 // Allow conservatively if not a parse-time constant.
1271 return true;
1272 }
1273
1274 template <unsigned Bits> bool isAnyImm() const {
1275 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1276 isUInt<Bits>(getConstantImm()))
1277 : isImm();
1278 }
1279
1280 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1281 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1282 }
1283
1284 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1285 return isConstantImm() && getConstantImm() >= Bottom &&
1286 getConstantImm() <= Top;
1287 }
1288
1289 bool isToken() const override {
1290 // Note: It's not possible to pretend that other operand kinds are tokens.
1291 // The matcher emitter checks tokens first.
1292 return Kind == k_Token;
1293 }
1294
1295 bool isMem() const override { return Kind == k_Memory; }
1296
1297 bool isConstantMemOff() const {
1298 return isMem() && isa<MCConstantExpr>(getMemOff());
1299 }
1300
1301 // Allow relocation operators.
1302 template <unsigned Bits, unsigned ShiftAmount = 0>
1303 bool isMemWithSimmOffset() const {
1304 if (!isMem())
1305 return false;
1306 if (!getMemBase()->isGPRAsmReg())
1307 return false;
1308 if (isa<MCSpecifierExpr>(getMemOff()) ||
1309 (isConstantMemOff() &&
1310 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1311 return true;
1312 MCValue Res;
1313 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr);
1314 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1315 }
1316
1317 bool isMemWithPtrSizeOffset() const {
1318 if (!isMem())
1319 return false;
1320 if (!getMemBase()->isGPRAsmReg())
1321 return false;
1322 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1323 if (isa<MCSpecifierExpr>(getMemOff()) ||
1324 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1325 return true;
1326 MCValue Res;
1327 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr);
1328 return IsReloc && isIntN(PtrBits, Res.getConstant());
1329 }
1330
1331 bool isMemWithGRPMM16Base() const {
1332 return isMem() && getMemBase()->isMM16AsmReg();
1333 }
1334
1335 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1336 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1337 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1338 }
1339
1340 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1341 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1342 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1343 && (getMemBase()->getGPR32Reg() == Mips::SP);
1344 }
1345
1346 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1347 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1348 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1349 && (getMemBase()->getGPR32Reg() == Mips::GP);
1350 }
1351
1352 template <unsigned Bits, unsigned ShiftLeftAmount>
1353 bool isScaledUImm() const {
1354 return isConstantImm() &&
1355 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1356 }
1357
1358 template <unsigned Bits, unsigned ShiftLeftAmount>
1359 bool isScaledSImm() const {
1360 if (isConstantImm() &&
1361 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1362 return true;
1363 // Operand can also be a symbol or symbol plus
1364 // offset in case of relocations.
1365 if (Kind != k_Immediate)
1366 return false;
1367 MCValue Res;
1368 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr);
1370 }
1371
1372 bool isRegList16() const {
1373 if (!isRegList())
1374 return false;
1375
1376 int Size = RegList.List->size();
1377 if (Size < 2 || Size > 5)
1378 return false;
1379
1380 unsigned R0 = RegList.List->front();
1381 unsigned R1 = RegList.List->back();
1382 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1383 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1384 return false;
1385
1386 int PrevReg = *RegList.List->begin();
1387 for (int i = 1; i < Size - 1; i++) {
1388 int Reg = (*(RegList.List))[i];
1389 if ( Reg != PrevReg + 1)
1390 return false;
1391 PrevReg = Reg;
1392 }
1393
1394 return true;
1395 }
1396
1397 bool isInvNum() const { return Kind == k_Immediate; }
1398
1399 bool isLSAImm() const {
1400 if (!isConstantImm())
1401 return false;
1402 int64_t Val = getConstantImm();
1403 return 1 <= Val && Val <= 4;
1404 }
1405
1406 bool isRegList() const { return Kind == k_RegList; }
1407
1408 StringRef getToken() const {
1409 assert(Kind == k_Token && "Invalid access!");
1410 return StringRef(Tok.Data, Tok.Length);
1411 }
1412
1413 MCRegister getReg() const override {
1414 // As a special case until we sort out the definition of div/divu, accept
1415 // $0/$zero here so that MCK_ZERO works correctly.
1416 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1417 RegIdx.Kind & RegKind_GPR)
1418 return getGPR32Reg(); // FIXME: GPR64 too
1419
1420 llvm_unreachable("Invalid access!");
1421 return 0;
1422 }
1423
1424 const MCExpr *getImm() const {
1425 assert((Kind == k_Immediate) && "Invalid access!");
1426 return Imm.Val;
1427 }
1428
1429 int64_t getConstantImm() const {
1430 const MCExpr *Val = getImm();
1431 int64_t Value = 0;
1432 (void)Val->evaluateAsAbsolute(Value);
1433 return Value;
1434 }
1435
1436 MipsOperand *getMemBase() const {
1437 assert((Kind == k_Memory) && "Invalid access!");
1438 return Mem.Base;
1439 }
1440
1441 const MCExpr *getMemOff() const {
1442 assert((Kind == k_Memory) && "Invalid access!");
1443 return Mem.Off;
1444 }
1445
1446 int64_t getConstantMemOff() const {
1447 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1448 }
1449
1450 const SmallVectorImpl<unsigned> &getRegList() const {
1451 assert((Kind == k_RegList) && "Invalid access!");
1452 return *(RegList.List);
1453 }
1454
1455 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1456 MipsAsmParser &Parser) {
1457 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1458 Op->Tok.Data = Str.data();
1459 Op->Tok.Length = Str.size();
1460 Op->StartLoc = S;
1461 Op->EndLoc = S;
1462 return Op;
1463 }
1464
1465 /// Create a numeric register (e.g. $1). The exact register remains
1466 /// unresolved until an instruction successfully matches
1467 static std::unique_ptr<MipsOperand>
1468 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1469 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1470 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1471 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1472 }
1473
1474 /// Create a register that is definitely a GPR.
1475 /// This is typically only used for named registers such as $gp.
1476 static std::unique_ptr<MipsOperand>
1477 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1478 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1479 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1480 }
1481
1482 /// Create a register that is definitely a FGR.
1483 /// This is typically only used for named registers such as $f0.
1484 static std::unique_ptr<MipsOperand>
1485 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1486 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1487 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1488 }
1489
1490 /// Create a register that is definitely a HWReg.
1491 /// This is typically only used for named registers such as $hwr_cpunum.
1492 static std::unique_ptr<MipsOperand>
1493 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1494 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1495 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1496 }
1497
1498 /// Create a register that is definitely an FCC.
1499 /// This is typically only used for named registers such as $fcc0.
1500 static std::unique_ptr<MipsOperand>
1501 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1502 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1503 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1504 }
1505
1506 /// Create a register that is definitely an ACC.
1507 /// This is typically only used for named registers such as $ac0.
1508 static std::unique_ptr<MipsOperand>
1509 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1510 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1511 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1512 }
1513
1514 /// Create a register that is definitely an MSA128.
1515 /// This is typically only used for named registers such as $w0.
1516 static std::unique_ptr<MipsOperand>
1517 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1518 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1519 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1520 }
1521
1522 /// Create a register that is definitely an MSACtrl.
1523 /// This is typically only used for named registers such as $msaaccess.
1524 static std::unique_ptr<MipsOperand>
1525 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1526 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1527 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1528 }
1529
1530 static std::unique_ptr<MipsOperand>
1531 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1532 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1533 Op->Imm.Val = Val;
1534 Op->StartLoc = S;
1535 Op->EndLoc = E;
1536 return Op;
1537 }
1538
1539 static std::unique_ptr<MipsOperand>
1540 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1541 SMLoc E, MipsAsmParser &Parser) {
1542 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1543 Op->Mem.Base = Base.release();
1544 Op->Mem.Off = Off;
1545 Op->StartLoc = S;
1546 Op->EndLoc = E;
1547 return Op;
1548 }
1549
1550 static std::unique_ptr<MipsOperand>
1551 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1552 MipsAsmParser &Parser) {
1553 assert(Regs.size() > 0 && "Empty list not allowed");
1554
1555 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1556 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1557 Op->StartLoc = StartLoc;
1558 Op->EndLoc = EndLoc;
1559 return Op;
1560 }
1561
1562 bool isGPRZeroAsmReg() const {
1563 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1564 }
1565
1566 bool isGPRNonZeroAsmReg() const {
1567 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1568 RegIdx.Index <= 31;
1569 }
1570
1571 bool isGPRAsmReg() const {
1572 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1573 }
1574
1575 bool isMM16AsmReg() const {
1576 if (!(isRegIdx() && RegIdx.Kind))
1577 return false;
1578 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1579 || RegIdx.Index == 16 || RegIdx.Index == 17);
1580
1581 }
1582 bool isMM16AsmRegZero() const {
1583 if (!(isRegIdx() && RegIdx.Kind))
1584 return false;
1585 return (RegIdx.Index == 0 ||
1586 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1587 RegIdx.Index == 17);
1588 }
1589
1590 bool isMM16AsmRegMoveP() const {
1591 if (!(isRegIdx() && RegIdx.Kind))
1592 return false;
1593 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1594 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1595 }
1596
1597 bool isMM16AsmRegMovePPairFirst() const {
1598 if (!(isRegIdx() && RegIdx.Kind))
1599 return false;
1600 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1601 }
1602
1603 bool isMM16AsmRegMovePPairSecond() const {
1604 if (!(isRegIdx() && RegIdx.Kind))
1605 return false;
1606 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1607 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1608 }
1609
1610 bool isFGRAsmReg() const {
1611 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1612 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1613 }
1614
1615 bool isStrictlyFGRAsmReg() const {
1616 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1617 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1618 }
1619
1620 bool isHWRegsAsmReg() const {
1621 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1622 }
1623
1624 bool isCCRAsmReg() const {
1625 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1626 }
1627
1628 bool isFCCAsmReg() const {
1629 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1630 return false;
1631 return RegIdx.Index <= 7;
1632 }
1633
1634 bool isACCAsmReg() const {
1635 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1636 }
1637
1638 bool isCOP0AsmReg() const {
1639 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1640 }
1641
1642 bool isCOP2AsmReg() const {
1643 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1644 }
1645
1646 bool isCOP3AsmReg() const {
1647 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1648 }
1649
1650 bool isMSA128AsmReg() const {
1651 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1652 }
1653
1654 bool isMSACtrlAsmReg() const {
1655 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1656 }
1657
1658 /// getStartLoc - Get the location of the first token of this operand.
1659 SMLoc getStartLoc() const override { return StartLoc; }
1660 /// getEndLoc - Get the location of the last token of this operand.
1661 SMLoc getEndLoc() const override { return EndLoc; }
1662
1663 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {
1664 switch (Kind) {
1665 case k_Immediate:
1666 OS << "Imm<";
1667 MAI.printExpr(OS, *Imm.Val);
1668 OS << ">";
1669 break;
1670 case k_Memory:
1671 OS << "Mem<";
1672 Mem.Base->print(OS, MAI);
1673 OS << ", ";
1674 MAI.printExpr(OS, *Mem.Off);
1675 OS << ">";
1676 break;
1677 case k_RegisterIndex:
1678 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1679 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1680 break;
1681 case k_Token:
1682 OS << getToken();
1683 break;
1684 case k_RegList:
1685 OS << "RegList< ";
1686 for (auto Reg : (*RegList.List))
1687 OS << Reg << " ";
1688 OS << ">";
1689 break;
1690 }
1691 }
1692
1693 bool isValidForTie(const MipsOperand &Other) const {
1694 if (Kind != Other.Kind)
1695 return false;
1696
1697 switch (Kind) {
1698 default:
1699 llvm_unreachable("Unexpected kind");
1700 return false;
1701 case k_RegisterIndex: {
1702 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1703 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1704 return Token == OtherToken;
1705 }
1706 }
1707 }
1708}; // class MipsOperand
1709
1710} // end anonymous namespace
1711
1712static bool hasShortDelaySlot(MCInst &Inst) {
1713 switch (Inst.getOpcode()) {
1714 case Mips::BEQ_MM:
1715 case Mips::BNE_MM:
1716 case Mips::BLTZ_MM:
1717 case Mips::BGEZ_MM:
1718 case Mips::BLEZ_MM:
1719 case Mips::BGTZ_MM:
1720 case Mips::JRC16_MM:
1721 case Mips::JALS_MM:
1722 case Mips::JALRS_MM:
1723 case Mips::JALRS16_MM:
1724 case Mips::BGEZALS_MM:
1725 case Mips::BLTZALS_MM:
1726 return true;
1727 case Mips::J_MM:
1728 return !Inst.getOperand(0).isReg();
1729 default:
1730 return false;
1731 }
1732}
1733
1734static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1735 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1736 return &SRExpr->getSymbol();
1737 }
1738
1739 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1740 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1741 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1742
1743 if (LHSSym)
1744 return LHSSym;
1745
1746 if (RHSSym)
1747 return RHSSym;
1748
1749 return nullptr;
1750 }
1751
1752 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1753 return getSingleMCSymbol(UExpr->getSubExpr());
1754
1755 return nullptr;
1756}
1757
1758static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1759 if (isa<MCSymbolRefExpr>(Expr))
1760 return 1;
1761
1762 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1763 return countMCSymbolRefExpr(BExpr->getLHS()) +
1764 countMCSymbolRefExpr(BExpr->getRHS());
1765
1766 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1767 return countMCSymbolRefExpr(UExpr->getSubExpr());
1768
1769 return 0;
1770}
1771
1772static bool isEvaluated(const MCExpr *Expr) {
1773 switch (Expr->getKind()) {
1774 case MCExpr::Constant:
1775 return true;
1776 case MCExpr::SymbolRef:
1777 return (cast<MCSymbolRefExpr>(Expr)->getSpecifier());
1778 case MCExpr::Binary: {
1779 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1780 if (!isEvaluated(BE->getLHS()))
1781 return false;
1782 return isEvaluated(BE->getRHS());
1783 }
1784 case MCExpr::Unary:
1785 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1786 case MCExpr::Specifier:
1787 return true;
1788 case MCExpr::Target:
1789 llvm_unreachable("unused by this backend");
1790 }
1791 return false;
1792}
1793
1794static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID) {
1795 unsigned NumOp = MCID.getNumOperands();
1796 if (NumOp != 3 && NumOp != 4)
1797 return false;
1798
1799 const MCOperandInfo &OpInfo = MCID.operands()[NumOp - 1];
1800 if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
1801 OpInfo.OperandType != MCOI::OPERAND_UNKNOWN &&
1802 OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9)
1803 return false;
1804
1805 MCOperand &Op = Inst.getOperand(NumOp - 1);
1806 if (Op.isImm()) {
1807 if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9)
1808 return !isInt<9>(Op.getImm());
1809 // Offset can't exceed 16bit value.
1810 return !isInt<16>(Op.getImm());
1811 }
1812
1813 if (Op.isExpr()) {
1814 const MCExpr *Expr = Op.getExpr();
1815 if (Expr->getKind() != MCExpr::SymbolRef)
1816 return !isEvaluated(Expr);
1817
1818 // Expand symbol.
1819 const MCSymbolRefExpr *SR = static_cast<const MCSymbolRefExpr *>(Expr);
1820 return SR->getSpecifier() == 0;
1821 }
1822
1823 return false;
1824}
1825
1826bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1827 MCStreamer &Out,
1828 const MCSubtargetInfo *STI) {
1829 MipsTargetStreamer &TOut = getTargetStreamer();
1830 const unsigned Opcode = Inst.getOpcode();
1831 const MCInstrDesc &MCID = MII.get(Opcode);
1832 bool ExpandedJalSym = false;
1833
1834 Inst.setLoc(IDLoc);
1835
1836 if (MCID.isBranch() || MCID.isCall()) {
1837 MCOperand Offset;
1838
1839 switch (Opcode) {
1840 default:
1841 break;
1842 case Mips::BBIT0:
1843 case Mips::BBIT032:
1844 case Mips::BBIT1:
1845 case Mips::BBIT132:
1846 assert(hasCnMips() && "instruction only valid for octeon cpus");
1847 [[fallthrough]];
1848
1849 case Mips::BEQ:
1850 case Mips::BNE:
1851 case Mips::BEQ_MM:
1852 case Mips::BNE_MM:
1853 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1854 Offset = Inst.getOperand(2);
1855 if (!Offset.isImm())
1856 break; // We'll deal with this situation later on when applying fixups.
1857 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1858 return Error(IDLoc, "branch target out of range");
1859 if (offsetToAlignment(Offset.getImm(),
1860 (inMicroMipsMode() ? Align(2) : Align(4))))
1861 return Error(IDLoc, "branch to misaligned address");
1862 break;
1863 case Mips::BGEZ:
1864 case Mips::BGTZ:
1865 case Mips::BLEZ:
1866 case Mips::BLTZ:
1867 case Mips::BGEZAL:
1868 case Mips::BLTZAL:
1869 case Mips::BC1F:
1870 case Mips::BC1T:
1871 case Mips::BGEZ_MM:
1872 case Mips::BGTZ_MM:
1873 case Mips::BLEZ_MM:
1874 case Mips::BLTZ_MM:
1875 case Mips::BGEZAL_MM:
1876 case Mips::BLTZAL_MM:
1877 case Mips::BC1F_MM:
1878 case Mips::BC1T_MM:
1879 case Mips::BC1EQZC_MMR6:
1880 case Mips::BC1NEZC_MMR6:
1881 case Mips::BC2EQZC_MMR6:
1882 case Mips::BC2NEZC_MMR6:
1883 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1884 Offset = Inst.getOperand(1);
1885 if (!Offset.isImm())
1886 break; // We'll deal with this situation later on when applying fixups.
1887 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1888 return Error(IDLoc, "branch target out of range");
1889 if (offsetToAlignment(Offset.getImm(),
1890 (inMicroMipsMode() ? Align(2) : Align(4))))
1891 return Error(IDLoc, "branch to misaligned address");
1892 break;
1893 case Mips::BGEC: case Mips::BGEC_MMR6:
1894 case Mips::BLTC: case Mips::BLTC_MMR6:
1895 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1896 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1897 case Mips::BEQC: case Mips::BEQC_MMR6:
1898 case Mips::BNEC: case Mips::BNEC_MMR6:
1899 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1900 Offset = Inst.getOperand(2);
1901 if (!Offset.isImm())
1902 break; // We'll deal with this situation later on when applying fixups.
1903 if (!isIntN(18, Offset.getImm()))
1904 return Error(IDLoc, "branch target out of range");
1905 if (offsetToAlignment(Offset.getImm(), Align(4)))
1906 return Error(IDLoc, "branch to misaligned address");
1907 break;
1908 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1909 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1910 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1911 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1912 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1913 Offset = Inst.getOperand(1);
1914 if (!Offset.isImm())
1915 break; // We'll deal with this situation later on when applying fixups.
1916 if (!isIntN(18, Offset.getImm()))
1917 return Error(IDLoc, "branch target out of range");
1918 if (offsetToAlignment(Offset.getImm(), Align(4)))
1919 return Error(IDLoc, "branch to misaligned address");
1920 break;
1921 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1922 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1923 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1924 Offset = Inst.getOperand(1);
1925 if (!Offset.isImm())
1926 break; // We'll deal with this situation later on when applying fixups.
1927 if (!isIntN(23, Offset.getImm()))
1928 return Error(IDLoc, "branch target out of range");
1929 if (offsetToAlignment(Offset.getImm(), Align(4)))
1930 return Error(IDLoc, "branch to misaligned address");
1931 break;
1932 case Mips::BEQZ16_MM:
1933 case Mips::BEQZC16_MMR6:
1934 case Mips::BNEZ16_MM:
1935 case Mips::BNEZC16_MMR6:
1936 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1937 Offset = Inst.getOperand(1);
1938 if (!Offset.isImm())
1939 break; // We'll deal with this situation later on when applying fixups.
1940 if (!isInt<8>(Offset.getImm()))
1941 return Error(IDLoc, "branch target out of range");
1942 if (offsetToAlignment(Offset.getImm(), Align(2)))
1943 return Error(IDLoc, "branch to misaligned address");
1944 break;
1945 }
1946 }
1947
1948 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1949 // We still accept it but it is a normal nop.
1950 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1951 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1952 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1953 "nop instruction");
1954 }
1955
1956 if (hasCnMips()) {
1957 MCOperand Opnd;
1958 int Imm;
1959
1960 switch (Opcode) {
1961 default:
1962 break;
1963
1964 case Mips::BBIT0:
1965 case Mips::BBIT032:
1966 case Mips::BBIT1:
1967 case Mips::BBIT132:
1968 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1969 // The offset is handled above
1970 Opnd = Inst.getOperand(1);
1971 if (!Opnd.isImm())
1972 return Error(IDLoc, "expected immediate operand kind");
1973 Imm = Opnd.getImm();
1974 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1975 Opcode == Mips::BBIT1 ? 63 : 31))
1976 return Error(IDLoc, "immediate operand value out of range");
1977 if (Imm > 31) {
1978 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1979 : Mips::BBIT132);
1980 Inst.getOperand(1).setImm(Imm - 32);
1981 }
1982 break;
1983
1984 case Mips::SEQi:
1985 case Mips::SNEi:
1986 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1987 Opnd = Inst.getOperand(2);
1988 if (!Opnd.isImm())
1989 return Error(IDLoc, "expected immediate operand kind");
1990 Imm = Opnd.getImm();
1991 if (!isInt<10>(Imm))
1992 return Error(IDLoc, "immediate operand value out of range");
1993 break;
1994 }
1995 }
1996
1997 // Warn on division by zero. We're checking here as all instructions get
1998 // processed here, not just the macros that need expansion.
1999 //
2000 // The MIPS backend models most of the divison instructions and macros as
2001 // three operand instructions. The pre-R6 divide instructions however have
2002 // two operands and explicitly define HI/LO as part of the instruction,
2003 // not in the operands.
2004 unsigned FirstOp = 1;
2005 unsigned SecondOp = 2;
2006 switch (Opcode) {
2007 default:
2008 break;
2009 case Mips::SDivIMacro:
2010 case Mips::UDivIMacro:
2011 case Mips::DSDivIMacro:
2012 case Mips::DUDivIMacro:
2013 if (Inst.getOperand(2).getImm() == 0) {
2014 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
2015 Inst.getOperand(1).getReg() == Mips::ZERO_64)
2016 Warning(IDLoc, "dividing zero by zero");
2017 else
2018 Warning(IDLoc, "division by zero");
2019 }
2020 break;
2021 case Mips::DSDIV:
2022 case Mips::SDIV:
2023 case Mips::UDIV:
2024 case Mips::DUDIV:
2025 case Mips::UDIV_MM:
2026 case Mips::SDIV_MM:
2027 FirstOp = 0;
2028 SecondOp = 1;
2029 [[fallthrough]];
2030 case Mips::SDivMacro:
2031 case Mips::DSDivMacro:
2032 case Mips::UDivMacro:
2033 case Mips::DUDivMacro:
2034 case Mips::DIV:
2035 case Mips::DIVU:
2036 case Mips::DDIV:
2037 case Mips::DDIVU:
2038 case Mips::DIVU_MMR6:
2039 case Mips::DIV_MMR6:
2040 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2041 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2042 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2043 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2044 Warning(IDLoc, "dividing zero by zero");
2045 else
2046 Warning(IDLoc, "division by zero");
2047 }
2048 break;
2049 }
2050
2051 // For PIC code convert unconditional jump to unconditional branch.
2052 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2053 MCInst BInst;
2054 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2055 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2056 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2057 BInst.addOperand(Inst.getOperand(0));
2058 Inst = BInst;
2059 }
2060
2061 // This expansion is not in a function called by tryExpandInstruction()
2062 // because the pseudo-instruction doesn't have a distinct opcode.
2063 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2064 warnIfNoMacro(IDLoc);
2065
2066 if (!Inst.getOperand(0).isExpr()) {
2067 return Error(IDLoc, "unsupported constant in relocation");
2068 }
2069
2070 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2071
2072 // We can do this expansion if there's only 1 symbol in the argument
2073 // expression.
2074 if (countMCSymbolRefExpr(JalExpr) > 1)
2075 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2076
2077 // FIXME: This is checking the expression can be handled by the later stages
2078 // of the assembler. We ought to leave it to those later stages.
2079 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2080
2081 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.getOperand(0),
2082 !isGP64bit(), IDLoc, Out, STI))
2083 return true;
2084
2085 MCInst JalrInst;
2086 if (inMicroMipsMode())
2087 JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2088 else
2089 JalrInst.setOpcode(Mips::JALR);
2090 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2091 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2092
2093 if (isJalrRelocAvailable(JalExpr)) {
2094 // As an optimization hint for the linker, before the JALR we add:
2095 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2096 // tmplabel:
2097 MCSymbol *TmpLabel = getContext().createTempSymbol();
2098 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2099 const MCExpr *RelocJalrExpr =
2100 MCSymbolRefExpr::create(JalSym, getContext(), IDLoc);
2101
2103 *TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2104 RelocJalrExpr);
2105 TOut.getStreamer().emitLabel(TmpLabel);
2106 }
2107
2108 Inst = JalrInst;
2109 ExpandedJalSym = true;
2110 }
2111
2112 if (MCID.mayLoad() || MCID.mayStore()) {
2113 // Check the offset of memory operand, if it is a symbol
2114 // reference or immediate we may have to expand instructions.
2115 if (needsExpandMemInst(Inst, MCID)) {
2116 switch (MCID.operands()[MCID.getNumOperands() - 1].OperandType) {
2118 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2119 break;
2120 default:
2121 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2122 break;
2123 }
2124 return getParser().hasPendingError();
2125 }
2126 }
2127
2128 if (inMicroMipsMode()) {
2129 if (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
2130 // Try to create 16-bit GP relative load instruction.
2131 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2132 const MCOperandInfo &OpInfo = MCID.operands()[i];
2133 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2134 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2135 MCOperand &Op = Inst.getOperand(i);
2136 if (Op.isImm()) {
2137 int MemOffset = Op.getImm();
2138 MCOperand &DstReg = Inst.getOperand(0);
2139 MCOperand &BaseReg = Inst.getOperand(1);
2140 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2141 getContext().getRegisterInfo()->getRegClass(
2142 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2143 (BaseReg.getReg() == Mips::GP ||
2144 BaseReg.getReg() == Mips::GP_64)) {
2145
2146 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2147 IDLoc, STI);
2148 return false;
2149 }
2150 }
2151 }
2152 } // for
2153 } // if load
2154
2155 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2156
2157 MCOperand Opnd;
2158 int Imm;
2159
2160 switch (Opcode) {
2161 default:
2162 break;
2163 case Mips::ADDIUSP_MM:
2164 Opnd = Inst.getOperand(0);
2165 if (!Opnd.isImm())
2166 return Error(IDLoc, "expected immediate operand kind");
2167 Imm = Opnd.getImm();
2168 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2169 Imm % 4 != 0)
2170 return Error(IDLoc, "immediate operand value out of range");
2171 break;
2172 case Mips::SLL16_MM:
2173 case Mips::SRL16_MM:
2174 Opnd = Inst.getOperand(2);
2175 if (!Opnd.isImm())
2176 return Error(IDLoc, "expected immediate operand kind");
2177 Imm = Opnd.getImm();
2178 if (Imm < 1 || Imm > 8)
2179 return Error(IDLoc, "immediate operand value out of range");
2180 break;
2181 case Mips::LI16_MM:
2182 Opnd = Inst.getOperand(1);
2183 if (!Opnd.isImm())
2184 return Error(IDLoc, "expected immediate operand kind");
2185 Imm = Opnd.getImm();
2186 if (Imm < -1 || Imm > 126)
2187 return Error(IDLoc, "immediate operand value out of range");
2188 break;
2189 case Mips::ADDIUR2_MM:
2190 Opnd = Inst.getOperand(2);
2191 if (!Opnd.isImm())
2192 return Error(IDLoc, "expected immediate operand kind");
2193 Imm = Opnd.getImm();
2194 if (!(Imm == 1 || Imm == -1 ||
2195 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2196 return Error(IDLoc, "immediate operand value out of range");
2197 break;
2198 case Mips::ANDI16_MM:
2199 Opnd = Inst.getOperand(2);
2200 if (!Opnd.isImm())
2201 return Error(IDLoc, "expected immediate operand kind");
2202 Imm = Opnd.getImm();
2203 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2204 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2205 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2206 return Error(IDLoc, "immediate operand value out of range");
2207 break;
2208 case Mips::LBU16_MM:
2209 Opnd = Inst.getOperand(2);
2210 if (!Opnd.isImm())
2211 return Error(IDLoc, "expected immediate operand kind");
2212 Imm = Opnd.getImm();
2213 if (Imm < -1 || Imm > 14)
2214 return Error(IDLoc, "immediate operand value out of range");
2215 break;
2216 case Mips::SB16_MM:
2217 case Mips::SB16_MMR6:
2218 Opnd = Inst.getOperand(2);
2219 if (!Opnd.isImm())
2220 return Error(IDLoc, "expected immediate operand kind");
2221 Imm = Opnd.getImm();
2222 if (Imm < 0 || Imm > 15)
2223 return Error(IDLoc, "immediate operand value out of range");
2224 break;
2225 case Mips::LHU16_MM:
2226 case Mips::SH16_MM:
2227 case Mips::SH16_MMR6:
2228 Opnd = Inst.getOperand(2);
2229 if (!Opnd.isImm())
2230 return Error(IDLoc, "expected immediate operand kind");
2231 Imm = Opnd.getImm();
2232 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2233 return Error(IDLoc, "immediate operand value out of range");
2234 break;
2235 case Mips::LW16_MM:
2236 case Mips::SW16_MM:
2237 case Mips::SW16_MMR6:
2238 Opnd = Inst.getOperand(2);
2239 if (!Opnd.isImm())
2240 return Error(IDLoc, "expected immediate operand kind");
2241 Imm = Opnd.getImm();
2242 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2243 return Error(IDLoc, "immediate operand value out of range");
2244 break;
2245 case Mips::ADDIUPC_MM:
2246 Opnd = Inst.getOperand(1);
2247 if (!Opnd.isImm())
2248 return Error(IDLoc, "expected immediate operand kind");
2249 Imm = Opnd.getImm();
2250 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2251 return Error(IDLoc, "immediate operand value out of range");
2252 break;
2253 case Mips::LWP_MM:
2254 case Mips::SWP_MM:
2255 if (Inst.getOperand(0).getReg() == Mips::RA)
2256 return Error(IDLoc, "invalid operand for instruction");
2257 break;
2258 case Mips::MOVEP_MM:
2259 case Mips::MOVEP_MMR6: {
2260 MCRegister R0 = Inst.getOperand(0).getReg();
2261 MCRegister R1 = Inst.getOperand(1).getReg();
2262 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2263 (R0 == Mips::A1 && R1 == Mips::A3) ||
2264 (R0 == Mips::A2 && R1 == Mips::A3) ||
2265 (R0 == Mips::A0 && R1 == Mips::S5) ||
2266 (R0 == Mips::A0 && R1 == Mips::S6) ||
2267 (R0 == Mips::A0 && R1 == Mips::A1) ||
2268 (R0 == Mips::A0 && R1 == Mips::A2) ||
2269 (R0 == Mips::A0 && R1 == Mips::A3));
2270 if (!RegPair)
2271 return Error(IDLoc, "invalid operand for instruction");
2272 break;
2273 }
2274 }
2275 }
2276
2277 bool FillDelaySlot =
2278 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2279
2280 // Get previous instruction`s forbidden slot attribute and
2281 // whether set reorder.
2282 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2283
2284 // Flag represents we set reorder after nop.
2285 bool SetReorderAfterNop = false;
2286
2287 // If previous instruction has forbidden slot and .set reorder
2288 // is active and current instruction is CTI.
2289 // Then emit a NOP after it.
2290 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2291 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2292 // When 'FillDelaySlot' is true, the existing logic will add
2293 // noreorder before instruction and reorder after it. So there
2294 // need exclude this case avoiding two '.set reorder'.
2295 // The format of the first case is:
2296 // .set noreorder
2297 // bnezc
2298 // nop
2299 // .set reorder
2300 if (AssemblerOptions.back()->isReorder() && !FillDelaySlot) {
2301 SetReorderAfterNop = true;
2303 }
2304 }
2305
2306 // Save current instruction`s forbidden slot and whether set reorder.
2307 // This is the judgment condition for whether to add nop.
2308 // We would add a couple of '.set noreorder' and '.set reorder' to
2309 // wrap the current instruction and the next instruction.
2310 CurForbiddenSlotAttr =
2311 hasForbiddenSlot(MCID) && AssemblerOptions.back()->isReorder();
2312
2313 if (FillDelaySlot || CurForbiddenSlotAttr)
2315
2316 MacroExpanderResultTy ExpandResult =
2317 tryExpandInstruction(Inst, IDLoc, Out, STI);
2318 switch (ExpandResult) {
2319 case MER_NotAMacro:
2320 Out.emitInstruction(Inst, *STI);
2321 break;
2322 case MER_Success:
2323 break;
2324 case MER_Fail:
2325 return true;
2326 }
2327
2328 // When current instruction was not CTI, recover reorder state.
2329 // The format of the second case is:
2330 // .set noreoder
2331 // bnezc
2332 // add
2333 // .set reorder
2334 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2335 AssemblerOptions.back()->isReorder()) {
2337 }
2338
2339 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2340 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2341 if (inMicroMipsMode()) {
2342 TOut.setUsesMicroMips();
2343 TOut.updateABIInfo(*this);
2344 }
2345
2346 // If this instruction has a delay slot and .set reorder is active,
2347 // emit a NOP after it.
2348 // The format of the third case is:
2349 // .set noreorder
2350 // bnezc
2351 // nop
2352 // .set noreorder
2353 // j
2354 // nop
2355 // .set reorder
2356 if (FillDelaySlot) {
2357 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2359 }
2360
2361 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2362 ExpandedJalSym) &&
2363 isPicAndNotNxxAbi()) {
2364 if (IsCpRestoreSet) {
2365 // We need a NOP between the JALR and the LW:
2366 // If .set reorder has been used, we've already emitted a NOP.
2367 // If .set noreorder has been used, we need to emit a NOP at this point.
2368 if (!AssemblerOptions.back()->isReorder())
2369 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2370 STI);
2371
2372 // Load the $gp from the stack.
2373 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2374 } else
2375 Warning(IDLoc, "no .cprestore used in PIC mode");
2376 }
2377
2378 return false;
2379}
2380
2381void MipsAsmParser::onEndOfFile() {
2382 MipsTargetStreamer &TOut = getTargetStreamer();
2383 SMLoc IDLoc = SMLoc();
2384 // If has pending forbidden slot, fill nop and recover reorder.
2385 if (CurForbiddenSlotAttr) {
2386 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2387 if (AssemblerOptions.back()->isReorder())
2389 }
2390}
2391
2392MipsAsmParser::MacroExpanderResultTy
2393MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2394 const MCSubtargetInfo *STI) {
2395 switch (Inst.getOpcode()) {
2396 default:
2397 return MER_NotAMacro;
2398 case Mips::LoadImm32:
2399 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2400 case Mips::LoadImm64:
2401 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2402 case Mips::LoadAddrImm32:
2403 case Mips::LoadAddrImm64:
2404 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2405 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2406 "expected immediate operand kind");
2407
2408 return expandLoadAddress(
2409 Inst.getOperand(0).getReg(), MCRegister(), Inst.getOperand(1),
2410 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2411 ? MER_Fail
2412 : MER_Success;
2413 case Mips::LoadAddrReg32:
2414 case Mips::LoadAddrReg64:
2415 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2416 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2417 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2418 "expected immediate operand kind");
2419
2420 return expandLoadAddress(Inst.getOperand(0).getReg(),
2421 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2422 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2423 Out, STI)
2424 ? MER_Fail
2425 : MER_Success;
2426 case Mips::B_MM_Pseudo:
2427 case Mips::B_MMR6_Pseudo:
2428 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2429 : MER_Success;
2430 case Mips::SWM_MM:
2431 case Mips::LWM_MM:
2432 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2433 : MER_Success;
2434 case Mips::JalOneReg:
2435 case Mips::JalTwoReg:
2436 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2437 case Mips::BneImm:
2438 case Mips::BeqImm:
2439 case Mips::BEQLImmMacro:
2440 case Mips::BNELImmMacro:
2441 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2442 case Mips::BLT:
2443 case Mips::BLE:
2444 case Mips::BGE:
2445 case Mips::BGT:
2446 case Mips::BLTU:
2447 case Mips::BLEU:
2448 case Mips::BGEU:
2449 case Mips::BGTU:
2450 case Mips::BLTL:
2451 case Mips::BLEL:
2452 case Mips::BGEL:
2453 case Mips::BGTL:
2454 case Mips::BLTUL:
2455 case Mips::BLEUL:
2456 case Mips::BGEUL:
2457 case Mips::BGTUL:
2458 case Mips::BLTImmMacro:
2459 case Mips::BLEImmMacro:
2460 case Mips::BGEImmMacro:
2461 case Mips::BGTImmMacro:
2462 case Mips::BLTUImmMacro:
2463 case Mips::BLEUImmMacro:
2464 case Mips::BGEUImmMacro:
2465 case Mips::BGTUImmMacro:
2466 case Mips::BLTLImmMacro:
2467 case Mips::BLELImmMacro:
2468 case Mips::BGELImmMacro:
2469 case Mips::BGTLImmMacro:
2470 case Mips::BLTULImmMacro:
2471 case Mips::BLEULImmMacro:
2472 case Mips::BGEULImmMacro:
2473 case Mips::BGTULImmMacro:
2474 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2475 case Mips::SDivMacro:
2476 case Mips::SDivIMacro:
2477 case Mips::SRemMacro:
2478 case Mips::SRemIMacro:
2479 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2480 : MER_Success;
2481 case Mips::DSDivMacro:
2482 case Mips::DSDivIMacro:
2483 case Mips::DSRemMacro:
2484 case Mips::DSRemIMacro:
2485 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2486 : MER_Success;
2487 case Mips::UDivMacro:
2488 case Mips::UDivIMacro:
2489 case Mips::URemMacro:
2490 case Mips::URemIMacro:
2491 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2492 : MER_Success;
2493 case Mips::DUDivMacro:
2494 case Mips::DUDivIMacro:
2495 case Mips::DURemMacro:
2496 case Mips::DURemIMacro:
2497 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2498 : MER_Success;
2499 case Mips::PseudoTRUNC_W_S:
2500 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2501 : MER_Success;
2502 case Mips::PseudoTRUNC_W_D32:
2503 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2504 : MER_Success;
2505 case Mips::PseudoTRUNC_W_D:
2506 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2507 : MER_Success;
2508
2509 case Mips::LoadImmSingleGPR:
2510 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2511 : MER_Success;
2512 case Mips::LoadImmSingleFGR:
2513 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2514 : MER_Success;
2515 case Mips::LoadImmDoubleGPR:
2516 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2517 : MER_Success;
2518 case Mips::LoadImmDoubleFGR:
2519 return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2520 : MER_Success;
2521 case Mips::LoadImmDoubleFGR_32:
2522 return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2523 : MER_Success;
2524
2525 case Mips::Ulh:
2526 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2527 case Mips::Ulhu:
2528 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2529 case Mips::Ush:
2530 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2531 case Mips::Ulw:
2532 case Mips::Usw:
2533 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534 case Mips::NORImm:
2535 case Mips::NORImm64:
2536 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537 case Mips::SGE:
2538 case Mips::SGEU:
2539 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2540 case Mips::SGEImm:
2541 case Mips::SGEUImm:
2542 case Mips::SGEImm64:
2543 case Mips::SGEUImm64:
2544 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545 case Mips::SGTImm:
2546 case Mips::SGTUImm:
2547 case Mips::SGTImm64:
2548 case Mips::SGTUImm64:
2549 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2550 case Mips::SLE:
2551 case Mips::SLEU:
2552 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2553 case Mips::SLEImm:
2554 case Mips::SLEUImm:
2555 case Mips::SLEImm64:
2556 case Mips::SLEUImm64:
2557 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2558 case Mips::SLTImm64:
2559 if (isInt<16>(Inst.getOperand(2).getImm())) {
2560 Inst.setOpcode(Mips::SLTi64);
2561 return MER_NotAMacro;
2562 }
2563 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564 case Mips::SLTUImm64:
2565 if (isInt<16>(Inst.getOperand(2).getImm())) {
2566 Inst.setOpcode(Mips::SLTiu64);
2567 return MER_NotAMacro;
2568 }
2569 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2570 case Mips::ADDi: case Mips::ADDi_MM:
2571 case Mips::ADDiu: case Mips::ADDiu_MM:
2572 case Mips::SLTi: case Mips::SLTi_MM:
2573 case Mips::SLTiu: case Mips::SLTiu_MM:
2574 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2575 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2576 int64_t ImmValue = Inst.getOperand(2).getImm();
2577 if (isInt<16>(ImmValue))
2578 return MER_NotAMacro;
2579 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2580 : MER_Success;
2581 }
2582 return MER_NotAMacro;
2583 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2584 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2585 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2586 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2587 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2588 int64_t ImmValue = Inst.getOperand(2).getImm();
2589 if (isUInt<16>(ImmValue))
2590 return MER_NotAMacro;
2591 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2592 : MER_Success;
2593 }
2594 return MER_NotAMacro;
2595 case Mips::ROL:
2596 case Mips::ROR:
2597 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2598 case Mips::ROLImm:
2599 case Mips::RORImm:
2600 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2601 case Mips::DROL:
2602 case Mips::DROR:
2603 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604 case Mips::DROLImm:
2605 case Mips::DRORImm:
2606 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607 case Mips::ABSMacro:
2608 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2609 case Mips::MULImmMacro:
2610 case Mips::DMULImmMacro:
2611 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2612 case Mips::MULOMacro:
2613 case Mips::DMULOMacro:
2614 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 case Mips::MULOUMacro:
2616 case Mips::DMULOUMacro:
2617 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2618 case Mips::DMULMacro:
2619 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2620 case Mips::LDMacro:
2621 case Mips::SDMacro:
2622 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2623 Inst.getOpcode() == Mips::LDMacro)
2624 ? MER_Fail
2625 : MER_Success;
2626 case Mips::SDC1_M1:
2627 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2628 ? MER_Fail
2629 : MER_Success;
2630 case Mips::SEQMacro:
2631 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2632 case Mips::SEQIMacro:
2633 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2634 case Mips::SNEMacro:
2635 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2636 case Mips::SNEIMacro:
2637 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2638 case Mips::MFTC0: case Mips::MTTC0:
2639 case Mips::MFTGPR: case Mips::MTTGPR:
2640 case Mips::MFTLO: case Mips::MTTLO:
2641 case Mips::MFTHI: case Mips::MTTHI:
2642 case Mips::MFTACX: case Mips::MTTACX:
2643 case Mips::MFTDSP: case Mips::MTTDSP:
2644 case Mips::MFTC1: case Mips::MTTC1:
2645 case Mips::MFTHC1: case Mips::MTTHC1:
2646 case Mips::CFTC1: case Mips::CTTC1:
2647 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2648 case Mips::SaaAddr:
2649 case Mips::SaadAddr:
2650 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651 }
2652}
2653
2654bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2655 MCStreamer &Out,
2656 const MCSubtargetInfo *STI) {
2657 MipsTargetStreamer &TOut = getTargetStreamer();
2658
2659 // Create a JALR instruction which is going to replace the pseudo-JAL.
2660 MCInst JalrInst;
2661 JalrInst.setLoc(IDLoc);
2662 const MCOperand FirstRegOp = Inst.getOperand(0);
2663 const unsigned Opcode = Inst.getOpcode();
2664
2665 if (Opcode == Mips::JalOneReg) {
2666 // jal $rs => jalr $rs
2667 if (IsCpRestoreSet && inMicroMipsMode()) {
2668 JalrInst.setOpcode(Mips::JALRS16_MM);
2669 JalrInst.addOperand(FirstRegOp);
2670 } else if (inMicroMipsMode()) {
2671 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2672 JalrInst.addOperand(FirstRegOp);
2673 } else {
2674 JalrInst.setOpcode(Mips::JALR);
2675 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2676 JalrInst.addOperand(FirstRegOp);
2677 }
2678 } else if (Opcode == Mips::JalTwoReg) {
2679 // jal $rd, $rs => jalr $rd, $rs
2680 if (IsCpRestoreSet && inMicroMipsMode())
2681 JalrInst.setOpcode(Mips::JALRS_MM);
2682 else
2683 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2684 JalrInst.addOperand(FirstRegOp);
2685 const MCOperand SecondRegOp = Inst.getOperand(1);
2686 JalrInst.addOperand(SecondRegOp);
2687 }
2688 Out.emitInstruction(JalrInst, *STI);
2689
2690 // If .set reorder is active and branch instruction has a delay slot,
2691 // emit a NOP after it.
2692 const MCInstrDesc &MCID = MII.get(JalrInst.getOpcode());
2693 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2694 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2695 STI);
2696
2697 return false;
2698}
2699
2700/// Can the value be represented by a unsigned N-bit value and a shift left?
2701template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2702 return x && isUInt<N>(x >> llvm::countr_zero(x));
2703}
2704
2705/// Load (or add) an immediate into a register.
2706///
2707/// @param ImmValue The immediate to load.
2708/// @param DstReg The register that will hold the immediate.
2709/// @param SrcReg A register to add to the immediate or MCRegister()
2710/// for a simple initialization.
2711/// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2712/// @param IsAddress True if the immediate represents an address. False if it
2713/// is an integer.
2714/// @param IDLoc Location of the immediate in the source file.
2715bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2716 MCRegister SrcReg, bool Is32BitImm,
2717 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2718 const MCSubtargetInfo *STI) {
2719 MipsTargetStreamer &TOut = getTargetStreamer();
2720
2721 if (!Is32BitImm && !isGP64bit()) {
2722 Error(IDLoc, "instruction requires a 64-bit architecture");
2723 return true;
2724 }
2725
2726 if (Is32BitImm) {
2727 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2728 // Sign extend up to 64-bit so that the predicates match the hardware
2729 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2730 // true.
2731 ImmValue = SignExtend64<32>(ImmValue);
2732 } else {
2733 Error(IDLoc, "instruction requires a 32-bit immediate");
2734 return true;
2735 }
2736 }
2737
2738 MCRegister ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2739 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2740
2741 bool UseSrcReg = false;
2742 if (SrcReg)
2743 UseSrcReg = true;
2744
2745 MCRegister TmpReg = DstReg;
2746 if (UseSrcReg &&
2747 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2748 // At this point we need AT to perform the expansions and we exit if it is
2749 // not available.
2750 MCRegister ATReg = getATReg(IDLoc);
2751 if (!ATReg)
2752 return true;
2753 TmpReg = ATReg;
2754 }
2755
2756 if (isInt<16>(ImmValue)) {
2757 if (!UseSrcReg)
2758 SrcReg = ZeroReg;
2759
2760 // This doesn't quite follow the usual ABI expectations for N32 but matches
2761 // traditional assembler behaviour. N32 would normally use addiu for both
2762 // integers and addresses.
2763 if (IsAddress && !Is32BitImm) {
2764 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2765 return false;
2766 }
2767
2768 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2769 return false;
2770 }
2771
2772 if (isUInt<16>(ImmValue)) {
2773 MCRegister TmpReg = DstReg;
2774 if (SrcReg == DstReg) {
2775 TmpReg = getATReg(IDLoc);
2776 if (!TmpReg)
2777 return true;
2778 }
2779
2780 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2781 if (UseSrcReg)
2782 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2783 return false;
2784 }
2785
2786 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2787 warnIfNoMacro(IDLoc);
2788
2789 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2790 uint16_t Bits15To0 = ImmValue & 0xffff;
2791 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2792 // Traditional behaviour seems to special case this particular value. It's
2793 // not clear why other masks are handled differently.
2794 if (ImmValue == 0xffffffff) {
2795 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2796 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2797 if (UseSrcReg)
2798 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2799 return false;
2800 }
2801
2802 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2803 // upper 32 bits.
2804 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2805 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2806 if (Bits15To0)
2807 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2808 if (UseSrcReg)
2809 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2810 return false;
2811 }
2812
2813 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2814 if (Bits15To0)
2815 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2816 if (UseSrcReg)
2817 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2818 return false;
2819 }
2820
2821 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2822 if (Is32BitImm) {
2823 Error(IDLoc, "instruction requires a 32-bit immediate");
2824 return true;
2825 }
2826
2827 // We've processed ImmValue satisfying isUInt<16> above, so ImmValue must be
2828 // at least 17-bit wide here.
2829 unsigned BitWidth = llvm::bit_width((uint64_t)ImmValue);
2830 assert(BitWidth >= 17 && "ImmValue must be at least 17-bit wide");
2831
2832 // Traditionally, these immediates are shifted as little as possible and as
2833 // such we align the most significant bit to bit 15 of our temporary.
2834 unsigned ShiftAmount = BitWidth - 16;
2835 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2836 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2837 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2838
2839 if (UseSrcReg)
2840 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2841
2842 return false;
2843 }
2844
2845 warnIfNoMacro(IDLoc);
2846
2847 // The remaining case is packed with a sequence of dsll and ori with zeros
2848 // being omitted and any neighbouring dsll's being coalesced.
2849 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2850
2851 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2852 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(), true, false, IDLoc,
2853 Out, STI))
2854 return false;
2855
2856 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2857 // skip it and defer the shift to the next chunk.
2858 unsigned ShiftCarriedForwards = 16;
2859 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2860 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2861
2862 if (ImmChunk != 0) {
2863 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2864 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2865 ShiftCarriedForwards = 0;
2866 }
2867
2868 ShiftCarriedForwards += 16;
2869 }
2870 ShiftCarriedForwards -= 16;
2871
2872 // Finish any remaining shifts left by trailing zeros.
2873 if (ShiftCarriedForwards)
2874 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2875
2876 if (UseSrcReg)
2877 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2878
2879 return false;
2880}
2881
2882bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2883 MCStreamer &Out, const MCSubtargetInfo *STI) {
2884 const MCOperand &ImmOp = Inst.getOperand(1);
2885 assert(ImmOp.isImm() && "expected immediate operand kind");
2886 const MCOperand &DstRegOp = Inst.getOperand(0);
2887 assert(DstRegOp.isReg() && "expected register operand kind");
2888
2889 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), MCRegister(), Is32BitImm,
2890 false, IDLoc, Out, STI))
2891 return true;
2892
2893 return false;
2894}
2895
2896bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2897 const MCOperand &Offset,
2898 bool Is32BitAddress, SMLoc IDLoc,
2899 MCStreamer &Out,
2900 const MCSubtargetInfo *STI) {
2901 // la can't produce a usable address when addresses are 64-bit.
2902 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2903 Warning(IDLoc, "la used to load 64-bit address");
2904 // Continue as if we had 'dla' instead.
2905 Is32BitAddress = false;
2906 }
2907
2908 // dla requires 64-bit addresses.
2909 if (!Is32BitAddress && !hasMips3()) {
2910 Error(IDLoc, "instruction requires a 64-bit architecture");
2911 return true;
2912 }
2913
2914 if (!Offset.isImm())
2915 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2916 Is32BitAddress, IDLoc, Out, STI);
2917
2918 if (!ABI.ArePtrs64bit()) {
2919 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2920 Is32BitAddress = true;
2921 }
2922
2923 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2924 IDLoc, Out, STI);
2925}
2926
2927bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2928 MCRegister DstReg,
2929 MCRegister SrcReg, bool Is32BitSym,
2930 SMLoc IDLoc, MCStreamer &Out,
2931 const MCSubtargetInfo *STI) {
2932 MipsTargetStreamer &TOut = getTargetStreamer();
2933 bool UseSrcReg =
2934 SrcReg.isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2935 warnIfNoMacro(IDLoc);
2936
2937 if (inPicMode()) {
2938 MCValue Res;
2939 if (!SymExpr->evaluateAsRelocatable(Res, nullptr)) {
2940 Error(IDLoc, "expected relocatable expression");
2941 return true;
2942 }
2943 if (Res.getSubSym()) {
2944 Error(IDLoc, "expected relocatable expression with only one symbol");
2945 return true;
2946 }
2947
2948 bool IsPtr64 = ABI.ArePtrs64bit();
2949 bool IsLocalSym =
2950 Res.getAddSym()->isInSection() || Res.getAddSym()->isTemporary() ||
2951 (getContext().isELF() &&
2952 static_cast<const MCSymbolELF *>(Res.getAddSym())->getBinding() ==
2954 // For O32, "$"-prefixed symbols are recognized as temporary while
2955 // .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
2956 // manually.
2957 if (ABI.IsO32() && Res.getAddSym()->getName().starts_with(".L"))
2958 IsLocalSym = true;
2959 bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2960
2961 // The case where the result register is $25 is somewhat special. If the
2962 // symbol in the final relocation is external and not modified with a
2963 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2964 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2965 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2966 Res.getConstant() == 0 && !IsLocalSym) {
2967 if (UseXGOT) {
2968 const MCExpr *CallHiExpr =
2970 const MCExpr *CallLoExpr =
2972 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2973 STI);
2974 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2975 IDLoc, STI);
2976 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2977 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2978 } else {
2979 const MCExpr *CallExpr =
2981 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2982 MCOperand::createExpr(CallExpr), IDLoc, STI);
2983 }
2984 return false;
2985 }
2986
2987 MCRegister TmpReg = DstReg;
2988 if (UseSrcReg &&
2989 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2990 SrcReg)) {
2991 // If $rs is the same as $rd, we need to use AT.
2992 // If it is not available we exit.
2993 MCRegister ATReg = getATReg(IDLoc);
2994 if (!ATReg)
2995 return true;
2996 TmpReg = ATReg;
2997 }
2998
2999 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
3000 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
3001 // FIXME: Implement XGOT for microMIPS.
3002 if (UseXGOT) {
3003 // Loading address from XGOT
3004 // External GOT: lui $tmp, %got_hi(symbol)($gp)
3005 // addu $tmp, $tmp, $gp
3006 // lw $tmp, %got_lo(symbol)($tmp)
3007 // >addiu $tmp, $tmp, offset
3008 // >addiu $rd, $tmp, $rs
3009 // The addiu's marked with a '>' may be omitted if they are redundant. If
3010 // this happens then the last instruction must use $rd as the result
3011 // register.
3012 const MCExpr *CallHiExpr =
3014 const MCExpr *CallLoExpr = MCSpecifierExpr::create(
3016
3017 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3018 STI);
3019 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3020 IDLoc, STI);
3021 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3022 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3023
3024 if (Res.getConstant() != 0)
3025 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3027 Res.getConstant(), getContext())),
3028 IDLoc, STI);
3029
3030 if (UseSrcReg)
3031 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3032 IDLoc, STI);
3033 return false;
3034 }
3035
3036 const MCSpecifierExpr *GotExpr = nullptr;
3037 const MCExpr *LoExpr = nullptr;
3038 if (ABI.IsN32() || ABI.IsN64()) {
3039 // The remaining cases are:
3040 // Small offset: ld $tmp, %got_disp(symbol)($gp)
3041 // >daddiu $tmp, $tmp, offset
3042 // >daddu $rd, $tmp, $rs
3043 // The daddiu's marked with a '>' may be omitted if they are redundant. If
3044 // this happens then the last instruction must use $rd as the result
3045 // register.
3047 getContext());
3048 if (Res.getConstant() != 0) {
3049 // Symbols fully resolve with just the %got_disp(symbol) but we
3050 // must still account for any offset to the symbol for
3051 // expressions like symbol+8.
3053
3054 // FIXME: Offsets greater than 16 bits are not yet implemented.
3055 // FIXME: The correct range is a 32-bit sign-extended number.
3056 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3057 Error(IDLoc, "macro instruction uses large offset, which is not "
3058 "currently supported");
3059 return true;
3060 }
3061 }
3062 } else {
3063 // The remaining cases are:
3064 // External GOT: lw $tmp, %got(symbol)($gp)
3065 // >addiu $tmp, $tmp, offset
3066 // >addiu $rd, $tmp, $rs
3067 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3068 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3069 // >addiu $rd, $tmp, $rs
3070 // The addiu's marked with a '>' may be omitted if they are redundant. If
3071 // this happens then the last instruction must use $rd as the result
3072 // register.
3073 if (IsLocalSym) {
3074 GotExpr = MCSpecifierExpr::create(SymExpr, Mips::S_GOT, getContext());
3075 LoExpr = MCSpecifierExpr::create(SymExpr, Mips::S_LO, getContext());
3076 } else {
3077 // External symbols fully resolve the symbol with just the %got(symbol)
3078 // but we must still account for any offset to the symbol for
3079 // expressions like symbol+8.
3080 GotExpr =
3082 if (Res.getConstant() != 0)
3084 }
3085 }
3086
3087 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3088 MCOperand::createExpr(GotExpr), IDLoc, STI);
3089
3090 if (LoExpr)
3091 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3092 MCOperand::createExpr(LoExpr), IDLoc, STI);
3093
3094 if (UseSrcReg)
3095 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3096 IDLoc, STI);
3097
3098 return false;
3099 }
3100
3101 const auto *HiExpr =
3103 const auto *LoExpr =
3105
3106 // This is the 64-bit symbol address expansion.
3107 if (ABI.ArePtrs64bit() && isGP64bit()) {
3108 // We need AT for the 64-bit expansion in the cases where the optional
3109 // source register is the destination register and for the superscalar
3110 // scheduled form.
3111 //
3112 // If it is not available we exit if the destination is the same as the
3113 // source register.
3114
3115 const auto *HighestExpr =
3117 const auto *HigherExpr =
3119
3120 bool RdRegIsRsReg =
3121 UseSrcReg &&
3122 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3123
3124 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3125 MCRegister ATReg = getATReg(IDLoc);
3126
3127 // If $rs is the same as $rd:
3128 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3129 // daddiu $at, $at, %higher(sym)
3130 // dsll $at, $at, 16
3131 // daddiu $at, $at, %hi(sym)
3132 // dsll $at, $at, 16
3133 // daddiu $at, $at, %lo(sym)
3134 // daddu $rd, $at, $rd
3135 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3136 STI);
3137 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3138 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3139 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3140 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3141 IDLoc, STI);
3142 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3143 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3144 IDLoc, STI);
3145 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3146
3147 return false;
3148 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3149 MCRegister ATReg = getATReg(IDLoc);
3150
3151 // If the $rs is different from $rd or if $rs isn't specified and we
3152 // have $at available:
3153 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3154 // lui $at, %hi(sym)
3155 // daddiu $rd, $rd, %higher(sym)
3156 // daddiu $at, $at, %lo(sym)
3157 // dsll32 $rd, $rd, 0
3158 // daddu $rd, $rd, $at
3159 // (daddu $rd, $rd, $rs)
3160 //
3161 // Which is preferred for superscalar issue.
3162 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3163 STI);
3164 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3165 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3166 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3167 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3168 IDLoc, STI);
3169 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3170 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3171 if (UseSrcReg)
3172 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3173
3174 return false;
3175 } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3176 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3177 // Otherwise, synthesize the address in the destination register
3178 // serially:
3179 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3180 // daddiu $rd, $rd, %higher(sym)
3181 // dsll $rd, $rd, 16
3182 // daddiu $rd, $rd, %hi(sym)
3183 // dsll $rd, $rd, 16
3184 // daddiu $rd, $rd, %lo(sym)
3185 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3186 STI);
3187 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3188 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3189 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3190 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3191 MCOperand::createExpr(HiExpr), IDLoc, STI);
3192 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3193 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3194 MCOperand::createExpr(LoExpr), IDLoc, STI);
3195 if (UseSrcReg)
3196 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3197
3198 return false;
3199 } else {
3200 // We have a case where SrcReg == DstReg and we don't have $at
3201 // available. We can't expand this case, so error out appropriately.
3202 assert(SrcReg == DstReg && !canUseATReg() &&
3203 "Could have expanded dla but didn't?");
3204 reportParseError(IDLoc,
3205 "pseudo-instruction requires $at, which is not available");
3206 return true;
3207 }
3208 }
3209
3210 // And now, the 32-bit symbol address expansion:
3211 // If $rs is the same as $rd:
3212 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3213 // ori $at, $at, %lo(sym)
3214 // addu $rd, $at, $rd
3215 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3216 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3217 // ori $rd, $rd, %lo(sym)
3218 // (addu $rd, $rd, $rs)
3219 MCRegister TmpReg = DstReg;
3220 if (UseSrcReg &&
3221 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3222 // If $rs is the same as $rd, we need to use AT.
3223 // If it is not available we exit.
3224 MCRegister ATReg = getATReg(IDLoc);
3225 if (!ATReg)
3226 return true;
3227 TmpReg = ATReg;
3228 }
3229
3230 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3231 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3232 IDLoc, STI);
3233
3234 if (UseSrcReg)
3235 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3236 else
3237 assert(
3238 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3239
3240 return false;
3241}
3242
3243// Each double-precision register DO-D15 overlaps with two of the single
3244// precision registers F0-F31. As an example, all of the following hold true:
3245// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3247 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3248 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3249 switch (Reg.id()) {
3250 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3251 case Mips::ZERO: return Mips::AT;
3252 case Mips::AT: return Mips::V0;
3253 case Mips::V0: return Mips::V1;
3254 case Mips::V1: return Mips::A0;
3255 case Mips::A0: return Mips::A1;
3256 case Mips::A1: return Mips::A2;
3257 case Mips::A2: return Mips::A3;
3258 case Mips::A3: return Mips::T0;
3259 case Mips::T0: return Mips::T1;
3260 case Mips::T1: return Mips::T2;
3261 case Mips::T2: return Mips::T3;
3262 case Mips::T3: return Mips::T4;
3263 case Mips::T4: return Mips::T5;
3264 case Mips::T5: return Mips::T6;
3265 case Mips::T6: return Mips::T7;
3266 case Mips::T7: return Mips::S0;
3267 case Mips::S0: return Mips::S1;
3268 case Mips::S1: return Mips::S2;
3269 case Mips::S2: return Mips::S3;
3270 case Mips::S3: return Mips::S4;
3271 case Mips::S4: return Mips::S5;
3272 case Mips::S5: return Mips::S6;
3273 case Mips::S6: return Mips::S7;
3274 case Mips::S7: return Mips::T8;
3275 case Mips::T8: return Mips::T9;
3276 case Mips::T9: return Mips::K0;
3277 case Mips::K0: return Mips::K1;
3278 case Mips::K1: return Mips::GP;
3279 case Mips::GP: return Mips::SP;
3280 case Mips::SP: return Mips::FP;
3281 case Mips::FP: return Mips::RA;
3282 case Mips::RA: return Mips::ZERO;
3283 case Mips::D0: return Mips::F1;
3284 case Mips::D1: return Mips::F3;
3285 case Mips::D2: return Mips::F5;
3286 case Mips::D3: return Mips::F7;
3287 case Mips::D4: return Mips::F9;
3288 case Mips::D5: return Mips::F11;
3289 case Mips::D6: return Mips::F13;
3290 case Mips::D7: return Mips::F15;
3291 case Mips::D8: return Mips::F17;
3292 case Mips::D9: return Mips::F19;
3293 case Mips::D10: return Mips::F21;
3294 case Mips::D11: return Mips::F23;
3295 case Mips::D12: return Mips::F25;
3296 case Mips::D13: return Mips::F27;
3297 case Mips::D14: return Mips::F29;
3298 case Mips::D15: return Mips::F31;
3299 }
3300}
3301
3302// FIXME: This method is too general. In principle we should compute the number
3303// of instructions required to synthesize the immediate inline compared to
3304// synthesizing the address inline and relying on non .text sections.
3305// For static O32 and N32 this may yield a small benefit, for static N64 this is
3306// likely to yield a much larger benefit as we have to synthesize a 64bit
3307// address to load a 64 bit value.
3308bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3309 MCSymbol *Sym) {
3310 MCRegister ATReg = getATReg(IDLoc);
3311 if (!ATReg)
3312 return true;
3313
3314 if(IsPicEnabled) {
3315 const MCExpr *GotSym = MCSymbolRefExpr::create(Sym, getContext());
3316 const auto *GotExpr =
3318
3319 if(isABI_O32() || isABI_N32()) {
3320 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3321 IDLoc, STI);
3322 } else { //isABI_N64()
3323 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3324 IDLoc, STI);
3325 }
3326 } else { //!IsPicEnabled
3327 const MCExpr *HiSym = MCSymbolRefExpr::create(Sym, getContext());
3328 const auto *HiExpr =
3330
3331 // FIXME: This is technically correct but gives a different result to gas,
3332 // but gas is incomplete there (it has a fixme noting it doesn't work with
3333 // 64-bit addresses).
3334 // FIXME: With -msym32 option, the address expansion for N64 should probably
3335 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3336 // symbol's value is considered sign extended.
3337 if(isABI_O32() || isABI_N32()) {
3338 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3339 } else { //isABI_N64()
3340 const MCExpr *HighestSym = MCSymbolRefExpr::create(Sym, getContext());
3341 const auto *HighestExpr =
3343 const MCExpr *HigherSym = MCSymbolRefExpr::create(Sym, getContext());
3344 const auto *HigherExpr =
3346
3347 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3348 STI);
3349 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3350 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3351 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3352 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3353 IDLoc, STI);
3354 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3355 }
3356 }
3357 return false;
3358}
3359
3361 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3362 // exponent field), convert it to double (e.g. 1 to 1.0)
3363 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3364 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3365 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3366 }
3367 return ImmOp64;
3368}
3369
3371 // Conversion of a double in an uint64_t to a float in a uint32_t,
3372 // retaining the bit pattern of a float.
3373 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3374 float TmpFloat = static_cast<float>(DoubleImm);
3375 return llvm::bit_cast<uint32_t>(TmpFloat);
3376}
3377
3378bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3379 MCStreamer &Out,
3380 const MCSubtargetInfo *STI) {
3381 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3382 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3383 "Invalid instruction operand.");
3384
3385 MCRegister FirstReg = Inst.getOperand(0).getReg();
3386 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3387
3388 uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3389
3390 return loadImmediate(ImmOp32, FirstReg, MCRegister(), true, false, IDLoc, Out,
3391 STI);
3392}
3393
3394bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3395 MCStreamer &Out,
3396 const MCSubtargetInfo *STI) {
3397 MipsTargetStreamer &TOut = getTargetStreamer();
3398 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3399 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3400 "Invalid instruction operand.");
3401
3402 MCRegister FirstReg = Inst.getOperand(0).getReg();
3403 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3404
3405 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3406
3407 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3408
3409 MCRegister TmpReg = Mips::ZERO;
3410 if (ImmOp32 != 0) {
3411 TmpReg = getATReg(IDLoc);
3412 if (!TmpReg)
3413 return true;
3414 }
3415
3416 if (Lo_32(ImmOp64) == 0) {
3417 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3418 true, false, IDLoc, Out, STI))
3419 return true;
3420 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3421 return false;
3422 }
3423
3424 MCSection *CS = getStreamer().getCurrentSectionOnly();
3425 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3426 // where appropriate.
3427 MCSection *ReadOnlySection =
3428 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3429
3430 MCSymbol *Sym = getContext().createTempSymbol();
3431 const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3432 const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3433
3434 getStreamer().switchSection(ReadOnlySection);
3435 getStreamer().emitLabel(Sym, IDLoc);
3436 getStreamer().emitInt32(ImmOp32);
3437 getStreamer().switchSection(CS);
3438
3439 if (emitPartialAddress(TOut, IDLoc, Sym))
3440 return true;
3441 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3442 IDLoc, STI);
3443 return false;
3444}
3445
3446bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3447 MCStreamer &Out,
3448 const MCSubtargetInfo *STI) {
3449 MipsTargetStreamer &TOut = getTargetStreamer();
3450 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3451 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3452 "Invalid instruction operand.");
3453
3454 MCRegister FirstReg = Inst.getOperand(0).getReg();
3455 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3456
3457 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3458
3459 if (Lo_32(ImmOp64) == 0) {
3460 if (isGP64bit()) {
3461 if (loadImmediate(ImmOp64, FirstReg, MCRegister(), false, false, IDLoc,
3462 Out, STI))
3463 return true;
3464 } else {
3465 if (loadImmediate(Hi_32(ImmOp64), FirstReg, MCRegister(), true, false,
3466 IDLoc, Out, STI))
3467 return true;
3468
3469 if (loadImmediate(0, nextReg(FirstReg), MCRegister(), true, false, IDLoc,
3470 Out, STI))
3471 return true;
3472 }
3473 return false;
3474 }
3475
3476 MCSection *CS = getStreamer().getCurrentSectionOnly();
3477 MCSection *ReadOnlySection =
3478 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3479
3480 MCSymbol *Sym = getContext().createTempSymbol();
3481 const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3482 const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3483
3484 getStreamer().switchSection(ReadOnlySection);
3485 getStreamer().emitLabel(Sym, IDLoc);
3486 getStreamer().emitValueToAlignment(Align(8));
3487 getStreamer().emitIntValue(ImmOp64, 8);
3488 getStreamer().switchSection(CS);
3489
3490 MCRegister TmpReg = getATReg(IDLoc);
3491 if (!TmpReg)
3492 return true;
3493
3494 if (emitPartialAddress(TOut, IDLoc, Sym))
3495 return true;
3496
3497 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3498 MCOperand::createExpr(LoExpr), IDLoc, STI);
3499
3500 if (isGP64bit())
3501 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3502 else {
3503 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3504 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3505 }
3506 return false;
3507}
3508
3509bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3510 SMLoc IDLoc, MCStreamer &Out,
3511 const MCSubtargetInfo *STI) {
3512 MipsTargetStreamer &TOut = getTargetStreamer();
3513 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3514 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3515 "Invalid instruction operand.");
3516
3517 MCRegister FirstReg = Inst.getOperand(0).getReg();
3518 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3519
3520 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3521
3522 MCRegister TmpReg = Mips::ZERO;
3523 if (ImmOp64 != 0) {
3524 TmpReg = getATReg(IDLoc);
3525 if (!TmpReg)
3526 return true;
3527 }
3528
3529 if ((Lo_32(ImmOp64) == 0) &&
3530 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3531 if (isGP64bit()) {
3532 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3533 false, false, IDLoc, Out, STI))
3534 return true;
3535 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3536 return false;
3537 }
3538
3539 if (TmpReg != Mips::ZERO &&
3540 loadImmediate(Hi_32(ImmOp64), TmpReg, MCRegister(), true, false, IDLoc,
3541 Out, STI))
3542 return true;
3543
3544 if (hasMips32r2()) {
3545 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3546 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3547 } else {
3548 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3549 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3550 }
3551 return false;
3552 }
3553
3554 MCSection *CS = getStreamer().getCurrentSectionOnly();
3555 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3556 // where appropriate.
3557 MCSection *ReadOnlySection =
3558 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3559
3560 MCSymbol *Sym = getContext().createTempSymbol();
3561 const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3562 const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3563
3564 getStreamer().switchSection(ReadOnlySection);
3565 getStreamer().emitLabel(Sym, IDLoc);
3566 getStreamer().emitValueToAlignment(Align(8));
3567 getStreamer().emitIntValue(ImmOp64, 8);
3568 getStreamer().switchSection(CS);
3569
3570 if (emitPartialAddress(TOut, IDLoc, Sym))
3571 return true;
3572
3573 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3574 MCOperand::createExpr(LoExpr), IDLoc, STI);
3575
3576 return false;
3577}
3578
3579bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3580 MCStreamer &Out,
3581 const MCSubtargetInfo *STI) {
3582 MipsTargetStreamer &TOut = getTargetStreamer();
3583
3584 assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 &&
3585 "unexpected number of operands");
3586
3587 MCOperand Offset = Inst.getOperand(0);
3588 if (Offset.isExpr()) {
3589 Inst.clear();
3590 Inst.setOpcode(Mips::BEQ_MM);
3591 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3592 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3593 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3594 } else {
3595 assert(Offset.isImm() && "expected immediate operand kind");
3596 if (isInt<11>(Offset.getImm())) {
3597 // If offset fits into 11 bits then this instruction becomes microMIPS
3598 // 16-bit unconditional branch instruction.
3599 if (inMicroMipsMode())
3600 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3601 } else {
3602 if (!isInt<17>(Offset.getImm()))
3603 return Error(IDLoc, "branch target out of range");
3604 if (offsetToAlignment(Offset.getImm(), Align(2)))
3605 return Error(IDLoc, "branch to misaligned address");
3606 Inst.clear();
3607 Inst.setOpcode(Mips::BEQ_MM);
3608 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3609 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3610 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3611 }
3612 }
3613 Out.emitInstruction(Inst, *STI);
3614
3615 // If .set reorder is active and branch instruction has a delay slot,
3616 // emit a NOP after it.
3617 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3618 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3619 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3620
3621 return false;
3622}
3623
3624bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3625 const MCSubtargetInfo *STI) {
3626 MipsTargetStreamer &TOut = getTargetStreamer();
3627 const MCOperand &DstRegOp = Inst.getOperand(0);
3628 assert(DstRegOp.isReg() && "expected register operand kind");
3629
3630 const MCOperand &ImmOp = Inst.getOperand(1);
3631 assert(ImmOp.isImm() && "expected immediate operand kind");
3632
3633 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3634 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3635 "expected immediate or expression operand");
3636
3637 bool IsLikely = false;
3638
3639 unsigned OpCode = 0;
3640 switch(Inst.getOpcode()) {
3641 case Mips::BneImm:
3642 OpCode = Mips::BNE;
3643 break;
3644 case Mips::BeqImm:
3645 OpCode = Mips::BEQ;
3646 break;
3647 case Mips::BEQLImmMacro:
3648 OpCode = Mips::BEQL;
3649 IsLikely = true;
3650 break;
3651 case Mips::BNELImmMacro:
3652 OpCode = Mips::BNEL;
3653 IsLikely = true;
3654 break;
3655 default:
3656 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3657 break;
3658 }
3659
3660 int64_t ImmValue = ImmOp.getImm();
3661 if (ImmValue == 0) {
3662 if (IsLikely) {
3663 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3664 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3665 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3666 } else
3667 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3668 STI);
3669 } else {
3670 warnIfNoMacro(IDLoc);
3671
3672 MCRegister ATReg = getATReg(IDLoc);
3673 if (!ATReg)
3674 return true;
3675
3676 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(), true, IDLoc,
3677 Out, STI))
3678 return true;
3679
3680 if (IsLikely) {
3681 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3682 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3683 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3684 } else
3685 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3686 }
3687 return false;
3688}
3689
3690void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3691 const MCSubtargetInfo *STI, bool IsLoad) {
3692 unsigned NumOp = Inst.getNumOperands();
3693 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3694 unsigned StartOp = NumOp == 3 ? 0 : 1;
3695
3696 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3697 assert(DstRegOp.isReg() && "expected register operand kind");
3698 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3699 assert(BaseRegOp.isReg() && "expected register operand kind");
3700 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3701
3702 MipsTargetStreamer &TOut = getTargetStreamer();
3703 unsigned OpCode = Inst.getOpcode();
3704 MCRegister DstReg = DstRegOp.getReg();
3705 MCRegister BaseReg = BaseRegOp.getReg();
3706 MCRegister TmpReg = DstReg;
3707
3708 const MCInstrDesc &Desc = MII.get(OpCode);
3709 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3710 unsigned DstRegClassID =
3711 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3712 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3713 (DstRegClassID == Mips::GPR64RegClassID);
3714
3715 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3716 // At this point we need AT to perform the expansions
3717 // and we exit if it is not available.
3718 TmpReg = getATReg(IDLoc);
3719 if (!TmpReg)
3720 return;
3721 }
3722
3723 auto emitInstWithOffset = [&](const MCOperand &Off) {
3724 if (NumOp == 3)
3725 TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3726 else
3727 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3728 };
3729
3730 if (OffsetOp.isImm()) {
3731 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3732 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3733
3734 // If msb of LoOffset is 1(negative number) we must increment
3735 // HiOffset to account for the sign-extension of the low part.
3736 if (LoOffset & 0x8000)
3737 HiOffset += 0x10000;
3738
3739 bool IsLargeOffset = HiOffset != 0;
3740
3741 if (IsLargeOffset) {
3742 bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3743 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm, true, IDLoc,
3744 Out, STI))
3745 return;
3746 }
3747
3748 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3749 TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3750 TmpReg, BaseReg, IDLoc, STI);
3751 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3752 return;
3753 }
3754
3755 if (OffsetOp.isExpr()) {
3756 if (inPicMode()) {
3757 // FIXME:
3758 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3759 // do not exceed 16-bit.
3760 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3761 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3762 // of GOT entries.
3763 MCValue Res;
3764 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr)) {
3765 Error(IDLoc, "expected relocatable expression");
3766 return;
3767 }
3768 if (Res.getSubSym()) {
3769 Error(IDLoc, "expected relocatable expression with only one symbol");
3770 return;
3771 }
3772
3773 loadAndAddSymbolAddress(
3775 BaseReg, !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3776 emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3777 } else {
3778 // FIXME: Implement 64-bit case.
3779 // 1) lw $8, sym => lui $8, %hi(sym)
3780 // lw $8, %lo(sym)($8)
3781 // 2) sw $8, sym => lui $at, %hi(sym)
3782 // sw $8, %lo(sym)($at)
3783 const MCExpr *OffExpr = OffsetOp.getExpr();
3784 MCOperand LoOperand = MCOperand::createExpr(
3786 MCOperand HiOperand = MCOperand::createExpr(
3788
3789 if (ABI.IsN64()) {
3790 MCOperand HighestOperand = MCOperand::createExpr(
3792 MCOperand HigherOperand = MCOperand::createExpr(
3794
3795 TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3796 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3797 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3798 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3799 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3800 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3801 TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3802 emitInstWithOffset(LoOperand);
3803 } else {
3804 // Generate the base address in TmpReg.
3805 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3806 if (BaseReg != Mips::ZERO)
3807 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3808 // Emit the load or store with the adjusted base and offset.
3809 emitInstWithOffset(LoOperand);
3810 }
3811 }
3812 return;
3813 }
3814
3815 llvm_unreachable("unexpected operand type");
3816}
3817
3818void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3819 const MCSubtargetInfo *STI, bool IsLoad) {
3820 unsigned NumOp = Inst.getNumOperands();
3821 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3822 unsigned StartOp = NumOp == 3 ? 0 : 1;
3823
3824 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3825 assert(DstRegOp.isReg() && "expected register operand kind");
3826 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3827 assert(BaseRegOp.isReg() && "expected register operand kind");
3828 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3829
3830 MipsTargetStreamer &TOut = getTargetStreamer();
3831 unsigned OpCode = Inst.getOpcode();
3832 MCRegister DstReg = DstRegOp.getReg();
3833 MCRegister BaseReg = BaseRegOp.getReg();
3834 MCRegister TmpReg = DstReg;
3835
3836 const MCInstrDesc &Desc = MII.get(OpCode);
3837 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3838 unsigned DstRegClassID =
3839 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3840 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3841 (DstRegClassID == Mips::GPR64RegClassID);
3842
3843 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3844 // At this point we need AT to perform the expansions
3845 // and we exit if it is not available.
3846 TmpReg = getATReg(IDLoc);
3847 if (!TmpReg)
3848 return;
3849 }
3850
3851 auto emitInst = [&]() {
3852 if (NumOp == 3)
3853 TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3854 else
3855 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3856 IDLoc, STI);
3857 };
3858
3859 if (OffsetOp.isImm()) {
3860 loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3861 IDLoc, Out, STI);
3862 emitInst();
3863 return;
3864 }
3865
3866 if (OffsetOp.isExpr()) {
3867 loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3868 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3869 emitInst();
3870 return;
3871 }
3872
3873 llvm_unreachable("unexpected operand type");
3874}
3875
3876bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3877 MCStreamer &Out,
3878 const MCSubtargetInfo *STI) {
3879 unsigned OpNum = Inst.getNumOperands();
3880 unsigned Opcode = Inst.getOpcode();
3881 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3882
3883 assert(Inst.getOperand(OpNum - 1).isImm() &&
3884 Inst.getOperand(OpNum - 2).isReg() &&
3885 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3886
3887 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3888 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3889 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3890 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3891 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3892 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3893 // It can be implemented as SWM16 or LWM16 instruction.
3894 if (inMicroMipsMode() && hasMips32r6())
3895 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3896 else
3897 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3898 }
3899
3900 Inst.setOpcode(NewOpcode);
3901 Out.emitInstruction(Inst, *STI);
3902 return false;
3903}
3904
3905bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3906 MCStreamer &Out,
3907 const MCSubtargetInfo *STI) {
3908 MipsTargetStreamer &TOut = getTargetStreamer();
3909 bool EmittedNoMacroWarning = false;
3910 unsigned PseudoOpcode = Inst.getOpcode();
3911 MCRegister SrcReg = Inst.getOperand(0).getReg();
3912 const MCOperand &TrgOp = Inst.getOperand(1);
3913 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3914
3915 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3916 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3917
3918 MCRegister TrgReg;
3919 if (TrgOp.isReg())
3920 TrgReg = TrgOp.getReg();
3921 else if (TrgOp.isImm()) {
3922 warnIfNoMacro(IDLoc);
3923 EmittedNoMacroWarning = true;
3924
3925 TrgReg = getATReg(IDLoc);
3926 if (!TrgReg)
3927 return true;
3928
3929 switch(PseudoOpcode) {
3930 default:
3931 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3932 case Mips::BLTImmMacro:
3933 PseudoOpcode = Mips::BLT;
3934 break;
3935 case Mips::BLEImmMacro:
3936 PseudoOpcode = Mips::BLE;
3937 break;
3938 case Mips::BGEImmMacro:
3939 PseudoOpcode = Mips::BGE;
3940 break;
3941 case Mips::BGTImmMacro:
3942 PseudoOpcode = Mips::BGT;
3943 break;
3944 case Mips::BLTUImmMacro:
3945 PseudoOpcode = Mips::BLTU;
3946 break;
3947 case Mips::BLEUImmMacro:
3948 PseudoOpcode = Mips::BLEU;
3949 break;
3950 case Mips::BGEUImmMacro:
3951 PseudoOpcode = Mips::BGEU;
3952 break;
3953 case Mips::BGTUImmMacro:
3954 PseudoOpcode = Mips::BGTU;
3955 break;
3956 case Mips::BLTLImmMacro:
3957 PseudoOpcode = Mips::BLTL;
3958 break;
3959 case Mips::BLELImmMacro:
3960 PseudoOpcode = Mips::BLEL;
3961 break;
3962 case Mips::BGELImmMacro:
3963 PseudoOpcode = Mips::BGEL;
3964 break;
3965 case Mips::BGTLImmMacro:
3966 PseudoOpcode = Mips::BGTL;
3967 break;
3968 case Mips::BLTULImmMacro:
3969 PseudoOpcode = Mips::BLTUL;
3970 break;
3971 case Mips::BLEULImmMacro:
3972 PseudoOpcode = Mips::BLEUL;
3973 break;
3974 case Mips::BGEULImmMacro:
3975 PseudoOpcode = Mips::BGEUL;
3976 break;
3977 case Mips::BGTULImmMacro:
3978 PseudoOpcode = Mips::BGTUL;
3979 break;
3980 }
3981
3982 if (loadImmediate(TrgOp.getImm(), TrgReg, MCRegister(), !isGP64bit(), false,
3983 IDLoc, Out, STI))
3984 return true;
3985 }
3986
3987 switch (PseudoOpcode) {
3988 case Mips::BLT:
3989 case Mips::BLTU:
3990 case Mips::BLTL:
3991 case Mips::BLTUL:
3992 AcceptsEquality = false;
3993 ReverseOrderSLT = false;
3994 IsUnsigned =
3995 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3996 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3997 ZeroSrcOpcode = Mips::BGTZ;
3998 ZeroTrgOpcode = Mips::BLTZ;
3999 break;
4000 case Mips::BLE:
4001 case Mips::BLEU:
4002 case Mips::BLEL:
4003 case Mips::BLEUL:
4004 AcceptsEquality = true;
4005 ReverseOrderSLT = true;
4006 IsUnsigned =
4007 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4008 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4009 ZeroSrcOpcode = Mips::BGEZ;
4010 ZeroTrgOpcode = Mips::BLEZ;
4011 break;
4012 case Mips::BGE:
4013 case Mips::BGEU:
4014 case Mips::BGEL:
4015 case Mips::BGEUL:
4016 AcceptsEquality = true;
4017 ReverseOrderSLT = false;
4018 IsUnsigned =
4019 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4020 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4021 ZeroSrcOpcode = Mips::BLEZ;
4022 ZeroTrgOpcode = Mips::BGEZ;
4023 break;
4024 case Mips::BGT:
4025 case Mips::BGTU:
4026 case Mips::BGTL:
4027 case Mips::BGTUL:
4028 AcceptsEquality = false;
4029 ReverseOrderSLT = true;
4030 IsUnsigned =
4031 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4032 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4033 ZeroSrcOpcode = Mips::BLTZ;
4034 ZeroTrgOpcode = Mips::BGTZ;
4035 break;
4036 default:
4037 llvm_unreachable("unknown opcode for branch pseudo-instruction");
4038 }
4039
4040 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4041 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4042 if (IsSrcRegZero && IsTrgRegZero) {
4043 // FIXME: All of these Opcode-specific if's are needed for compatibility
4044 // with GAS' behaviour. However, they may not generate the most efficient
4045 // code in some circumstances.
4046 if (PseudoOpcode == Mips::BLT) {
4047 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4048 IDLoc, STI);
4049 return false;
4050 }
4051 if (PseudoOpcode == Mips::BLE) {
4052 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4053 IDLoc, STI);
4054 Warning(IDLoc, "branch is always taken");
4055 return false;
4056 }
4057 if (PseudoOpcode == Mips::BGE) {
4058 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4059 IDLoc, STI);
4060 Warning(IDLoc, "branch is always taken");
4061 return false;
4062 }
4063 if (PseudoOpcode == Mips::BGT) {
4064 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4065 IDLoc, STI);
4066 return false;
4067 }
4068 if (PseudoOpcode == Mips::BGTU) {
4069 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4070 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4071 return false;
4072 }
4073 if (AcceptsEquality) {
4074 // If both registers are $0 and the pseudo-branch accepts equality, it
4075 // will always be taken, so we emit an unconditional branch.
4076 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4077 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4078 Warning(IDLoc, "branch is always taken");
4079 return false;
4080 }
4081 // If both registers are $0 and the pseudo-branch does not accept
4082 // equality, it will never be taken, so we don't have to emit anything.
4083 return false;
4084 }
4085 if (IsSrcRegZero || IsTrgRegZero) {
4086 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4087 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4088 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4089 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4090 // the pseudo-branch will never be taken, so we don't emit anything.
4091 // This only applies to unsigned pseudo-branches.
4092 return false;
4093 }
4094 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4095 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4096 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4097 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4098 // the pseudo-branch will always be taken, so we emit an unconditional
4099 // branch.
4100 // This only applies to unsigned pseudo-branches.
4101 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4102 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4103 Warning(IDLoc, "branch is always taken");
4104 return false;
4105 }
4106 if (IsUnsigned) {
4107 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4108 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4109 // the pseudo-branch will be taken only when the non-zero register is
4110 // different from 0, so we emit a BNEZ.
4111 //
4112 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4113 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4114 // the pseudo-branch will be taken only when the non-zero register is
4115 // equal to 0, so we emit a BEQZ.
4116 //
4117 // Because only BLEU and BGEU branch on equality, we can use the
4118 // AcceptsEquality variable to decide when to emit the BEQZ.
4119 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4120 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4121 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4122 return false;
4123 }
4124 // If we have a signed pseudo-branch and one of the registers is $0,
4125 // we can use an appropriate compare-to-zero branch. We select which one
4126 // to use in the switch statement above.
4127 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4128 IsSrcRegZero ? TrgReg : SrcReg,
4129 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4130 return false;
4131 }
4132
4133 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4134 // expansions. If it is not available, we return.
4135 MCRegister ATRegNum = getATReg(IDLoc);
4136 if (!ATRegNum)
4137 return true;
4138
4139 if (!EmittedNoMacroWarning)
4140 warnIfNoMacro(IDLoc);
4141
4142 // SLT fits well with 2 of our 4 pseudo-branches:
4143 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4144 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4145 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4146 // This is accomplished by using a BNEZ with the result of the SLT.
4147 //
4148 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4149 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4150 // Because only BGE and BLE branch on equality, we can use the
4151 // AcceptsEquality variable to decide when to emit the BEQZ.
4152 // Note that the order of the SLT arguments doesn't change between
4153 // opposites.
4154 //
4155 // The same applies to the unsigned variants, except that SLTu is used
4156 // instead of SLT.
4157 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4158 ReverseOrderSLT ? TrgReg : SrcReg,
4159 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4160
4161 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4162 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4163 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4164 STI);
4165 return false;
4166}
4167
4168// Expand a integer division macro.
4169//
4170// Notably we don't have to emit a warning when encountering $rt as the $zero
4171// register, or 0 as an immediate. processInstruction() has already done that.
4172//
4173// The destination register can only be $zero when expanding (S)DivIMacro or
4174// D(S)DivMacro.
4175
4176bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4177 const MCSubtargetInfo *STI,
4178 const bool IsMips64, const bool Signed) {
4179 MipsTargetStreamer &TOut = getTargetStreamer();
4180
4181 warnIfNoMacro(IDLoc);
4182
4183 const MCOperand &RdRegOp = Inst.getOperand(0);
4184 assert(RdRegOp.isReg() && "expected register operand kind");
4185 MCRegister RdReg = RdRegOp.getReg();
4186
4187 const MCOperand &RsRegOp = Inst.getOperand(1);
4188 assert(RsRegOp.isReg() && "expected register operand kind");
4189 MCRegister RsReg = RsRegOp.getReg();
4190
4191 MCRegister RtReg;
4192 int64_t ImmValue;
4193
4194 const MCOperand &RtOp = Inst.getOperand(2);
4195 assert((RtOp.isReg() || RtOp.isImm()) &&
4196 "expected register or immediate operand kind");
4197 if (RtOp.isReg())
4198 RtReg = RtOp.getReg();
4199 else
4200 ImmValue = RtOp.getImm();
4201
4202 unsigned DivOp;
4203 unsigned ZeroReg;
4204 unsigned SubOp;
4205
4206 if (IsMips64) {
4207 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4208 ZeroReg = Mips::ZERO_64;
4209 SubOp = Mips::DSUB;
4210 } else {
4211 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4212 ZeroReg = Mips::ZERO;
4213 SubOp = Mips::SUB;
4214 }
4215
4216 bool UseTraps = useTraps();
4217
4218 unsigned Opcode = Inst.getOpcode();
4219 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4220 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4221 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4222 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4223
4224 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4225 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4226 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4227 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4228
4229 if (RtOp.isImm()) {
4230 MCRegister ATReg = getATReg(IDLoc);
4231 if (!ATReg)
4232 return true;
4233
4234 if (ImmValue == 0) {
4235 if (UseTraps)
4236 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4237 else
4238 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4239 return false;
4240 }
4241
4242 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4243 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4244 return false;
4245 } else if (isDiv && ImmValue == 1) {
4246 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4247 return false;
4248 } else if (isDiv && Signed && ImmValue == -1) {
4249 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4250 return false;
4251 } else {
4252 if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue),
4253 false, Inst.getLoc(), Out, STI))
4254 return true;
4255 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4256 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4257 return false;
4258 }
4259 return true;
4260 }
4261
4262 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4263 // break, insert the trap/break and exit. This gives a different result to
4264 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4265 // are handled equivalently. As the observed behaviour is the same, we're ok.
4266 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4267 if (UseTraps) {
4268 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4269 return false;
4270 }
4271 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4272 return false;
4273 }
4274
4275 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4276 // not expand to macro sequence.
4277 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4278 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4279 return false;
4280 }
4281
4282 // Temporary label for first branch traget
4283 MCContext &Context = TOut.getContext();
4284 MCSymbol *BrTarget;
4285 MCOperand LabelOp;
4286
4287 if (UseTraps) {
4288 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4289 } else {
4290 // Branch to the li instruction.
4291 BrTarget = Context.createTempSymbol();
4293 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4294 }
4295
4296 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4297
4298 if (!UseTraps)
4299 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4300
4301 if (!Signed) {
4302 if (!UseTraps)
4303 TOut.getStreamer().emitLabel(BrTarget);
4304
4305 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4306 return false;
4307 }
4308
4309 MCRegister ATReg = getATReg(IDLoc);
4310 if (!ATReg)
4311 return true;
4312
4313 if (!UseTraps)
4314 TOut.getStreamer().emitLabel(BrTarget);
4315
4316 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4317
4318 // Temporary label for the second branch target.
4319 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4320 MCOperand LabelOpEnd =
4322
4323 // Branch to the mflo instruction.
4324 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4325
4326 if (IsMips64) {
4327 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4328 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4329 } else {
4330 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4331 }
4332
4333 if (UseTraps)
4334 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4335 else {
4336 // Branch to the mflo instruction.
4337 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4338 TOut.emitNop(IDLoc, STI);
4339 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4340 }
4341
4342 TOut.getStreamer().emitLabel(BrTargetEnd);
4343 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4344 return false;
4345}
4346
4347bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4348 SMLoc IDLoc, MCStreamer &Out,
4349 const MCSubtargetInfo *STI) {
4350 MipsTargetStreamer &TOut = getTargetStreamer();
4351
4352 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4353 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4354 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4355
4356 MCRegister FirstReg = Inst.getOperand(0).getReg();
4357 MCRegister SecondReg = Inst.getOperand(1).getReg();
4358 MCRegister ThirdReg = Inst.getOperand(2).getReg();
4359
4360 if (hasMips1() && !hasMips2()) {
4361 MCRegister ATReg = getATReg(IDLoc);
4362 if (!ATReg)
4363 return true;
4364 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4365 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4366 TOut.emitNop(IDLoc, STI);
4367 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4368 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4369 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4370 TOut.emitNop(IDLoc, STI);
4371 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4372 : Mips::CVT_W_S,
4373 FirstReg, SecondReg, IDLoc, STI);
4374 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4375 TOut.emitNop(IDLoc, STI);
4376 return false;
4377 }
4378
4379 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4380 : Mips::TRUNC_W_S,
4381 FirstReg, SecondReg, IDLoc, STI);
4382
4383 return false;
4384}
4385
4386bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4387 MCStreamer &Out, const MCSubtargetInfo *STI) {
4388 if (hasMips32r6() || hasMips64r6()) {
4389 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4390 }
4391
4392 const MCOperand &DstRegOp = Inst.getOperand(0);
4393 assert(DstRegOp.isReg() && "expected register operand kind");
4394 const MCOperand &SrcRegOp = Inst.getOperand(1);
4395 assert(SrcRegOp.isReg() && "expected register operand kind");
4396 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4397 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4398
4399 MipsTargetStreamer &TOut = getTargetStreamer();
4400 MCRegister DstReg = DstRegOp.getReg();
4401 MCRegister SrcReg = SrcRegOp.getReg();
4402 int64_t OffsetValue = OffsetImmOp.getImm();
4403
4404 // NOTE: We always need AT for ULHU, as it is always used as the source
4405 // register for one of the LBu's.
4406 warnIfNoMacro(IDLoc);
4407 MCRegister ATReg = getATReg(IDLoc);
4408 if (!ATReg)
4409 return true;
4410
4411 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4412 if (IsLargeOffset) {
4413 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4414 IDLoc, Out, STI))
4415 return true;
4416 }
4417
4418 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4419 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4420 if (isLittle())
4421 std::swap(FirstOffset, SecondOffset);
4422
4423 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4424 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4425
4426 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4427 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4428
4429 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4430 FirstOffset, IDLoc, STI);
4431 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4432 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4433 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4434
4435 return false;
4436}
4437
4438bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4439 const MCSubtargetInfo *STI) {
4440 if (hasMips32r6() || hasMips64r6()) {
4441 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4442 }
4443
4444 const MCOperand &DstRegOp = Inst.getOperand(0);
4445 assert(DstRegOp.isReg() && "expected register operand kind");
4446 const MCOperand &SrcRegOp = Inst.getOperand(1);
4447 assert(SrcRegOp.isReg() && "expected register operand kind");
4448 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4449 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4450
4451 MipsTargetStreamer &TOut = getTargetStreamer();
4452 MCRegister DstReg = DstRegOp.getReg();
4453 MCRegister SrcReg = SrcRegOp.getReg();
4454 int64_t OffsetValue = OffsetImmOp.getImm();
4455
4456 warnIfNoMacro(IDLoc);
4457 MCRegister ATReg = getATReg(IDLoc);
4458 if (!ATReg)
4459 return true;
4460
4461 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4462 if (IsLargeOffset) {
4463 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4464 IDLoc, Out, STI))
4465 return true;
4466 }
4467
4468 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4469 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4470 if (isLittle())
4471 std::swap(FirstOffset, SecondOffset);
4472
4473 if (IsLargeOffset) {
4474 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4475 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4476 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4477 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4478 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4479 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4480 } else {
4481 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4482 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4483 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4484 }
4485
4486 return false;
4487}
4488
4489bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4490 const MCSubtargetInfo *STI) {
4491 if (hasMips32r6() || hasMips64r6()) {
4492 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4493 }
4494
4495 const MCOperand &DstRegOp = Inst.getOperand(0);
4496 assert(DstRegOp.isReg() && "expected register operand kind");
4497 const MCOperand &SrcRegOp = Inst.getOperand(1);
4498 assert(SrcRegOp.isReg() && "expected register operand kind");
4499 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4500 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4501
4502 MipsTargetStreamer &TOut = getTargetStreamer();
4503 MCRegister DstReg = DstRegOp.getReg();
4504 MCRegister SrcReg = SrcRegOp.getReg();
4505 int64_t OffsetValue = OffsetImmOp.getImm();
4506
4507 // Compute left/right load/store offsets.
4508 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4509 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4510 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4511 if (isLittle())
4512 std::swap(LxlOffset, LxrOffset);
4513
4514 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4515 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4516 MCRegister TmpReg = SrcReg;
4517 if (IsLargeOffset || DoMove) {
4518 warnIfNoMacro(IDLoc);
4519 TmpReg = getATReg(IDLoc);
4520 if (!TmpReg)
4521 return true;
4522 }
4523
4524 if (IsLargeOffset) {
4525 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4526 IDLoc, Out, STI))
4527 return true;
4528 }
4529
4530 if (DoMove)
4531 std::swap(DstReg, TmpReg);
4532
4533 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4534 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4535 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4536 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4537
4538 if (DoMove)
4539 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4540
4541 return false;
4542}
4543
4544bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4545 const MCSubtargetInfo *STI) {
4546 MipsTargetStreamer &TOut = getTargetStreamer();
4547
4548 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4549 assert(Inst.getOperand(0).isReg() &&
4550 Inst.getOperand(1).isReg() &&
4551 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4552
4553 MCRegister DstReg = Inst.getOperand(0).getReg();
4554 MCRegister SrcReg = Inst.getOperand(1).getReg();
4555 MCRegister OpReg = Inst.getOperand(2).getReg();
4556 unsigned OpCode;
4557
4558 warnIfNoMacro(IDLoc);
4559
4560 switch (Inst.getOpcode()) {
4561 case Mips::SGE:
4562 OpCode = Mips::SLT;
4563 break;
4564 case Mips::SGEU:
4565 OpCode = Mips::SLTu;
4566 break;
4567 default:
4568 llvm_unreachable("unexpected 'sge' opcode");
4569 }
4570
4571 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4572 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4573 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4574
4575 return false;
4576}
4577
4578bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4579 const MCSubtargetInfo *STI) {
4580 MipsTargetStreamer &TOut = getTargetStreamer();
4581
4582 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4583 assert(Inst.getOperand(0).isReg() &&
4584 Inst.getOperand(1).isReg() &&
4585 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4586
4587 MCRegister DstReg = Inst.getOperand(0).getReg();
4588 MCRegister SrcReg = Inst.getOperand(1).getReg();
4589 int64_t ImmValue = Inst.getOperand(2).getImm();
4590 unsigned OpRegCode, OpImmCode;
4591
4592 warnIfNoMacro(IDLoc);
4593
4594 switch (Inst.getOpcode()) {
4595 case Mips::SGEImm:
4596 case Mips::SGEImm64:
4597 OpRegCode = Mips::SLT;
4598 OpImmCode = Mips::SLTi;
4599 break;
4600 case Mips::SGEUImm:
4601 case Mips::SGEUImm64:
4602 OpRegCode = Mips::SLTu;
4603 OpImmCode = Mips::SLTiu;
4604 break;
4605 default:
4606 llvm_unreachable("unexpected 'sge' opcode with immediate");
4607 }
4608
4609 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4610 if (isInt<16>(ImmValue)) {
4611 // Use immediate version of STL.
4612 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4613 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4614 } else {
4615 MCRegister ImmReg = DstReg;
4616 if (DstReg == SrcReg) {
4617 MCRegister ATReg = getATReg(Inst.getLoc());
4618 if (!ATReg)
4619 return true;
4620 ImmReg = ATReg;
4621 }
4622
4623 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue),
4624 false, IDLoc, Out, STI))
4625 return true;
4626
4627 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4628 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4629 }
4630
4631 return false;
4632}
4633
4634bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4635 const MCSubtargetInfo *STI) {
4636 MipsTargetStreamer &TOut = getTargetStreamer();
4637
4638 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4639 assert(Inst.getOperand(0).isReg() &&
4640 Inst.getOperand(1).isReg() &&
4641 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4642
4643 MCRegister DstReg = Inst.getOperand(0).getReg();
4644 MCRegister SrcReg = Inst.getOperand(1).getReg();
4645 MCRegister ImmReg = DstReg;
4646 int64_t ImmValue = Inst.getOperand(2).getImm();
4647 unsigned OpCode;
4648
4649 warnIfNoMacro(IDLoc);
4650
4651 switch (Inst.getOpcode()) {
4652 case Mips::SGTImm:
4653 case Mips::SGTImm64:
4654 OpCode = Mips::SLT;
4655 break;
4656 case Mips::SGTUImm:
4657 case Mips::SGTUImm64:
4658 OpCode = Mips::SLTu;
4659 break;
4660 default:
4661 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4662 }
4663
4664 if (DstReg == SrcReg) {
4665 MCRegister ATReg = getATReg(Inst.getLoc());
4666 if (!ATReg)
4667 return true;
4668 ImmReg = ATReg;
4669 }
4670
4671 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4672 IDLoc, Out, STI))
4673 return true;
4674
4675 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4676 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4677
4678 return false;
4679}
4680
4681bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4682 const MCSubtargetInfo *STI) {
4683 MipsTargetStreamer &TOut = getTargetStreamer();
4684
4685 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4686 assert(Inst.getOperand(0).isReg() &&
4687 Inst.getOperand(1).isReg() &&
4688 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4689
4690 MCRegister DstReg = Inst.getOperand(0).getReg();
4691 MCRegister SrcReg = Inst.getOperand(1).getReg();
4692 MCRegister OpReg = Inst.getOperand(2).getReg();
4693 unsigned OpCode;
4694
4695 warnIfNoMacro(IDLoc);
4696
4697 switch (Inst.getOpcode()) {
4698 case Mips::SLE:
4699 OpCode = Mips::SLT;
4700 break;
4701 case Mips::SLEU:
4702 OpCode = Mips::SLTu;
4703 break;
4704 default:
4705 llvm_unreachable("unexpected 'sge' opcode");
4706 }
4707
4708 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4709 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4710 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4711
4712 return false;
4713}
4714
4715bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4716 const MCSubtargetInfo *STI) {
4717 MipsTargetStreamer &TOut = getTargetStreamer();
4718
4719 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4720 assert(Inst.getOperand(0).isReg() &&
4721 Inst.getOperand(1).isReg() &&
4722 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4723
4724 MCRegister DstReg = Inst.getOperand(0).getReg();
4725 MCRegister SrcReg = Inst.getOperand(1).getReg();
4726 int64_t ImmValue = Inst.getOperand(2).getImm();
4727 unsigned OpRegCode;
4728
4729 warnIfNoMacro(IDLoc);
4730
4731 switch (Inst.getOpcode()) {
4732 case Mips::SLEImm:
4733 case Mips::SLEImm64:
4734 OpRegCode = Mips::SLT;
4735 break;
4736 case Mips::SLEUImm:
4737 case Mips::SLEUImm64:
4738 OpRegCode = Mips::SLTu;
4739 break;
4740 default:
4741 llvm_unreachable("unexpected 'sge' opcode with immediate");
4742 }
4743
4744 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4745 MCRegister ImmReg = DstReg;
4746 if (DstReg == SrcReg) {
4747 MCRegister ATReg = getATReg(Inst.getLoc());
4748 if (!ATReg)
4749 return true;
4750 ImmReg = ATReg;
4751 }
4752
4753 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4754 IDLoc, Out, STI))
4755 return true;
4756
4757 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4758 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4759
4760 return false;
4761}
4762
4763bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4764 MCStreamer &Out,
4765 const MCSubtargetInfo *STI) {
4766 MipsTargetStreamer &TOut = getTargetStreamer();
4767
4768 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4769 assert(Inst.getOperand(0).isReg() &&
4770 Inst.getOperand(1).isReg() &&
4771 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4772
4773 MCRegister ATReg;
4774 MCRegister FinalDstReg;
4775 MCRegister DstReg = Inst.getOperand(0).getReg();
4776 MCRegister SrcReg = Inst.getOperand(1).getReg();
4777 int64_t ImmValue = Inst.getOperand(2).getImm();
4778
4779 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4780
4781 unsigned FinalOpcode = Inst.getOpcode();
4782
4783 if (DstReg == SrcReg) {
4784 ATReg = getATReg(Inst.getLoc());
4785 if (!ATReg)
4786 return true;
4787 FinalDstReg = DstReg;
4788 DstReg = ATReg;
4789 }
4790
4791 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit, false,
4792 Inst.getLoc(), Out, STI)) {
4793 switch (FinalOpcode) {
4794 default:
4795 llvm_unreachable("unimplemented expansion");
4796 case Mips::ADDi:
4797 FinalOpcode = Mips::ADD;
4798 break;
4799 case Mips::ADDiu:
4800 FinalOpcode = Mips::ADDu;
4801 break;
4802 case Mips::ANDi:
4803 FinalOpcode = Mips::AND;
4804 break;
4805 case Mips::NORImm:
4806 FinalOpcode = Mips::NOR;
4807 break;
4808 case Mips::ORi:
4809 FinalOpcode = Mips::OR;
4810 break;
4811 case Mips::SLTi:
4812 FinalOpcode = Mips::SLT;
4813 break;
4814 case Mips::SLTiu:
4815 FinalOpcode = Mips::SLTu;
4816 break;
4817 case Mips::XORi:
4818 FinalOpcode = Mips::XOR;
4819 break;
4820 case Mips::ADDi_MM:
4821 FinalOpcode = Mips::ADD_MM;
4822 break;
4823 case Mips::ADDiu_MM:
4824 FinalOpcode = Mips::ADDu_MM;
4825 break;
4826 case Mips::ANDi_MM:
4827 FinalOpcode = Mips::AND_MM;
4828 break;
4829 case Mips::ORi_MM:
4830 FinalOpcode = Mips::OR_MM;
4831 break;
4832 case Mips::SLTi_MM:
4833 FinalOpcode = Mips::SLT_MM;
4834 break;
4835 case Mips::SLTiu_MM:
4836 FinalOpcode = Mips::SLTu_MM;
4837 break;
4838 case Mips::XORi_MM:
4839 FinalOpcode = Mips::XOR_MM;
4840 break;
4841 case Mips::ANDi64:
4842 FinalOpcode = Mips::AND64;
4843 break;
4844 case Mips::NORImm64:
4845 FinalOpcode = Mips::NOR64;
4846 break;
4847 case Mips::ORi64:
4848 FinalOpcode = Mips::OR64;
4849 break;
4850 case Mips::SLTImm64:
4851 FinalOpcode = Mips::SLT64;
4852 break;
4853 case Mips::SLTUImm64:
4854 FinalOpcode = Mips::SLTu64;
4855 break;
4856 case Mips::XORi64:
4857 FinalOpcode = Mips::XOR64;
4858 break;
4859 }
4860
4861 if (!FinalDstReg)
4862 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4863 else
4864 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4865 return false;
4866 }
4867 return true;
4868}
4869
4870bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4871 const MCSubtargetInfo *STI) {
4872 MipsTargetStreamer &TOut = getTargetStreamer();
4873 MCRegister ATReg;
4874 MCRegister DReg = Inst.getOperand(0).getReg();
4875 MCRegister SReg = Inst.getOperand(1).getReg();
4876 MCRegister TReg = Inst.getOperand(2).getReg();
4877 MCRegister TmpReg = DReg;
4878
4879 unsigned FirstShift = Mips::NOP;
4880 unsigned SecondShift = Mips::NOP;
4881
4882 if (hasMips32r2()) {
4883 if (DReg == SReg) {
4884 TmpReg = getATReg(Inst.getLoc());
4885 if (!TmpReg)
4886 return true;
4887 }
4888
4889 if (Inst.getOpcode() == Mips::ROL) {
4890 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4891 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4892 return false;
4893 }
4894
4895 if (Inst.getOpcode() == Mips::ROR) {
4896 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4897 return false;
4898 }
4899
4900 return true;
4901 }
4902
4903 if (hasMips32()) {
4904 switch (Inst.getOpcode()) {
4905 default:
4906 llvm_unreachable("unexpected instruction opcode");
4907 case Mips::ROL:
4908 FirstShift = Mips::SRLV;
4909 SecondShift = Mips::SLLV;
4910 break;
4911 case Mips::ROR:
4912 FirstShift = Mips::SLLV;
4913 SecondShift = Mips::SRLV;
4914 break;
4915 }
4916
4917 ATReg = getATReg(Inst.getLoc());
4918 if (!ATReg)
4919 return true;
4920
4921 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4922 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4923 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4924 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4925
4926 return false;
4927 }
4928
4929 return true;
4930}
4931
4932bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4933 MCStreamer &Out,
4934 const MCSubtargetInfo *STI) {
4935 MipsTargetStreamer &TOut = getTargetStreamer();
4936 MCRegister ATReg;
4937 MCRegister DReg = Inst.getOperand(0).getReg();
4938 MCRegister SReg = Inst.getOperand(1).getReg();
4939 int64_t ImmValue = Inst.getOperand(2).getImm();
4940
4941 unsigned FirstShift = Mips::NOP;
4942 unsigned SecondShift = Mips::NOP;
4943
4944 if (hasMips32r2()) {
4945 if (Inst.getOpcode() == Mips::ROLImm) {
4946 uint64_t MaxShift = 32;
4947 uint64_t ShiftValue = ImmValue;
4948 if (ImmValue != 0)
4949 ShiftValue = MaxShift - ImmValue;
4950 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4951 return false;
4952 }
4953
4954 if (Inst.getOpcode() == Mips::RORImm) {
4955 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4956 return false;
4957 }
4958
4959 return true;
4960 }
4961
4962 if (hasMips32()) {
4963 if (ImmValue == 0) {
4964 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4965 return false;
4966 }
4967
4968 switch (Inst.getOpcode()) {
4969 default:
4970 llvm_unreachable("unexpected instruction opcode");
4971 case Mips::ROLImm:
4972 FirstShift = Mips::SLL;
4973 SecondShift = Mips::SRL;
4974 break;
4975 case Mips::RORImm:
4976 FirstShift = Mips::SRL;
4977 SecondShift = Mips::SLL;
4978 break;
4979 }
4980
4981 ATReg = getATReg(Inst.getLoc());
4982 if (!ATReg)
4983 return true;
4984
4985 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4986 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4987 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4988
4989 return false;
4990 }
4991
4992 return true;
4993}
4994
4995bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4996 const MCSubtargetInfo *STI) {
4997 MipsTargetStreamer &TOut = getTargetStreamer();
4998 MCRegister ATReg;
4999 MCRegister DReg = Inst.getOperand(0).getReg();
5000 MCRegister SReg = Inst.getOperand(1).getReg();
5001 MCRegister TReg = Inst.getOperand(2).getReg();
5002 MCRegister TmpReg = DReg;
5003
5004 unsigned FirstShift = Mips::NOP;
5005 unsigned SecondShift = Mips::NOP;
5006
5007 if (hasMips64r2()) {
5008 if (TmpReg == SReg) {
5009 TmpReg = getATReg(Inst.getLoc());
5010 if (!TmpReg)
5011 return true;
5012 }
5013
5014 if (Inst.getOpcode() == Mips::DROL) {
5015 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5016 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
5017 return false;
5018 }
5019
5020 if (Inst.getOpcode() == Mips::DROR) {
5021 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
5022 return false;
5023 }
5024
5025 return true;
5026 }
5027
5028 if (hasMips64()) {
5029 switch (Inst.getOpcode()) {
5030 default:
5031 llvm_unreachable("unexpected instruction opcode");
5032 case Mips::DROL:
5033 FirstShift = Mips::DSRLV;
5034 SecondShift = Mips::DSLLV;
5035 break;
5036 case Mips::DROR:
5037 FirstShift = Mips::DSLLV;
5038 SecondShift = Mips::DSRLV;
5039 break;
5040 }
5041
5042 ATReg = getATReg(Inst.getLoc());
5043 if (!ATReg)
5044 return true;
5045
5046 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5047 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5048 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5049 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5050
5051 return false;
5052 }
5053
5054 return true;
5055}
5056
5057bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5058 MCStreamer &Out,
5059 const MCSubtargetInfo *STI) {
5060 MipsTargetStreamer &TOut = getTargetStreamer();
5061 MCRegister ATReg;
5062 MCRegister DReg = Inst.getOperand(0).getReg();
5063 MCRegister SReg = Inst.getOperand(1).getReg();
5064 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5065
5066 unsigned FirstShift = Mips::NOP;
5067 unsigned SecondShift = Mips::NOP;
5068
5069 MCInst TmpInst;
5070
5071 if (hasMips64r2()) {
5072 unsigned FinalOpcode = Mips::NOP;
5073 if (ImmValue == 0)
5074 FinalOpcode = Mips::DROTR;
5075 else if (ImmValue % 32 == 0)
5076 FinalOpcode = Mips::DROTR32;
5077 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5078 if (Inst.getOpcode() == Mips::DROLImm)
5079 FinalOpcode = Mips::DROTR32;
5080 else
5081 FinalOpcode = Mips::DROTR;
5082 } else if (ImmValue >= 33) {
5083 if (Inst.getOpcode() == Mips::DROLImm)
5084 FinalOpcode = Mips::DROTR;
5085 else
5086 FinalOpcode = Mips::DROTR32;
5087 }
5088
5089 uint64_t ShiftValue = ImmValue % 32;
5090 if (Inst.getOpcode() == Mips::DROLImm)
5091 ShiftValue = (32 - ImmValue % 32) % 32;
5092
5093 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5094
5095 return false;
5096 }
5097
5098 if (hasMips64()) {
5099 if (ImmValue == 0) {
5100 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5101 return false;
5102 }
5103
5104 switch (Inst.getOpcode()) {
5105 default:
5106 llvm_unreachable("unexpected instruction opcode");
5107 case Mips::DROLImm:
5108 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5109 FirstShift = Mips::DSLL;
5110 SecondShift = Mips::DSRL32;
5111 }
5112 if (ImmValue == 32) {
5113 FirstShift = Mips::DSLL32;
5114 SecondShift = Mips::DSRL32;
5115 }
5116 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5117 FirstShift = Mips::DSLL32;
5118 SecondShift = Mips::DSRL;
5119 }
5120 break;
5121 case Mips::DRORImm:
5122 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5123 FirstShift = Mips::DSRL;
5124 SecondShift = Mips::DSLL32;
5125 }
5126 if (ImmValue == 32) {
5127 FirstShift = Mips::DSRL32;
5128 SecondShift = Mips::DSLL32;
5129 }
5130 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5131 FirstShift = Mips::DSRL32;
5132 SecondShift = Mips::DSLL;
5133 }
5134 break;
5135 }
5136
5137 ATReg = getATReg(Inst.getLoc());
5138 if (!ATReg)
5139 return true;
5140
5141 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5142 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5143 Inst.getLoc(), STI);
5144 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5145
5146 return false;
5147 }
5148
5149 return true;
5150}
5151
5152bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5153 const MCSubtargetInfo *STI) {
5154 MipsTargetStreamer &TOut = getTargetStreamer();
5155 MCRegister FirstRegOp = Inst.getOperand(0).getReg();
5156 MCRegister SecondRegOp = Inst.getOperand(1).getReg();
5157
5158 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5159 if (FirstRegOp != SecondRegOp)
5160 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5161 else
5162 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5163 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5164
5165 return false;
5166}
5167
5168bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5169 const MCSubtargetInfo *STI) {
5170 MipsTargetStreamer &TOut = getTargetStreamer();
5171 MCRegister ATReg;
5172 MCRegister DstReg = Inst.getOperand(0).getReg();
5173 MCRegister SrcReg = Inst.getOperand(1).getReg();
5174 int32_t ImmValue = Inst.getOperand(2).getImm();
5175
5176 ATReg = getATReg(IDLoc);
5177 if (!ATReg)
5178 return true;
5179
5180 loadImmediate(ImmValue, ATReg, MCRegister(), true, false, IDLoc, Out, STI);
5181
5182 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5183 SrcReg, ATReg, IDLoc, STI);
5184
5185 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5186
5187 return false;
5188}
5189
5190bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5191 const MCSubtargetInfo *STI) {
5192 MipsTargetStreamer &TOut = getTargetStreamer();
5193 MCRegister ATReg;
5194 MCRegister DstReg = Inst.getOperand(0).getReg();
5195 MCRegister SrcReg = Inst.getOperand(1).getReg();
5196 MCRegister TmpReg = Inst.getOperand(2).getReg();
5197
5198 ATReg = getATReg(Inst.getLoc());
5199 if (!ATReg)
5200 return true;
5201
5202 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5203 SrcReg, TmpReg, IDLoc, STI);
5204
5205 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5206
5207 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5208 DstReg, DstReg, 0x1F, IDLoc, STI);
5209
5210 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5211
5212 if (useTraps()) {
5213 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5214 } else {
5215 MCContext &Context = TOut.getContext();
5216 MCSymbol * BrTarget = Context.createTempSymbol();
5217 MCOperand LabelOp =
5219
5220 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5221 if (AssemblerOptions.back()->isReorder())
5222 TOut.emitNop(IDLoc, STI);
5223 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5224
5225 TOut.getStreamer().emitLabel(BrTarget);
5226 }
5227 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5228
5229 return false;
5230}
5231
5232bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5233 const MCSubtargetInfo *STI) {
5234 MipsTargetStreamer &TOut = getTargetStreamer();
5235 MCRegister ATReg;
5236 MCRegister DstReg = Inst.getOperand(0).getReg();
5237 MCRegister SrcReg = Inst.getOperand(1).getReg();
5238 MCRegister TmpReg = Inst.getOperand(2).getReg();
5239
5240 ATReg = getATReg(IDLoc);
5241 if (!ATReg)
5242 return true;
5243
5244 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5245 SrcReg, TmpReg, IDLoc, STI);
5246
5247 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5248 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5249 if (useTraps()) {
5250 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5251 } else {
5252 MCContext &Context = TOut.getContext();
5253 MCSymbol * BrTarget = Context.createTempSymbol();
5254 MCOperand LabelOp =
5256
5257 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5258 if (AssemblerOptions.back()->isReorder())
5259 TOut.emitNop(IDLoc, STI);
5260 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5261
5262 TOut.getStreamer().emitLabel(BrTarget);
5263 }
5264
5265 return false;
5266}
5267
5268bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5269 const MCSubtargetInfo *STI) {
5270 MipsTargetStreamer &TOut = getTargetStreamer();
5271 MCRegister DstReg = Inst.getOperand(0).getReg();
5272 MCRegister SrcReg = Inst.getOperand(1).getReg();
5273 MCRegister TmpReg = Inst.getOperand(2).getReg();
5274
5275 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5276 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5277
5278 return false;
5279}
5280
5281// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5282// lw $<reg+1>>, offset+4($reg2)'
5283// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5284// sw $<reg+1>>, offset+4($reg2)'
5285// for O32.
5286bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5287 MCStreamer &Out,
5288 const MCSubtargetInfo *STI,
5289 bool IsLoad) {
5290 if (!isABI_O32())
5291 return true;
5292
5293 warnIfNoMacro(IDLoc);
5294
5295 MipsTargetStreamer &TOut = getTargetStreamer();
5296 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5297 MCRegister FirstReg = Inst.getOperand(0).getReg();
5298 MCRegister SecondReg = nextReg(FirstReg);
5299 MCRegister BaseReg = Inst.getOperand(1).getReg();
5300 if (!SecondReg)
5301 return true;
5302
5303 warnIfRegIndexIsAT(FirstReg, IDLoc);
5304
5305 assert(Inst.getOperand(2).isImm() &&
5306 "Offset for load macro is not immediate!");
5307
5308 MCOperand &FirstOffset = Inst.getOperand(2);
5309 signed NextOffset = FirstOffset.getImm() + 4;
5310 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5311
5312 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5313 return true;
5314
5315 // For loads, clobber the base register with the second load instead of the
5316 // first if the BaseReg == FirstReg.
5317 if (FirstReg != BaseReg || !IsLoad) {
5318 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5319 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5320 } else {
5321 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5322 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5323 }
5324
5325 return false;
5326}
5327
5328
5329// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5330// swc1 $<reg>, offset+4($reg2)'
5331// or if little endian to 'swc1 $<reg>, offset($reg2);
5332// swc1 $<reg+1>, offset+4($reg2)'
5333// for Mips1.
5334bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5335 MCStreamer &Out,
5336 const MCSubtargetInfo *STI) {
5337 if (!isABI_O32())
5338 return true;
5339
5340 warnIfNoMacro(IDLoc);
5341
5342 MipsTargetStreamer &TOut = getTargetStreamer();
5343 unsigned Opcode = Mips::SWC1;
5344 MCRegister FirstReg = Inst.getOperand(0).getReg();
5345 MCRegister SecondReg = nextReg(FirstReg);
5346 MCRegister BaseReg = Inst.getOperand(1).getReg();
5347 if (!SecondReg)
5348 return true;
5349
5350 warnIfRegIndexIsAT(FirstReg, IDLoc);
5351
5352 assert(Inst.getOperand(2).isImm() &&
5353 "Offset for macro is not immediate!");
5354
5355 MCOperand &FirstOffset = Inst.getOperand(2);
5356 signed NextOffset = FirstOffset.getImm() + 4;
5357 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5358
5359 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5360 return true;
5361
5362 if (!IsLittleEndian)
5363 std::swap(FirstReg, SecondReg);
5364
5365 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5366 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5367
5368 return false;
5369}
5370
5371bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5372 const MCSubtargetInfo *STI) {
5373 MipsTargetStreamer &TOut = getTargetStreamer();
5374
5375 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5376 assert(Inst.getOperand(0).isReg() &&
5377 Inst.getOperand(1).isReg() &&
5378 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5379
5380 MCRegister DstReg = Inst.getOperand(0).getReg();
5381 MCRegister SrcReg = Inst.getOperand(1).getReg();
5382 MCRegister OpReg = Inst.getOperand(2).getReg();
5383
5384 warnIfNoMacro(IDLoc);
5385
5386 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5387 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5388 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5389 return false;
5390 }
5391
5392 MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5393 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5394 return false;
5395}
5396
5397bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5398 const MCSubtargetInfo *STI) {
5399 MipsTargetStreamer &TOut = getTargetStreamer();
5400
5401 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5402 assert(Inst.getOperand(0).isReg() &&
5403 Inst.getOperand(1).isReg() &&
5404 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5405
5406 MCRegister DstReg = Inst.getOperand(0).getReg();
5407 MCRegister SrcReg = Inst.getOperand(1).getReg();
5408 int64_t Imm = Inst.getOperand(2).getImm();
5409
5410 warnIfNoMacro(IDLoc);
5411
5412 if (Imm == 0) {
5413 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5414 return false;
5415 }
5416
5417 if (SrcReg == Mips::ZERO) {
5418 Warning(IDLoc, "comparison is always false");
5419 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5420 DstReg, SrcReg, SrcReg, IDLoc, STI);
5421 return false;
5422 }
5423
5424 unsigned Opc;
5425 if (Imm > -0x8000 && Imm < 0) {
5426 Imm = -Imm;
5427 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5428 } else {
5429 Opc = Mips::XORi;
5430 }
5431
5432 if (!isUInt<16>(Imm)) {
5433 MCRegister ATReg = getATReg(IDLoc);
5434 if (!ATReg)
5435 return true;
5436
5437 if (loadImmediate(Imm, ATReg, MCRegister(), true, isGP64bit(), IDLoc, Out,
5438 STI))
5439 return true;
5440
5441 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5442 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5443 return false;
5444 }
5445
5446 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5447 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5448 return false;
5449}
5450
5451bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5452 const MCSubtargetInfo *STI) {
5453
5454 MipsTargetStreamer &TOut = getTargetStreamer();
5455
5456 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5457 assert(Inst.getOperand(0).isReg() &&
5458 Inst.getOperand(1).isReg() &&
5459 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5460
5461 MCRegister DstReg = Inst.getOperand(0).getReg();
5462 MCRegister SrcReg = Inst.getOperand(1).getReg();
5463 MCRegister OpReg = Inst.getOperand(2).getReg();
5464
5465 warnIfNoMacro(IDLoc);
5466
5467 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5468 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5469 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5470 return false;
5471 }
5472
5473 MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5474 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5475 return false;
5476}
5477
5478bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5479 const MCSubtargetInfo *STI) {
5480 MipsTargetStreamer &TOut = getTargetStreamer();
5481
5482 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5483 assert(Inst.getOperand(0).isReg() &&
5484 Inst.getOperand(1).isReg() &&
5485 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5486
5487 MCRegister DstReg = Inst.getOperand(0).getReg();
5488 MCRegister SrcReg = Inst.getOperand(1).getReg();
5489 int64_t ImmValue = Inst.getOperand(2).getImm();
5490
5491 warnIfNoMacro(IDLoc);
5492
5493 if (ImmValue == 0) {
5494 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5495 return false;
5496 }
5497
5498 if (SrcReg == Mips::ZERO) {
5499 Warning(IDLoc, "comparison is always true");
5500 if (loadImmediate(1, DstReg, MCRegister(), true, false, IDLoc, Out, STI))
5501 return true;
5502 return false;
5503 }
5504
5505 unsigned Opc;
5506 if (ImmValue > -0x8000 && ImmValue < 0) {
5507 ImmValue = -ImmValue;
5508 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5509 } else {
5510 Opc = Mips::XORi;
5511 }
5512
5513 if (isUInt<16>(ImmValue)) {
5514 TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5515 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5516 return false;
5517 }
5518
5519 MCRegister ATReg = getATReg(IDLoc);
5520 if (!ATReg)
5521 return true;
5522
5523 if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue), false,
5524 IDLoc, Out, STI))
5525 return true;
5526
5527 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5528 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5529 return false;
5530}
5531
5532// Map the DSP accumulator and control register to the corresponding gpr
5533// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5534// do not map the DSP registers contigously to gpr registers.
5535static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5536 switch (Inst.getOpcode()) {
5537 case Mips::MFTLO:
5538 case Mips::MTTLO:
5539 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5540 case Mips::AC0:
5541 return Mips::ZERO;
5542 case Mips::AC1:
5543 return Mips::A0;
5544 case Mips::AC2:
5545 return Mips::T0;
5546 case Mips::AC3:
5547 return Mips::T4;
5548 default:
5549 llvm_unreachable("Unknown register for 'mttr' alias!");
5550 }
5551 case Mips::MFTHI:
5552 case Mips::MTTHI:
5553 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5554 case Mips::AC0:
5555 return Mips::AT;
5556 case Mips::AC1:
5557 return Mips::A1;
5558 case Mips::AC2:
5559 return Mips::T1;
5560 case Mips::AC3:
5561 return Mips::T5;
5562 default:
5563 llvm_unreachable("Unknown register for 'mttr' alias!");
5564 }
5565 case Mips::MFTACX:
5566 case Mips::MTTACX:
5567 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5568 case Mips::AC0:
5569 return Mips::V0;
5570 case Mips::AC1:
5571 return Mips::A2;
5572 case Mips::AC2:
5573 return Mips::T2;
5574 case Mips::AC3:
5575 return Mips::T6;
5576 default:
5577 llvm_unreachable("Unknown register for 'mttr' alias!");
5578 }
5579 case Mips::MFTDSP:
5580 case Mips::MTTDSP:
5581 return Mips::S0;
5582 default:
5583 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5584 }
5585}
5586
5587// Map the floating point register operand to the corresponding register
5588// operand.
5589static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5590 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg().id()) {
5591 case Mips::F0: return Mips::ZERO;
5592 case Mips::F1: return Mips::AT;
5593 case Mips::F2: return Mips::V0;
5594 case Mips::F3: return Mips::V1;
5595 case Mips::F4: return Mips::A0;
5596 case Mips::F5: return Mips::A1;
5597 case Mips::F6: return Mips::A2;
5598 case Mips::F7: return Mips::A3;
5599 case Mips::F8: return Mips::T0;
5600 case Mips::F9: return Mips::T1;
5601 case Mips::F10: return Mips::T2;
5602 case Mips::F11: return Mips::T3;
5603 case Mips::F12: return Mips::T4;
5604 case Mips::F13: return Mips::T5;
5605 case Mips::F14: return Mips::T6;
5606 case Mips::F15: return Mips::T7;
5607 case Mips::F16: return Mips::S0;
5608 case Mips::F17: return Mips::S1;
5609 case Mips::F18: return Mips::S2;
5610 case Mips::F19: return Mips::S3;
5611 case Mips::F20: return Mips::S4;
5612 case Mips::F21: return Mips::S5;
5613 case Mips::F22: return Mips::S6;
5614 case Mips::F23: return Mips::S7;
5615 case Mips::F24: return Mips::T8;
5616 case Mips::F25: return Mips::T9;
5617 case Mips::F26: return Mips::K0;
5618 case Mips::F27: return Mips::K1;
5619 case Mips::F28: return Mips::GP;
5620 case Mips::F29: return Mips::SP;
5621 case Mips::F30: return Mips::FP;
5622 case Mips::F31: return Mips::RA;
5623 default: llvm_unreachable("Unknown register for mttc1 alias!");
5624 }
5625}
5626
5627// Map the coprocessor operand the corresponding gpr register operand.
5628static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5629 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg().id()) {
5630 case Mips::COP00: return Mips::ZERO;
5631 case Mips::COP01: return Mips::AT;
5632 case Mips::COP02: return Mips::V0;
5633 case Mips::COP03: return Mips::V1;
5634 case Mips::COP04: return Mips::A0;
5635 case Mips::COP05: return Mips::A1;
5636 case Mips::COP06: return Mips::A2;
5637 case Mips::COP07: return Mips::A3;
5638 case Mips::COP08: return Mips::T0;
5639 case Mips::COP09: return Mips::T1;
5640 case Mips::COP010: return Mips::T2;
5641 case Mips::COP011: return Mips::T3;
5642 case Mips::COP012: return Mips::T4;
5643 case Mips::COP013: return Mips::T5;
5644 case Mips::COP014: return Mips::T6;
5645 case Mips::COP015: return Mips::T7;
5646 case Mips::COP016: return Mips::S0;
5647 case Mips::COP017: return Mips::S1;
5648 case Mips::COP018: return Mips::S2;
5649 case Mips::COP019: return Mips::S3;
5650 case Mips::COP020: return Mips::S4;
5651 case Mips::COP021: return Mips::S5;
5652 case Mips::COP022: return Mips::S6;
5653 case Mips::COP023: return Mips::S7;
5654 case Mips::COP024: return Mips::T8;
5655 case Mips::COP025: return Mips::T9;
5656 case Mips::COP026: return Mips::K0;
5657 case Mips::COP027: return Mips::K1;
5658 case Mips::COP028: return Mips::GP;
5659 case Mips::COP029: return Mips::SP;
5660 case Mips::COP030: return Mips::FP;
5661 case Mips::COP031: return Mips::RA;
5662 default: llvm_unreachable("Unknown register for mttc0 alias!");
5663 }
5664}
5665
5666/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5667/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5668bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5669 const MCSubtargetInfo *STI) {
5670 MipsTargetStreamer &TOut = getTargetStreamer();
5671 MCRegister rd;
5672 unsigned u = 1;
5673 unsigned sel = 0;
5674 unsigned h = 0;
5675 bool IsMFTR = false;
5676 switch (Inst.getOpcode()) {
5677 case Mips::MFTC0:
5678 IsMFTR = true;
5679 [[fallthrough]];
5680 case Mips::MTTC0:
5681 u = 0;
5682 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5683 sel = Inst.getOperand(2).getImm();
5684 break;
5685 case Mips::MFTGPR:
5686 IsMFTR = true;
5687 [[fallthrough]];
5688 case Mips::MTTGPR:
5689 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5690 break;
5691 case Mips::MFTLO:
5692 case Mips::MFTHI:
5693 case Mips::MFTACX:
5694 case Mips::MFTDSP:
5695 IsMFTR = true;
5696 [[fallthrough]];
5697 case Mips::MTTLO:
5698 case Mips::MTTHI:
5699 case Mips::MTTACX:
5700 case Mips::MTTDSP:
5701 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5702 sel = 1;
5703 break;
5704 case Mips::MFTHC1:
5705 h = 1;
5706 [[fallthrough]];
5707 case Mips::MFTC1:
5708 IsMFTR = true;
5709 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5710 sel = 2;
5711 break;
5712 case Mips::MTTHC1:
5713 h = 1;
5714 [[fallthrough]];
5715 case Mips::MTTC1:
5716 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5717 sel = 2;
5718 break;
5719 case Mips::CFTC1:
5720 IsMFTR = true;
5721 [[fallthrough]];
5722 case Mips::CTTC1:
5723 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5724 sel = 3;
5725 break;
5726 }
5727 MCRegister Op0 = IsMFTR ? Inst.getOperand(0).getReg() : MCRegister(rd);
5728 MCRegister Op1 =
5729 IsMFTR ? MCRegister(rd)
5730 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5731 : Inst.getOperand(0).getReg());
5732
5733 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5734 STI);
5735 return false;
5736}
5737
5738bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5739 const MCSubtargetInfo *STI) {
5740 assert(Inst.getNumOperands() == 3 && "expected three operands");
5741 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5742 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5743
5744 warnIfNoMacro(IDLoc);
5745
5746 MipsTargetStreamer &TOut = getTargetStreamer();
5747 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5748 MCRegister RtReg = Inst.getOperand(0).getReg();
5749 MCRegister BaseReg = Inst.getOperand(1).getReg();
5750 const MCOperand &BaseOp = Inst.getOperand(2);
5751
5752 if (BaseOp.isImm()) {
5753 int64_t ImmValue = BaseOp.getImm();
5754 if (ImmValue == 0) {
5755 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5756 return false;
5757 }
5758 }
5759
5760 MCRegister ATReg = getATReg(IDLoc);
5761 if (!ATReg)
5762 return true;
5763
5764 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5765 return true;
5766
5767 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5768 return false;
5769}
5770
5771unsigned
5772MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5773 const OperandVector &Operands) {
5774 switch (Inst.getOpcode()) {
5775 default:
5776 return Match_Success;
5777 case Mips::DATI:
5778 case Mips::DAHI:
5779 if (static_cast<MipsOperand &>(*Operands[1])
5780 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5781 return Match_Success;
5782 return Match_RequiresSameSrcAndDst;
5783 }
5784}
5785
5786unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5787 switch (Inst.getOpcode()) {
5788 // As described by the MIPSR6 spec, daui must not use the zero operand for
5789 // its source operand.
5790 case Mips::DAUI:
5791 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5792 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5793 return Match_RequiresNoZeroRegister;
5794 return Match_Success;
5795 // As described by the Mips32r2 spec, the registers Rd and Rs for
5796 // jalr.hb must be different.
5797 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5798 // and registers Rd and Base for microMIPS lwp instruction
5799 case Mips::JALR_HB:
5800 case Mips::JALR_HB64:
5801 case Mips::JALRC_HB_MMR6:
5802 case Mips::JALRC_MMR6:
5803 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5804 return Match_RequiresDifferentSrcAndDst;
5805 return Match_Success;
5806 case Mips::LWP_MM:
5807 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5808 return Match_RequiresDifferentSrcAndDst;
5809 return Match_Success;
5810 case Mips::SYNC:
5811 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5812 return Match_NonZeroOperandForSync;
5813 return Match_Success;
5814 case Mips::MFC0:
5815 case Mips::MTC0:
5816 case Mips::MTC2:
5817 case Mips::MFC2:
5818 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5819 return Match_NonZeroOperandForMTCX;
5820 return Match_Success;
5821 // As described the MIPSR6 spec, the compact branches that compare registers
5822 // must:
5823 // a) Not use the zero register.
5824 // b) Not use the same register twice.
5825 // c) rs < rt for bnec, beqc.
5826 // NB: For this case, the encoding will swap the operands as their
5827 // ordering doesn't matter. GAS performs this transformation too.
5828 // Hence, that constraint does not have to be enforced.
5829 //
5830 // The compact branches that branch iff the signed addition of two registers
5831 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5832 // operand swapping. They do not have restriction of using the zero register.
5833 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5834 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5835 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5836 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5837 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5838 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5839 case Mips::BLEZC64:
5840 case Mips::BGEZC64:
5841 case Mips::BGTZC64:
5842 case Mips::BLTZC64:
5843 case Mips::BEQZC64:
5844 case Mips::BNEZC64:
5845 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5846 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5847 return Match_RequiresNoZeroRegister;
5848 return Match_Success;
5849 case Mips::BGEC: case Mips::BGEC_MMR6:
5850 case Mips::BLTC: case Mips::BLTC_MMR6:
5851 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5852 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5853 case Mips::BEQC: case Mips::BEQC_MMR6:
5854 case Mips::BNEC: case Mips::BNEC_MMR6:
5855 case Mips::BGEC64:
5856 case Mips::BLTC64:
5857 case Mips::BGEUC64:
5858 case Mips::BLTUC64:
5859 case Mips::BEQC64:
5860 case Mips::BNEC64:
5861 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5862 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5863 return Match_RequiresNoZeroRegister;
5864 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5865 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5866 return Match_RequiresNoZeroRegister;
5867 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5868 return Match_RequiresDifferentOperands;
5869 return Match_Success;
5870 case Mips::DINS: {
5871 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5872 "Operands must be immediates for dins!");
5873 const signed Pos = Inst.getOperand(2).getImm();
5874 const signed Size = Inst.getOperand(3).getImm();
5875 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5876 return Match_RequiresPosSizeRange0_32;
5877 return Match_Success;
5878 }
5879 case Mips::DINSM:
5880 case Mips::DINSU: {
5881 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5882 "Operands must be immediates for dinsm/dinsu!");
5883 const signed Pos = Inst.getOperand(2).getImm();
5884 const signed Size = Inst.getOperand(3).getImm();
5885 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5886 return Match_RequiresPosSizeRange33_64;
5887 return Match_Success;
5888 }
5889 case Mips::DEXT: {
5890 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5891 "Operands must be immediates for DEXTM!");
5892 const signed Pos = Inst.getOperand(2).getImm();
5893 const signed Size = Inst.getOperand(3).getImm();
5894 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5895 return Match_RequiresPosSizeUImm6;
5896 return Match_Success;
5897 }
5898 case Mips::DEXTM:
5899 case Mips::DEXTU: {
5900 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5901 "Operands must be immediates for dextm/dextu!");
5902 const signed Pos = Inst.getOperand(2).getImm();
5903 const signed Size = Inst.getOperand(3).getImm();
5904 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5905 return Match_RequiresPosSizeRange33_64;
5906 return Match_Success;
5907 }
5908 case Mips::CRC32B: case Mips::CRC32CB:
5909 case Mips::CRC32H: case Mips::CRC32CH:
5910 case Mips::CRC32W: case Mips::CRC32CW:
5911 case Mips::CRC32D: case Mips::CRC32CD:
5912 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5913 return Match_RequiresSameSrcAndDst;
5914 return Match_Success;
5915 }
5916
5917 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5918 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5919 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5920 return Match_NoFCCRegisterForCurrentISA;
5921
5922 return Match_Success;
5923
5924}
5925
5928 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5929 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5930 if (ErrorLoc == SMLoc())
5931 return Loc;
5932 return ErrorLoc;
5933 }
5934 return Loc;
5935}
5936
5937bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5939 MCStreamer &Out,
5940 uint64_t &ErrorInfo,
5941 bool MatchingInlineAsm) {
5942 MCInst Inst;
5943 unsigned MatchResult =
5944 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5945
5946 switch (MatchResult) {
5947 case Match_Success:
5948 if (processInstruction(Inst, IDLoc, Out, STI))
5949 return true;
5950 return false;
5951 case Match_MissingFeature:
5952 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5953 return true;
5954 case Match_InvalidTiedOperand:
5955 Error(IDLoc, "operand must match destination register");
5956 return true;
5957 case Match_InvalidOperand: {
5958 SMLoc ErrorLoc = IDLoc;
5959 if (ErrorInfo != ~0ULL) {
5960 if (ErrorInfo >= Operands.size())
5961 return Error(IDLoc, "too few operands for instruction");
5962
5963 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5964 if (ErrorLoc == SMLoc())
5965 ErrorLoc = IDLoc;
5966 }
5967
5968 return Error(ErrorLoc, "invalid operand for instruction");
5969 }
5970 case Match_NonZeroOperandForSync:
5971 return Error(IDLoc,
5972 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5973 case Match_NonZeroOperandForMTCX:
5974 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5975 case Match_MnemonicFail:
5976 return Error(IDLoc, "invalid instruction");
5977 case Match_RequiresDifferentSrcAndDst:
5978 return Error(IDLoc, "source and destination must be different");
5979 case Match_RequiresDifferentOperands:
5980 return Error(IDLoc, "registers must be different");
5981 case Match_RequiresNoZeroRegister:
5982 return Error(IDLoc, "invalid operand ($zero) for instruction");
5983 case Match_RequiresSameSrcAndDst:
5984 return Error(IDLoc, "source and destination must match");
5985 case Match_NoFCCRegisterForCurrentISA:
5986 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5987 "non-zero fcc register doesn't exist in current ISA level");
5988 case Match_Immz:
5989 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5990 case Match_UImm1_0:
5991 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5992 "expected 1-bit unsigned immediate");
5993 case Match_UImm2_0:
5994 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5995 "expected 2-bit unsigned immediate");
5996 case Match_UImm2_1:
5997 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5998 "expected immediate in range 1 .. 4");
5999 case Match_UImm3_0:
6000 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6001 "expected 3-bit unsigned immediate");
6002 case Match_UImm4_0:
6003 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6004 "expected 4-bit unsigned immediate");
6005 case Match_SImm4_0:
6006 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6007 "expected 4-bit signed immediate");
6008 case Match_UImm5_0:
6009 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6010 "expected 5-bit unsigned immediate");
6011 case Match_SImm5_0:
6012 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6013 "expected 5-bit signed immediate");
6014 case Match_UImm5_1:
6015 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6016 "expected immediate in range 1 .. 32");
6017 case Match_UImm5_32:
6018 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6019 "expected immediate in range 32 .. 63");
6020 case Match_UImm5_33:
6021 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6022 "expected immediate in range 33 .. 64");
6023 case Match_UImm5_0_Report_UImm6:
6024 // This is used on UImm5 operands that have a corresponding UImm5_32
6025 // operand to avoid confusing the user.
6026 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6027 "expected 6-bit unsigned immediate");
6028 case Match_UImm5_Lsl2:
6029 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6030 "expected both 7-bit unsigned immediate and multiple of 4");
6031 case Match_UImmRange2_64:
6032 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6033 "expected immediate in range 2 .. 64");
6034 case Match_UImm6_0:
6035 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6036 "expected 6-bit unsigned immediate");
6037 case Match_UImm6_Lsl2:
6038 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6039 "expected both 8-bit unsigned immediate and multiple of 4");
6040 case Match_SImm6_0:
6041 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6042 "expected 6-bit signed immediate");
6043 case Match_UImm7_0:
6044 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6045 "expected 7-bit unsigned immediate");
6046 case Match_UImm7_N1:
6047 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6048 "expected immediate in range -1 .. 126");
6049 case Match_SImm7_Lsl2:
6050 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6051 "expected both 9-bit signed immediate and multiple of 4");
6052 case Match_UImm8_0:
6053 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6054 "expected 8-bit unsigned immediate");
6055 case Match_UImm10_0:
6056 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6057 "expected 10-bit unsigned immediate");
6058 case Match_SImm10_0:
6059 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6060 "expected 10-bit signed immediate");
6061 case Match_SImm11_0:
6062 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6063 "expected 11-bit signed immediate");
6064 case Match_UImm16:
6065 case Match_UImm16_Relaxed:
6066 case Match_UImm16_AltRelaxed:
6067 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6068 "expected 16-bit unsigned immediate");
6069 case Match_SImm16:
6070 case Match_SImm16_Relaxed:
6071 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6072 "expected 16-bit signed immediate");
6073 case Match_SImm19_Lsl2:
6074 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6075 "expected both 19-bit signed immediate and multiple of 4");
6076 case Match_UImm20_0:
6077 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6078 "expected 20-bit unsigned immediate");
6079 case Match_UImm26_0:
6080 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6081 "expected 26-bit unsigned immediate");
6082 case Match_SImm32:
6083 case Match_SImm32_Relaxed:
6084 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6085 "expected 32-bit signed immediate");
6086 case Match_UImm32_Coerced:
6087 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6088 "expected 32-bit immediate");
6089 case Match_MemSImm9:
6090 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6091 "expected memory with 9-bit signed offset");
6092 case Match_MemSImm10:
6093 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6094 "expected memory with 10-bit signed offset");
6095 case Match_MemSImm10Lsl1:
6096 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6097 "expected memory with 11-bit signed offset and multiple of 2");
6098 case Match_MemSImm10Lsl2:
6099 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6100 "expected memory with 12-bit signed offset and multiple of 4");
6101 case Match_MemSImm10Lsl3:
6102 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6103 "expected memory with 13-bit signed offset and multiple of 8");
6104 case Match_MemSImm11:
6105 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6106 "expected memory with 11-bit signed offset");
6107 case Match_MemSImm12:
6108 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6109 "expected memory with 12-bit signed offset");
6110 case Match_MemSImm16:
6111 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6112 "expected memory with 16-bit signed offset");
6113 case Match_MemSImmPtr:
6114 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6115 "expected memory with 32-bit signed offset");
6116 case Match_RequiresPosSizeRange0_32: {
6117 SMLoc ErrorStart = Operands[3]->getStartLoc();
6118 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6119 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6120 SMRange(ErrorStart, ErrorEnd));
6121 }
6122 case Match_RequiresPosSizeUImm6: {
6123 SMLoc ErrorStart = Operands[3]->getStartLoc();
6124 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6125 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6126 SMRange(ErrorStart, ErrorEnd));
6127 }
6128 case Match_RequiresPosSizeRange33_64: {
6129 SMLoc ErrorStart = Operands[3]->getStartLoc();
6130 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6131 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6132 SMRange(ErrorStart, ErrorEnd));
6133 }
6134 }
6135
6136 llvm_unreachable("Implement any new match types added!");
6137}
6138
6139void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6140 if (RegIndex && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6141 Warning(Loc, "used $at (currently $" + Twine(RegIndex.id()) +
6142 ") without \".set noat\"");
6143}
6144
6145void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6146 if (!AssemblerOptions.back()->isMacro())
6147 Warning(Loc, "macro instruction expanded into multiple instructions");
6148}
6149
6150void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6151 const OperandVector &Operands) {
6152 assert(
6153 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
6154 "Unexpected instruction!");
6155 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6156 MCRegister NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6157 Inst.addOperand(MCOperand::createReg(NextReg));
6158 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6159}
6160
6161void
6162MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6163 SMRange Range, bool ShowColors) {
6164 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6165 Range, SMFixIt(Range, FixMsg),
6166 ShowColors);
6167}
6168
6169int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6170 int CC;
6171
6172 CC = StringSwitch<unsigned>(Name)
6173 .Case("zero", 0)
6174 .Cases("at", "AT", 1)
6175 .Case("a0", 4)
6176 .Case("a1", 5)
6177 .Case("a2", 6)
6178 .Case("a3", 7)
6179 .Case("v0", 2)
6180 .Case("v1", 3)
6181 .Case("s0", 16)
6182 .Case("s1", 17)
6183 .Case("s2", 18)
6184 .Case("s3", 19)
6185 .Case("s4", 20)
6186 .Case("s5", 21)
6187 .Case("s6", 22)
6188 .Case("s7", 23)
6189 .Case("k0", 26)
6190 .Case("k1", 27)
6191 .Case("gp", 28)
6192 .Case("sp", 29)
6193 .Case("fp", 30)
6194 .Case("s8", 30)
6195 .Case("ra", 31)
6196 .Case("t0", 8)
6197 .Case("t1", 9)
6198 .Case("t2", 10)
6199 .Case("t3", 11)
6200 .Case("t4", 12)
6201 .Case("t5", 13)
6202 .Case("t6", 14)
6203 .Case("t7", 15)
6204 .Case("t8", 24)
6205 .Case("t9", 25)
6206 .Default(-1);
6207
6208 if (!(isABI_N32() || isABI_N64()))
6209 return CC;
6210
6211 if (12 <= CC && CC <= 15) {
6212 // Name is one of t4-t7
6213 AsmToken RegTok = getLexer().peekTok();
6214 SMRange RegRange = RegTok.getLocRange();
6215
6216 StringRef FixedName = StringSwitch<StringRef>(Name)
6217 .Case("t4", "t0")
6218 .Case("t5", "t1")
6219 .Case("t6", "t2")
6220 .Case("t7", "t3")
6221 .Default("");
6222 assert(FixedName != "" && "Register name is not one of t4-t7.");
6223
6224 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6225 "Did you mean $" + FixedName + "?", RegRange);
6226 }
6227
6228 // Although SGI documentation just cuts out t0-t3 for n32/n64,
6229 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
6230 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
6231 if (8 <= CC && CC <= 11)
6232 CC += 4;
6233
6234 if (CC == -1)
6235 CC = StringSwitch<unsigned>(Name)
6236 .Case("a4", 8)
6237 .Case("a5", 9)
6238 .Case("a6", 10)
6239 .Case("a7", 11)
6240 .Case("kt0", 26)
6241 .Case("kt1", 27)
6242 .Default(-1);
6243
6244 return CC;
6245}
6246
6247int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6248 int CC;
6249
6250 CC = StringSwitch<unsigned>(Name)
6251 .Case("hwr_cpunum", 0)
6252 .Case("hwr_synci_step", 1)
6253 .Case("hwr_cc", 2)
6254 .Case("hwr_ccres", 3)
6255 .Case("hwr_ulr", 29)
6256 .Default(-1);
6257
6258 return CC;
6259}
6260
6261int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6262 if (Name[0] == 'f') {
6263 StringRef NumString = Name.substr(1);
6264 unsigned IntVal;
6265 if (NumString.getAsInteger(10, IntVal))
6266 return -1; // This is not an integer.
6267 if (IntVal > 31) // Maximum index for fpu register.
6268 return -1;
6269 return IntVal;
6270 }
6271 return -1;
6272}
6273
6274int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6275 if (Name.starts_with("fcc")) {
6276 StringRef NumString = Name.substr(3);
6277 unsigned IntVal;
6278 if (NumString.getAsInteger(10, IntVal))
6279 return -1; // This is not an integer.
6280 if (IntVal > 7) // There are only 8 fcc registers.
6281 return -1;
6282 return IntVal;
6283 }
6284 return -1;
6285}
6286
6287int MipsAsmParser::matchACRegisterName(StringRef Name) {
6288 if (Name.starts_with("ac")) {
6289 StringRef NumString = Name.substr(2);
6290 unsigned IntVal;
6291 if (NumString.getAsInteger(10, IntVal))
6292 return -1; // This is not an integer.
6293 if (IntVal > 3) // There are only 3 acc registers.
6294 return -1;
6295 return IntVal;
6296 }
6297 return -1;
6298}
6299
6300int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6301 unsigned IntVal;
6302
6303 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6304 return -1;
6305
6306 if (IntVal > 31)
6307 return -1;
6308
6309 return IntVal;
6310}
6311
6312int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6313 int CC;
6314
6315 CC = StringSwitch<unsigned>(Name)
6316 .Case("msair", 0)
6317 .Case("msacsr", 1)
6318 .Case("msaaccess", 2)
6319 .Case("msasave", 3)
6320 .Case("msamodify", 4)
6321 .Case("msarequest", 5)
6322 .Case("msamap", 6)
6323 .Case("msaunmap", 7)
6324 .Default(-1);
6325
6326 return CC;
6327}
6328
6329bool MipsAsmParser::canUseATReg() {
6330 return AssemblerOptions.back()->getATRegIndex() != 0;
6331}
6332
6333MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6334 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6335 if (ATIndex == 0) {
6336 reportParseError(Loc,
6337 "pseudo-instruction requires $at, which is not available");
6338 return 0;
6339 }
6340 MCRegister AT = getReg(
6341 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6342 return AT;
6343}
6344
6345MCRegister MipsAsmParser::getReg(int RC, int RegNo) {
6346 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6347}
6348
6349// Parse an expression with optional relocation operator prefixes (e.g. %lo).
6350// Some weird expressions allowed by gas are not supported for simplicity,
6351// e.g. "%lo foo", "(%lo(foo))", "%lo(foo)+1".
6352const MCExpr *MipsAsmParser::parseRelocExpr() {
6353 auto getOp = [](StringRef Op) {
6354 return StringSwitch<Mips::Specifier>(Op)
6355 .Case("call16", Mips::S_GOT_CALL)
6356 .Case("call_hi", Mips::S_CALL_HI16)
6357 .Case("call_lo", Mips::S_CALL_LO16)
6358 .Case("dtprel_hi", Mips::S_DTPREL_HI)
6359 .Case("dtprel_lo", Mips::S_DTPREL_LO)
6360 .Case("got", Mips::S_GOT)
6361 .Case("got_disp", Mips::S_GOT_DISP)
6362 .Case("got_hi", Mips::S_GOT_HI16)
6363 .Case("got_lo", Mips::S_GOT_LO16)
6364 .Case("got_ofst", Mips::S_GOT_OFST)
6365 .Case("got_page", Mips::S_GOT_PAGE)
6366 .Case("gottprel", Mips::S_GOTTPREL)
6367 .Case("gp_rel", Mips::S_GPREL)
6368 .Case("hi", Mips::S_HI)
6369 .Case("higher", Mips::S_HIGHER)
6370 .Case("highest", Mips::S_HIGHEST)
6371 .Case("lo", Mips::S_LO)
6372 .Case("neg", Mips::S_NEG)
6373 .Case("pcrel_hi", Mips::S_PCREL_HI16)
6374 .Case("pcrel_lo", Mips::S_PCREL_LO16)
6375 .Case("tlsgd", Mips::S_TLSGD)
6376 .Case("tlsldm", Mips::S_TLSLDM)
6377 .Case("tprel_hi", Mips::S_TPREL_HI)
6378 .Case("tprel_lo", Mips::S_TPREL_LO)
6379 .Default(Mips::S_None);
6380 };
6381
6382 MCAsmParser &Parser = getParser();
6383 StringRef Name;
6384 const MCExpr *Res = nullptr;
6386 while (parseOptionalToken(AsmToken::Percent)) {
6387 if (Parser.parseIdentifier(Name) ||
6388 Parser.parseToken(AsmToken::LParen, "expected '('"))
6389 return nullptr;
6390 auto Op = getOp(Name);
6391 if (Op == Mips::S_None) {
6392 Error(Parser.getTok().getLoc(), "invalid relocation operator");
6393 return nullptr;
6394 }
6395 Ops.push_back(Op);
6396 }
6397 if (Parser.parseExpression(Res))
6398 return nullptr;
6399 while (Ops.size()) {
6400 if (Parser.parseToken(AsmToken::RParen, "expected ')'"))
6401 return nullptr;
6402 Res = MCSpecifierExpr::create(Res, Ops.pop_back_val(), getContext());
6403 }
6404 return Res;
6405}
6406
6407bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6408 MCAsmParser &Parser = getParser();
6409 LLVM_DEBUG(dbgs() << "parseOperand\n");
6410
6411 // Check if the current operand has a custom associated parser, if so, try to
6412 // custom parse the operand, or fallback to the general approach.
6413 // Setting the third parameter to true tells the parser to keep parsing even
6414 // if the operands are not supported with the current feature set. In this
6415 // case, the instruction matcher will output a "instruction requires a CPU
6416 // feature not currently enabled" error. If this were false, the parser would
6417 // stop here and output a less useful "invalid operand" error.
6418 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic, true);
6419 if (Res.isSuccess())
6420 return false;
6421 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6422 // there was a match, but an error occurred, in which case, just return that
6423 // the operand parsing failed.
6424 if (Res.isFailure())
6425 return true;
6426
6427 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6428
6429 switch (getLexer().getKind()) {
6430 case AsmToken::Dollar: {
6431 // Parse the register.
6432 SMLoc S = Parser.getTok().getLoc();
6433
6434 // Almost all registers have been parsed by custom parsers. There is only
6435 // one exception to this. $zero (and it's alias $0) will reach this point
6436 // for div, divu, and similar instructions because it is not an operand
6437 // to the instruction definition but an explicit register. Special case
6438 // this situation for now.
6439 if (!parseAnyRegister(Operands).isNoMatch())
6440 return false;
6441
6442 // Maybe it is a symbol reference.
6443 StringRef Identifier;
6444 if (Parser.parseIdentifier(Identifier))
6445 return true;
6446
6447 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6448 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
6449 // Otherwise create a symbol reference.
6450 const MCExpr *SymRef = MCSymbolRefExpr::create(Sym, getContext());
6451
6452 Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this));
6453 return false;
6454 }
6455 default: {
6456 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6457 const MCExpr *Expr = parseRelocExpr();
6458 if (!Expr)
6459 return true;
6460 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6461 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6462 return false;
6463 }
6464 } // switch(getLexer().getKind())
6465 return true;
6466}
6467
6468bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
6469 SMLoc &EndLoc) {
6470 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6471}
6472
6473ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6474 SMLoc &EndLoc) {
6476 ParseStatus Res = parseAnyRegister(Operands);
6477 if (Res.isSuccess()) {
6478 assert(Operands.size() == 1);
6479 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6480 StartLoc = Operand.getStartLoc();
6481 EndLoc = Operand.getEndLoc();
6482
6483 // AFAIK, we only support numeric registers and named GPR's in CFI
6484 // directives.
6485 // Don't worry about eating tokens before failing. Using an unrecognised
6486 // register is a parse error.
6487 if (Operand.isGPRAsmReg()) {
6488 // Resolve to GPR32 or GPR64 appropriately.
6489 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6490 }
6491
6492 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6493 }
6494
6495 assert(Operands.size() == 0);
6496 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6497}
6498
6499ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6500 MCAsmParser &Parser = getParser();
6501 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6502 const MCExpr *IdVal = nullptr;
6503 SMLoc S;
6504 bool isParenExpr = false;
6505 ParseStatus Res = ParseStatus::NoMatch;
6506 // First operand is the offset.
6507 S = Parser.getTok().getLoc();
6508
6509 if (getLexer().getKind() == AsmToken::LParen) {
6510 Parser.Lex();
6511 isParenExpr = true;
6512 }
6513
6514 if (getLexer().getKind() != AsmToken::Dollar) {
6515 IdVal = parseRelocExpr();
6516 if (!IdVal)
6517 return ParseStatus::Failure;
6518 if (isParenExpr && Parser.parseRParen())
6519 return ParseStatus::Failure;
6520
6521 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6522 if (Tok.isNot(AsmToken::LParen)) {
6523 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6524 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6525 SMLoc E =
6527 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6528 return ParseStatus::Success;
6529 }
6530 if (Tok.is(AsmToken::EndOfStatement)) {
6531 SMLoc E =
6533
6534 // Zero register assumed, add a memory operand with ZERO as its base.
6535 // "Base" will be managed by k_Memory.
6536 auto Base = MipsOperand::createGPRReg(
6537 0, "0", getContext().getRegisterInfo(), S, E, *this);
6538 Operands.push_back(
6539 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6540 return ParseStatus::Success;
6541 }
6542 MCBinaryExpr::Opcode Opcode;
6543 // GAS and LLVM treat comparison operators different. GAS will generate -1
6544 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6545 // highly unlikely to be found in a memory offset expression, we don't
6546 // handle them.
6547 switch (Tok.getKind()) {
6548 case AsmToken::Plus:
6549 Opcode = MCBinaryExpr::Add;
6550 Parser.Lex();
6551 break;
6552 case AsmToken::Minus:
6553 Opcode = MCBinaryExpr::Sub;
6554 Parser.Lex();
6555 break;
6556 case AsmToken::Star:
6557 Opcode = MCBinaryExpr::Mul;
6558 Parser.Lex();
6559 break;
6560 case AsmToken::Pipe:
6561 Opcode = MCBinaryExpr::Or;
6562 Parser.Lex();
6563 break;
6564 case AsmToken::Amp:
6565 Opcode = MCBinaryExpr::And;
6566 Parser.Lex();
6567 break;
6568 case AsmToken::LessLess:
6569 Opcode = MCBinaryExpr::Shl;
6570 Parser.Lex();
6571 break;
6573 Opcode = MCBinaryExpr::LShr;
6574 Parser.Lex();
6575 break;
6576 case AsmToken::Caret:
6577 Opcode = MCBinaryExpr::Xor;
6578 Parser.Lex();
6579 break;
6580 case AsmToken::Slash:
6581 Opcode = MCBinaryExpr::Div;
6582 Parser.Lex();
6583 break;
6584 case AsmToken::Percent:
6585 Opcode = MCBinaryExpr::Mod;
6586 Parser.Lex();
6587 break;
6588 default:
6589 return Error(Parser.getTok().getLoc(), "'(' or expression expected");
6590 }
6591 const MCExpr * NextExpr;
6592 if (getParser().parseExpression(NextExpr))
6593 return ParseStatus::Failure;
6594 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6595 }
6596
6597 Parser.Lex(); // Eat the '(' token.
6598 }
6599
6600 Res = parseAnyRegister(Operands);
6601 if (!Res.isSuccess())
6602 return Res;
6603
6604 if (Parser.getTok().isNot(AsmToken::RParen))
6605 return Error(Parser.getTok().getLoc(), "')' expected");
6606
6607 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6608
6609 Parser.Lex(); // Eat the ')' token.
6610
6611 if (!IdVal)
6612 IdVal = MCConstantExpr::create(0, getContext());
6613
6614 // Replace the register operand with the memory operand.
6615 std::unique_ptr<MipsOperand> op(
6616 static_cast<MipsOperand *>(Operands.back().release()));
6617 // Remove the register from the operands.
6618 // "op" will be managed by k_Memory.
6619 Operands.pop_back();
6620 // Add the memory operand.
6621 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6622 int64_t Imm;
6623 if (IdVal->evaluateAsAbsolute(Imm))
6624 IdVal = MCConstantExpr::create(Imm, getContext());
6625 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6626 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6627 getContext());
6628 }
6629
6630 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6631 return ParseStatus::Success;
6632}
6633
6634bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6635 MCAsmParser &Parser = getParser();
6636 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6637 if (!Sym)
6638 return false;
6639
6640 SMLoc S = Parser.getTok().getLoc();
6641 if (Sym->isVariable()) {
6642 const MCExpr *Expr = Sym->getVariableValue();
6643 if (Expr->getKind() == MCExpr::SymbolRef) {
6644 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6645 StringRef DefSymbol = Ref->getSymbol().getName();
6646 if (DefSymbol.starts_with("$")) {
6647 ParseStatus Res =
6648 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6649 if (Res.isSuccess()) {
6650 Parser.Lex();
6651 return true;
6652 }
6653 if (Res.isFailure())
6654 llvm_unreachable("Should never fail");
6655 }
6656 }
6657 } else if (Sym->isUndefined()) {
6658 // If symbol is unset, it might be created in the `parseSetAssignment`
6659 // routine as an alias for a numeric register name.
6660 // Lookup in the aliases list.
6661 auto Entry = RegisterSets.find(Sym->getName());
6662 if (Entry != RegisterSets.end()) {
6663 ParseStatus Res =
6664 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6665 if (Res.isSuccess()) {
6666 Parser.Lex();
6667 return true;
6668 }
6669 }
6670 }
6671
6672 return false;
6673}
6674
6675ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6676 OperandVector &Operands, StringRef Identifier, SMLoc S) {
6677 int Index = matchCPURegisterName(Identifier);
6678 if (Index != -1) {
6679 Operands.push_back(MipsOperand::createGPRReg(
6680 Index, Identifier, getContext().getRegisterInfo(), S,
6681 getLexer().getLoc(), *this));
6682 return ParseStatus::Success;
6683 }
6684
6685 Index = matchHWRegsRegisterName(Identifier);
6686 if (Index != -1) {
6687 Operands.push_back(MipsOperand::createHWRegsReg(
6688 Index, Identifier, getContext().getRegisterInfo(), S,
6689 getLexer().getLoc(), *this));
6690 return ParseStatus::Success;
6691 }
6692
6693 Index = matchFPURegisterName(Identifier);
6694 if (Index != -1) {
6695 Operands.push_back(MipsOperand::createFGRReg(
6696 Index, Identifier, getContext().getRegisterInfo(), S,
6697 getLexer().getLoc(), *this));
6698 return ParseStatus::Success;
6699 }
6700
6701 Index = matchFCCRegisterName(Identifier);
6702 if (Index != -1) {
6703 Operands.push_back(MipsOperand::createFCCReg(
6704 Index, Identifier, getContext().getRegisterInfo(), S,
6705 getLexer().getLoc(), *this));
6706 return ParseStatus::Success;
6707 }
6708
6709 Index = matchACRegisterName(Identifier);
6710 if (Index != -1) {
6711 Operands.push_back(MipsOperand::createACCReg(
6712 Index, Identifier, getContext().getRegisterInfo(), S,
6713 getLexer().getLoc(), *this));
6714 return ParseStatus::Success;
6715 }
6716
6717 Index = matchMSA128RegisterName(Identifier);
6718 if (Index != -1) {
6719 Operands.push_back(MipsOperand::createMSA128Reg(
6720 Index, Identifier, getContext().getRegisterInfo(), S,
6721 getLexer().getLoc(), *this));
6722 return ParseStatus::Success;
6723 }
6724
6725 Index = matchMSA128CtrlRegisterName(Identifier);
6726 if (Index != -1) {
6727 Operands.push_back(MipsOperand::createMSACtrlReg(
6728 Index, Identifier, getContext().getRegisterInfo(), S,
6729 getLexer().getLoc(), *this));
6730 return ParseStatus::Success;
6731 }
6732
6733 return ParseStatus::NoMatch;
6734}
6735
6736ParseStatus
6737MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6738 const AsmToken &Token, SMLoc S) {
6739 if (Token.is(AsmToken::Identifier)) {
6740 LLVM_DEBUG(dbgs() << ".. identifier\n");
6741 StringRef Identifier = Token.getIdentifier();
6742 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6743 }
6744 if (Token.is(AsmToken::Integer)) {
6745 LLVM_DEBUG(dbgs() << ".. integer\n");
6746 int64_t RegNum = Token.getIntVal();
6747 if (RegNum < 0 || RegNum > 31) {
6748 // Show the error, but treat invalid register
6749 // number as a normal one to continue parsing
6750 // and catch other possible errors.
6751 Error(getLexer().getLoc(), "invalid register number");
6752 }
6753 Operands.push_back(MipsOperand::createNumericReg(
6754 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6755 Token.getLoc(), *this));
6756 return ParseStatus::Success;
6757 }
6758
6759 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6760
6761 return ParseStatus::NoMatch;
6762}
6763
6764ParseStatus
6765MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6766 auto Token = getLexer().peekTok(false);
6767 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6768}
6769
6770ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6771 MCAsmParser &Parser = getParser();
6772 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6773
6774 auto Token = Parser.getTok();
6775
6776 SMLoc S = Token.getLoc();
6777
6778 if (Token.isNot(AsmToken::Dollar)) {
6779 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6780 if (Token.is(AsmToken::Identifier)) {
6781 if (searchSymbolAlias(Operands))
6782 return ParseStatus::Success;
6783 }
6784 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6785 return ParseStatus::NoMatch;
6786 }
6787 LLVM_DEBUG(dbgs() << ".. $\n");
6788
6789 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6790 if (Res.isSuccess()) {
6791 Parser.Lex(); // $
6792 Parser.Lex(); // identifier
6793 }
6794 return Res;
6795}
6796
6797ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6798 MCAsmParser &Parser = getParser();
6799 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6800
6801 SMLoc S = getLexer().getLoc();
6802
6803 // Registers are a valid target and have priority over symbols.
6804 ParseStatus Res = parseAnyRegister(Operands);
6805 if (!Res.isNoMatch())
6806 return Res;
6807
6808 // Integers and expressions are acceptable
6809 const MCExpr *Expr = nullptr;
6810 if (Parser.parseExpression(Expr)) {
6811 // We have no way of knowing if a symbol was consumed so we must ParseFail
6812 return ParseStatus::Failure;
6813 }
6814 Operands.push_back(
6815 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6816 return ParseStatus::Success;
6817}
6818
6819ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) {
6820 MCAsmParser &Parser = getParser();
6821 const MCExpr *IdVal;
6822 // If the first token is '$' we may have register operand. We have to reject
6823 // cases where it is not a register. Complicating the matter is that
6824 // register names are not reserved across all ABIs.
6825 // Peek past the dollar to see if it's a register name for this ABI.
6826 SMLoc S = Parser.getTok().getLoc();
6827 if (Parser.getTok().is(AsmToken::Dollar)) {
6828 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6831 }
6832 if (getParser().parseExpression(IdVal))
6833 return ParseStatus::Failure;
6834 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6835 if (!MCE)
6836 return ParseStatus::NoMatch;
6837 int64_t Val = MCE->getValue();
6838 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6839 Operands.push_back(MipsOperand::CreateImm(
6840 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6841 return ParseStatus::Success;
6842}
6843
6844ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6845 MCAsmParser &Parser = getParser();
6847 unsigned RegNo;
6848 unsigned PrevReg = Mips::NoRegister;
6849 bool RegRange = false;
6851
6852 if (Parser.getTok().isNot(AsmToken::Dollar))
6853 return ParseStatus::Failure;
6854
6855 SMLoc S = Parser.getTok().getLoc();
6856 while (parseAnyRegister(TmpOperands).isSuccess()) {
6857 SMLoc E = getLexer().getLoc();
6858 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6859 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6860 if (RegRange) {
6861 // Remove last register operand because registers from register range
6862 // should be inserted first.
6863 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6864 (!isGP64bit() && RegNo == Mips::RA)) {
6865 Regs.push_back(RegNo);
6866 } else {
6867 unsigned TmpReg = PrevReg + 1;
6868 while (TmpReg <= RegNo) {
6869 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6870 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6871 isGP64bit()))
6872 return Error(E, "invalid register operand");
6873
6874 PrevReg = TmpReg;
6875 Regs.push_back(TmpReg++);
6876 }
6877 }
6878
6879 RegRange = false;
6880 } else {
6881 if ((PrevReg == Mips::NoRegister) &&
6882 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6883 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6884 return Error(E, "$16 or $31 expected");
6885 if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6886 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6887 !isGP64bit()) ||
6888 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6889 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6890 isGP64bit())))
6891 return Error(E, "invalid register operand");
6892 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6893 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6894 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6895 return Error(E, "consecutive register numbers expected");
6896
6897 Regs.push_back(RegNo);
6898 }
6899
6900 if (Parser.getTok().is(AsmToken::Minus))
6901 RegRange = true;
6902
6903 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6904 !Parser.getTok().isNot(AsmToken::Comma))
6905 return Error(E, "',' or '-' expected");
6906
6907 Lex(); // Consume comma or minus
6908 if (Parser.getTok().isNot(AsmToken::Dollar))
6909 break;
6910
6911 PrevReg = RegNo;
6912 }
6913
6914 SMLoc E = Parser.getTok().getLoc();
6915 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6916 parseMemOperand(Operands);
6917 return ParseStatus::Success;
6918}
6919
6920/// Sometimes (i.e. load/stores) the operand may be followed immediately by
6921/// either this.
6922/// ::= '(', register, ')'
6923/// handle it before we iterate so we don't get tripped up by the lack of
6924/// a comma.
6925bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6926 MCAsmParser &Parser = getParser();
6927 if (getLexer().is(AsmToken::LParen)) {
6928 Operands.push_back(
6929 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6930 Parser.Lex();
6931 if (parseOperand(Operands, Name)) {
6932 SMLoc Loc = getLexer().getLoc();
6933 return Error(Loc, "unexpected token in argument list");
6934 }
6935 if (Parser.getTok().isNot(AsmToken::RParen)) {
6936 SMLoc Loc = getLexer().getLoc();
6937 return Error(Loc, "unexpected token, expected ')'");
6938 }
6939 Operands.push_back(
6940 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6941 Parser.Lex();
6942 }
6943 return false;
6944}
6945
6946/// Sometimes (i.e. in MSA) the operand may be followed immediately by
6947/// either one of these.
6948/// ::= '[', register, ']'
6949/// ::= '[', integer, ']'
6950/// handle it before we iterate so we don't get tripped up by the lack of
6951/// a comma.
6952bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6954 MCAsmParser &Parser = getParser();
6955 if (getLexer().is(AsmToken::LBrac)) {
6956 Operands.push_back(
6957 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6958 Parser.Lex();
6959 if (parseOperand(Operands, Name)) {
6960 SMLoc Loc = getLexer().getLoc();
6961 return Error(Loc, "unexpected token in argument list");
6962 }
6963 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6964 SMLoc Loc = getLexer().getLoc();
6965 return Error(Loc, "unexpected token, expected ']'");
6966 }
6967 Operands.push_back(
6968 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6969 Parser.Lex();
6970 }
6971 return false;
6972}
6973
6974static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6975 unsigned VariantID = 0);
6976
6977bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6978 const MCParsedAsmOperand &Op2) const {
6979 // This target-overriden function exists to maintain current behaviour for
6980 // e.g.
6981 // dahi $3, $3, 0x5678
6982 // as tested in test/MC/Mips/mips64r6/valid.s.
6983 // FIXME: Should this test actually fail with an error? If so, then remove
6984 // this overloaded method.
6985 if (!Op1.isReg() || !Op2.isReg())
6986 return true;
6987 return Op1.getReg() == Op2.getReg();
6988}
6989
6990bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6991 SMLoc NameLoc, OperandVector &Operands) {
6992 MCAsmParser &Parser = getParser();
6993 LLVM_DEBUG(dbgs() << "parseInstruction\n");
6994
6995 // We have reached first instruction, module directive are now forbidden.
6996 getTargetStreamer().forbidModuleDirective();
6997
6998 // Check if we have valid mnemonic
6999 if (!mnemonicIsValid(Name, 0)) {
7000 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7001 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
7002 return Error(NameLoc, "unknown instruction" + Suggestion);
7003 }
7004 // First operand in MCInst is instruction mnemonic.
7005 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
7006
7007 // Read the remaining operands.
7008 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7009 // Read the first operand.
7010 if (parseOperand(Operands, Name)) {
7011 SMLoc Loc = getLexer().getLoc();
7012 return Error(Loc, "unexpected token in argument list");
7013 }
7014 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7015 return true;
7016 // AFAIK, parenthesis suffixes are never on the first operand
7017
7018 while (getLexer().is(AsmToken::Comma)) {
7019 Parser.Lex(); // Eat the comma.
7020 // Parse and remember the operand.
7021 if (parseOperand(Operands, Name)) {
7022 SMLoc Loc = getLexer().getLoc();
7023 return Error(Loc, "unexpected token in argument list");
7024 }
7025 // Parse bracket and parenthesis suffixes before we iterate
7026 if (getLexer().is(AsmToken::LBrac)) {
7027 if (parseBracketSuffix(Name, Operands))
7028 return true;
7029 } else if (getLexer().is(AsmToken::LParen) &&
7030 parseParenSuffix(Name, Operands))
7031 return true;
7032 }
7033 }
7034 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7035 SMLoc Loc = getLexer().getLoc();
7036 return Error(Loc, "unexpected token in argument list");
7037 }
7038 Parser.Lex(); // Consume the EndOfStatement.
7039 return false;
7040}
7041
7042// FIXME: Given that these have the same name, these should both be
7043// consistent on affecting the Parser.
7044bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
7045 SMLoc Loc = getLexer().getLoc();
7046 return Error(Loc, ErrorMsg);
7047}
7048
7049bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
7050 return Error(Loc, ErrorMsg);
7051}
7052
7053bool MipsAsmParser::parseSetNoAtDirective() {
7054 MCAsmParser &Parser = getParser();
7055 // Line should look like: ".set noat".
7056
7057 // Set the $at register to $0.
7058 AssemblerOptions.back()->setATRegIndex(0);
7059
7060 Parser.Lex(); // Eat "noat".
7061
7062 // If this is not the end of the statement, report an error.
7063 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7064 reportParseError("unexpected token, expected end of statement");
7065 return false;
7066 }
7067
7068 getTargetStreamer().emitDirectiveSetNoAt();
7069 Parser.Lex(); // Consume the EndOfStatement.
7070 return false;
7071}
7072
7073bool MipsAsmParser::parseSetAtDirective() {
7074 // Line can be: ".set at", which sets $at to $1
7075 // or ".set at=$reg", which sets $at to $reg.
7076 MCAsmParser &Parser = getParser();
7077 Parser.Lex(); // Eat "at".
7078
7079 if (getLexer().is(AsmToken::EndOfStatement)) {
7080 // No register was specified, so we set $at to $1.
7081 AssemblerOptions.back()->setATRegIndex(1);
7082
7083 getTargetStreamer().emitDirectiveSetAt();
7084 Parser.Lex(); // Consume the EndOfStatement.
7085 return false;
7086 }
7087
7088 if (getLexer().isNot(AsmToken::Equal)) {
7089 reportParseError("unexpected token, expected equals sign");
7090 return false;
7091 }
7092 Parser.Lex(); // Eat "=".
7093
7094 if (getLexer().isNot(AsmToken::Dollar)) {
7095 if (getLexer().is(AsmToken::EndOfStatement)) {
7096 reportParseError("no register specified");
7097 return false;
7098 } else {
7099 reportParseError("unexpected token, expected dollar sign '$'");
7100 return false;
7101 }
7102 }
7103 Parser.Lex(); // Eat "$".
7104
7105 // Find out what "reg" is.
7106 unsigned AtRegNo;
7107 const AsmToken &Reg = Parser.getTok();
7108 if (Reg.is(AsmToken::Identifier)) {
7109 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7110 } else if (Reg.is(AsmToken::Integer)) {
7111 AtRegNo = Reg.getIntVal();
7112 } else {
7113 reportParseError("unexpected token, expected identifier or integer");
7114 return false;
7115 }
7116
7117 // Check if $reg is a valid register. If it is, set $at to $reg.
7118 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7119 reportParseError("invalid register");
7120 return false;
7121 }
7122 Parser.Lex(); // Eat "reg".
7123
7124 // If this is not the end of the statement, report an error.
7125 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7126 reportParseError("unexpected token, expected end of statement");
7127 return false;
7128 }
7129
7130 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7131
7132 Parser.Lex(); // Consume the EndOfStatement.
7133 return false;
7134}
7135
7136bool MipsAsmParser::parseSetReorderDirective() {
7137 MCAsmParser &Parser = getParser();
7138 Parser.Lex();
7139 // If this is not the end of the statement, report an error.
7140 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7141 reportParseError("unexpected token, expected end of statement");
7142 return false;
7143 }
7144 AssemblerOptions.back()->setReorder();
7145 getTargetStreamer().emitDirectiveSetReorder();
7146 Parser.Lex(); // Consume the EndOfStatement.
7147 return false;
7148}
7149
7150bool MipsAsmParser::parseSetNoReorderDirective() {
7151 MCAsmParser &Parser = getParser();
7152 Parser.Lex();
7153 // If this is not the end of the statement, report an error.
7154 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7155 reportParseError("unexpected token, expected end of statement");
7156 return false;
7157 }
7158 AssemblerOptions.back()->setNoReorder();
7159 getTargetStreamer().emitDirectiveSetNoReorder();
7160 Parser.Lex(); // Consume the EndOfStatement.
7161 return false;
7162}
7163
7164bool MipsAsmParser::parseSetMacroDirective() {
7165 MCAsmParser &Parser = getParser();
7166 Parser.Lex();
7167 // If this is not the end of the statement, report an error.
7168 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7169 reportParseError("unexpected token, expected end of statement");
7170 return false;
7171 }
7172 AssemblerOptions.back()->setMacro();
7173 getTargetStreamer().emitDirectiveSetMacro();
7174 Parser.Lex(); // Consume the EndOfStatement.
7175 return false;
7176}
7177
7178bool MipsAsmParser::parseSetNoMacroDirective() {
7179 MCAsmParser &Parser = getParser();
7180 Parser.Lex();
7181 // If this is not the end of the statement, report an error.
7182 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7183 reportParseError("unexpected token, expected end of statement");
7184 return false;
7185 }
7186 if (AssemblerOptions.back()->isReorder()) {
7187 reportParseError("`noreorder' must be set before `nomacro'");
7188 return false;
7189 }
7190 AssemblerOptions.back()->setNoMacro();
7191 getTargetStreamer().emitDirectiveSetNoMacro();
7192 Parser.Lex(); // Consume the EndOfStatement.
7193 return false;
7194}
7195
7196bool MipsAsmParser::parseSetMsaDirective() {
7197 MCAsmParser &Parser = getParser();
7198 Parser.Lex();
7199
7200 // If this is not the end of the statement, report an error.
7201 if (getLexer().isNot(AsmToken::EndOfStatement))
7202 return reportParseError("unexpected token, expected end of statement");
7203
7204 setFeatureBits(Mips::FeatureMSA, "msa");
7205 getTargetStreamer().emitDirectiveSetMsa();
7206 return false;
7207}
7208
7209bool MipsAsmParser::parseSetNoMsaDirective() {
7210 MCAsmParser &Parser = getParser();
7211 Parser.Lex();
7212
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");
7216
7217 clearFeatureBits(Mips::FeatureMSA, "msa");
7218 getTargetStreamer().emitDirectiveSetNoMsa();
7219 return false;
7220}
7221
7222bool MipsAsmParser::parseSetNoDspDirective() {
7223 MCAsmParser &Parser = getParser();
7224 Parser.Lex(); // Eat "nodsp".
7225
7226 // If this is not the end of the statement, report an error.
7227 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7228 reportParseError("unexpected token, expected end of statement");
7229 return false;
7230 }
7231
7232 clearFeatureBits(Mips::FeatureDSP, "dsp");
7233 getTargetStreamer().emitDirectiveSetNoDsp();
7234 return false;
7235}
7236
7237bool MipsAsmParser::parseSetNoMips3DDirective() {
7238 MCAsmParser &Parser = getParser();
7239 Parser.Lex(); // Eat "nomips3d".
7240
7241 // If this is not the end of the statement, report an error.
7242 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7243 reportParseError("unexpected token, expected end of statement");
7244 return false;
7245 }
7246
7247 clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7248 getTargetStreamer().emitDirectiveSetNoMips3D();
7249 return false;
7250}
7251
7252bool MipsAsmParser::parseSetMips16Directive() {
7253 MCAsmParser &Parser = getParser();
7254 Parser.Lex(); // Eat "mips16".
7255
7256 // If this is not the end of the statement, report an error.
7257 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7258 reportParseError("unexpected token, expected end of statement");
7259 return false;
7260 }
7261
7262 setFeatureBits(Mips::FeatureMips16, "mips16");
7263 getTargetStreamer().emitDirectiveSetMips16();
7264 Parser.Lex(); // Consume the EndOfStatement.
7265 return false;
7266}
7267
7268bool MipsAsmParser::parseSetNoMips16Directive() {
7269 MCAsmParser &Parser = getParser();
7270 Parser.Lex(); // Eat "nomips16".
7271
7272 // If this is not the end of the statement, report an error.
7273 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7274 reportParseError("unexpected token, expected end of statement");
7275 return false;
7276 }
7277
7278 clearFeatureBits(Mips::FeatureMips16, "mips16");
7279 getTargetStreamer().emitDirectiveSetNoMips16();
7280 Parser.Lex(); // Consume the EndOfStatement.
7281 return false;
7282}
7283
7284bool MipsAsmParser::parseSetFpDirective() {
7285 MCAsmParser &Parser = getParser();
7287 // Line can be: .set fp=32
7288 // .set fp=xx
7289 // .set fp=64
7290 Parser.Lex(); // Eat fp token
7291 AsmToken Tok = Parser.getTok();
7292 if (Tok.isNot(AsmToken::Equal)) {
7293 reportParseError("unexpected token, expected equals sign '='");
7294 return false;
7295 }
7296 Parser.Lex(); // Eat '=' token.
7297 Tok = Parser.getTok();
7298
7299 if (!parseFpABIValue(FpAbiVal, ".set"))
7300 return false;
7301
7302 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7303 reportParseError("unexpected token, expected end of statement");
7304 return false;
7305 }
7306 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7307 Parser.Lex(); // Consume the EndOfStatement.
7308 return false;
7309}
7310
7311bool MipsAsmParser::parseSetOddSPRegDirective() {
7312 MCAsmParser &Parser = getParser();
7313
7314 Parser.Lex(); // Eat "oddspreg".
7315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7316 reportParseError("unexpected token, expected end of statement");
7317 return false;
7318 }
7319
7320 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7321 getTargetStreamer().emitDirectiveSetOddSPReg();
7322 return false;
7323}
7324
7325bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7326 MCAsmParser &Parser = getParser();
7327
7328 Parser.Lex(); // Eat "nooddspreg".
7329 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7330 reportParseError("unexpected token, expected end of statement");
7331 return false;
7332 }
7333
7334 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7335 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7336 return false;
7337}
7338
7339bool MipsAsmParser::parseSetMtDirective() {
7340 MCAsmParser &Parser = getParser();
7341 Parser.Lex(); // Eat "mt".
7342
7343 // If this is not the end of the statement, report an error.
7344 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7345 reportParseError("unexpected token, expected end of statement");
7346 return false;
7347 }
7348
7349 setFeatureBits(Mips::FeatureMT, "mt");
7350 getTargetStreamer().emitDirectiveSetMt();
7351 Parser.Lex(); // Consume the EndOfStatement.
7352 return false;
7353}
7354
7355bool MipsAsmParser::parseSetNoMtDirective() {
7356 MCAsmParser &Parser = getParser();
7357 Parser.Lex(); // Eat "nomt".
7358
7359 // If this is not the end of the statement, report an error.
7360 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7361 reportParseError("unexpected token, expected end of statement");
7362 return false;
7363 }
7364
7365 clearFeatureBits(Mips::FeatureMT, "mt");
7366
7367 getTargetStreamer().emitDirectiveSetNoMt();
7368 Parser.Lex(); // Consume the EndOfStatement.
7369 return false;
7370}
7371
7372bool MipsAsmParser::parseSetNoCRCDirective() {
7373 MCAsmParser &Parser = getParser();
7374 Parser.Lex(); // Eat "nocrc".
7375
7376 // If this is not the end of the statement, report an error.
7377 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7378 reportParseError("unexpected token, expected end of statement");
7379 return false;
7380 }
7381
7382 clearFeatureBits(Mips::FeatureCRC, "crc");
7383
7384 getTargetStreamer().emitDirectiveSetNoCRC();
7385 Parser.Lex(); // Consume the EndOfStatement.
7386 return false;
7387}
7388
7389bool MipsAsmParser::parseSetNoVirtDirective() {
7390 MCAsmParser &Parser = getParser();
7391 Parser.Lex(); // Eat "novirt".
7392
7393 // If this is not the end of the statement, report an error.
7394 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7395 reportParseError("unexpected token, expected end of statement");
7396 return false;
7397 }
7398
7399 clearFeatureBits(Mips::FeatureVirt, "virt");
7400
7401 getTargetStreamer().emitDirectiveSetNoVirt();
7402 Parser.Lex(); // Consume the EndOfStatement.
7403 return false;
7404}
7405
7406bool MipsAsmParser::parseSetNoGINVDirective() {
7407 MCAsmParser &Parser = getParser();
7408 Parser.Lex(); // Eat "noginv".
7409
7410 // If this is not the end of the statement, report an error.
7411 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7412 reportParseError("unexpected token, expected end of statement");
7413 return false;
7414 }
7415
7416 clearFeatureBits(Mips::FeatureGINV, "ginv");
7417
7418 getTargetStreamer().emitDirectiveSetNoGINV();
7419 Parser.Lex(); // Consume the EndOfStatement.
7420 return false;
7421}
7422
7423bool MipsAsmParser::parseSetPopDirective() {
7424 MCAsmParser &Parser = getParser();
7425 SMLoc Loc = getLexer().getLoc();
7426
7427 Parser.Lex();
7428 if (getLexer().isNot(AsmToken::EndOfStatement))
7429 return reportParseError("unexpected token, expected end of statement");
7430
7431 // Always keep an element on the options "stack" to prevent the user
7432 // from changing the initial options. This is how we remember them.
7433 if (AssemblerOptions.size() == 2)
7434 return reportParseError(Loc, ".set pop with no .set push");
7435
7436 MCSubtargetInfo &STI = copySTI();
7437 AssemblerOptions.pop_back();
7438 setAvailableFeatures(
7439 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7440 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7441
7442 getTargetStreamer().emitDirectiveSetPop();
7443 return false;
7444}
7445
7446bool MipsAsmParser::parseSetPushDirective() {
7447 MCAsmParser &Parser = getParser();
7448 Parser.Lex();
7449 if (getLexer().isNot(AsmToken::EndOfStatement))
7450 return reportParseError("unexpected token, expected end of statement");
7451
7452 // Create a copy of the current assembler options environment and push it.
7453 AssemblerOptions.push_back(
7454 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7455
7456 getTargetStreamer().emitDirectiveSetPush();
7457 return false;
7458}
7459
7460bool MipsAsmParser::parseSetSoftFloatDirective() {
7461 MCAsmParser &Parser = getParser();
7462 Parser.Lex();
7463 if (getLexer().isNot(AsmToken::EndOfStatement))
7464 return reportParseError("unexpected token, expected end of statement");
7465
7466 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7467 getTargetStreamer().emitDirectiveSetSoftFloat();
7468 return false;
7469}
7470
7471bool MipsAsmParser::parseSetHardFloatDirective() {
7472 MCAsmParser &Parser = getParser();
7473 Parser.Lex();
7474 if (getLexer().isNot(AsmToken::EndOfStatement))
7475 return reportParseError("unexpected token, expected end of statement");
7476
7477 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7478 getTargetStreamer().emitDirectiveSetHardFloat();
7479 return false;
7480}
7481
7482bool MipsAsmParser::parseSetAssignment() {
7483 StringRef Name;
7484 MCAsmParser &Parser = getParser();
7485
7486 if (Parser.parseIdentifier(Name))
7487 return reportParseError("expected identifier after .set");
7488
7489 if (getLexer().isNot(AsmToken::Comma))
7490 return reportParseError("unexpected token, expected comma");
7491 Lex(); // Eat comma
7492
7493 if (getLexer().is(AsmToken::Dollar) &&
7494 getLexer().peekTok().is(AsmToken::Integer)) {
7495 // Parse assignment of a numeric register:
7496 // .set r1,$1
7497 Parser.Lex(); // Eat $.
7498 RegisterSets[Name] = Parser.getTok();
7499 Parser.Lex(); // Eat identifier.
7500 getContext().getOrCreateSymbol(Name);
7501 return false;
7502 }
7503
7504 MCSymbol *Sym;
7505 const MCExpr *Value;
7506 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7507 Parser, Sym, Value))
7508 return true;
7509 getStreamer().emitAssignment(Sym, Value);
7510
7511 return false;
7512}
7513
7514bool MipsAsmParser::parseSetMips0Directive() {
7515 MCAsmParser &Parser = getParser();
7516 Parser.Lex();
7517 if (getLexer().isNot(AsmToken::EndOfStatement))
7518 return reportParseError("unexpected token, expected end of statement");
7519
7520 // Reset assembler options to their initial values.
7521 MCSubtargetInfo &STI = copySTI();
7522 setAvailableFeatures(
7523 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7524 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7525 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7526
7527 getTargetStreamer().emitDirectiveSetMips0();
7528 return false;
7529}
7530
7531bool MipsAsmParser::parseSetArchDirective() {
7532 MCAsmParser &Parser = getParser();
7533 Parser.Lex();
7534 if (getLexer().isNot(AsmToken::Equal))
7535 return reportParseError("unexpected token, expected equals sign");
7536
7537 Parser.Lex();
7538 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7539 if (Arch.empty())
7540 return reportParseError("expected arch identifier");
7541
7542 StringRef ArchFeatureName =
7543 StringSwitch<StringRef>(Arch)
7544 .Case("mips1", "mips1")
7545 .Case("mips2", "mips2")
7546 .Case("mips3", "mips3")
7547 .Case("mips4", "mips4")
7548 .Case("mips5", "mips5")
7549 .Case("mips32", "mips32")
7550 .Case("mips32r2", "mips32r2")
7551 .Case("mips32r3", "mips32r3")
7552 .Case("mips32r5", "mips32r5")
7553 .Case("mips32r6", "mips32r6")
7554 .Case("mips64", "mips64")
7555 .Case("mips64r2", "mips64r2")
7556 .Case("mips64r3", "mips64r3")
7557 .Case("mips64r5", "mips64r5")
7558 .Case("mips64r6", "mips64r6")
7559 .Case("octeon", "cnmips")
7560 .Case("octeon+", "cnmipsp")
7561 .Case("r4000", "mips3") // This is an implementation of Mips3.
7562 .Default("");
7563
7564 if (ArchFeatureName.empty())
7565 return reportParseError("unsupported architecture");
7566
7567 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7568 return reportParseError("mips64r6 does not support microMIPS");
7569
7570 selectArch(ArchFeatureName);
7571 getTargetStreamer().emitDirectiveSetArch(Arch);
7572 return false;
7573}
7574
7575bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7576 MCAsmParser &Parser = getParser();
7577 Parser.Lex();
7578 if (getLexer().isNot(AsmToken::EndOfStatement))
7579 return reportParseError("unexpected token, expected end of statement");
7580
7581 switch (Feature) {
7582 default:
7583 llvm_unreachable("Unimplemented feature");
7584 case Mips::FeatureMips3D:
7585 setFeatureBits(Mips::FeatureMips3D, "mips3d");
7586 getTargetStreamer().emitDirectiveSetMips3D();
7587 break;
7588 case Mips::FeatureDSP:
7589 setFeatureBits(Mips::FeatureDSP, "dsp");
7590 getTargetStreamer().emitDirectiveSetDsp();
7591 break;
7592 case Mips::FeatureDSPR2:
7593 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7594 getTargetStreamer().emitDirectiveSetDspr2();
7595 break;
7596 case Mips::FeatureMicroMips:
7597 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7598 getTargetStreamer().emitDirectiveSetMicroMips();
7599 break;
7600 case Mips::FeatureMips1:
7601 selectArch("mips1");
7602 getTargetStreamer().emitDirectiveSetMips1();
7603 break;
7604 case Mips::FeatureMips2:
7605 selectArch("mips2");
7606 getTargetStreamer().emitDirectiveSetMips2();
7607 break;
7608 case Mips::FeatureMips3:
7609 selectArch("mips3");
7610 getTargetStreamer().emitDirectiveSetMips3();
7611 break;
7612 case Mips::FeatureMips4:
7613 selectArch("mips4");
7614 getTargetStreamer().emitDirectiveSetMips4();
7615 break;
7616 case Mips::FeatureMips5:
7617 selectArch("mips5");
7618 getTargetStreamer().emitDirectiveSetMips5();
7619 break;
7620 case Mips::FeatureMips32:
7621 selectArch("mips32");
7622 getTargetStreamer().emitDirectiveSetMips32();
7623 break;
7624 case Mips::FeatureMips32r2:
7625 selectArch("mips32r2");
7626 getTargetStreamer().emitDirectiveSetMips32R2();
7627 break;
7628 case Mips::FeatureMips32r3:
7629 selectArch("mips32r3");
7630 getTargetStreamer().emitDirectiveSetMips32R3();
7631 break;
7632 case Mips::FeatureMips32r5:
7633 selectArch("mips32r5");
7634 getTargetStreamer().emitDirectiveSetMips32R5();
7635 break;
7636 case Mips::FeatureMips32r6:
7637 selectArch("mips32r6");
7638 getTargetStreamer().emitDirectiveSetMips32R6();
7639 break;
7640 case Mips::FeatureMips64:
7641 selectArch("mips64");
7642 getTargetStreamer().emitDirectiveSetMips64();
7643 break;
7644 case Mips::FeatureMips64r2:
7645 selectArch("mips64r2");
7646 getTargetStreamer().emitDirectiveSetMips64R2();
7647 break;
7648 case Mips::FeatureMips64r3:
7649 selectArch("mips64r3");
7650 getTargetStreamer().emitDirectiveSetMips64R3();
7651 break;
7652 case Mips::FeatureMips64r5:
7653 selectArch("mips64r5");
7654 getTargetStreamer().emitDirectiveSetMips64R5();
7655 break;
7656 case Mips::FeatureMips64r6:
7657 selectArch("mips64r6");
7658 getTargetStreamer().emitDirectiveSetMips64R6();
7659 break;
7660 case Mips::FeatureCRC:
7661 setFeatureBits(Mips::FeatureCRC, "crc");
7662 getTargetStreamer().emitDirectiveSetCRC();
7663 break;
7664 case Mips::FeatureVirt:
7665 setFeatureBits(Mips::FeatureVirt, "virt");
7666 getTargetStreamer().emitDirectiveSetVirt();
7667 break;
7668 case Mips::FeatureGINV:
7669 setFeatureBits(Mips::FeatureGINV, "ginv");
7670 getTargetStreamer().emitDirectiveSetGINV();
7671 break;
7672 }
7673 return false;
7674}
7675
7676bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7677 MCAsmParser &Parser = getParser();
7678 if (getLexer().isNot(AsmToken::Comma)) {
7679 SMLoc Loc = getLexer().getLoc();
7680 return Error(Loc, ErrorStr);
7681 }
7682
7683 Parser.Lex(); // Eat the comma.
7684 return true;
7685}
7686
7687// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7688// In this class, it is only used for .cprestore.
7689// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7690// MipsTargetELFStreamer and MipsAsmParser.
7691bool MipsAsmParser::isPicAndNotNxxAbi() {
7692 return inPicMode() && !(isABI_N32() || isABI_N64());
7693}
7694
7695bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7697 ParseStatus Res = parseAnyRegister(Reg);
7698 if (Res.isNoMatch() || Res.isFailure()) {
7699 reportParseError("expected register");
7700 return false;
7701 }
7702
7703 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7704 if (!RegOpnd.isGPRAsmReg()) {
7705 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7706 return false;
7707 }
7708
7709 // If this is not the end of the statement, report an error.
7710 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7711 reportParseError("unexpected token, expected end of statement");
7712 return false;
7713 }
7714 getParser().Lex(); // Consume the EndOfStatement.
7715
7716 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7717 return false;
7718}
7719
7720bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7721 if (AssemblerOptions.back()->isReorder())
7722 Warning(Loc, ".cpload should be inside a noreorder section");
7723
7724 if (inMips16Mode()) {
7725 reportParseError(".cpload is not supported in Mips16 mode");
7726 return false;
7727 }
7728
7730 ParseStatus Res = parseAnyRegister(Reg);
7731 if (Res.isNoMatch() || Res.isFailure()) {
7732 reportParseError("expected register containing function address");
7733 return false;
7734 }
7735
7736 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7737 if (!RegOpnd.isGPRAsmReg()) {
7738 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7739 return false;
7740 }
7741
7742 // If this is not the end of the statement, report an error.
7743 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7744 reportParseError("unexpected token, expected end of statement");
7745 return false;
7746 }
7747
7748 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7749 return false;
7750}
7751
7752bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7753 if (!isABI_N32() && !isABI_N64()) {
7754 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7755 return false;
7756 }
7757
7759 ParseStatus Res = parseAnyRegister(Reg);
7760 if (Res.isNoMatch() || Res.isFailure()) {
7761 reportParseError("expected register containing global pointer");
7762 return false;
7763 }
7764
7765 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7766 if (!RegOpnd.isGPRAsmReg()) {
7767 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7768 return false;
7769 }
7770
7771 // If this is not the end of the statement, report an error.
7772 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7773 reportParseError("unexpected token, expected end of statement");
7774 return false;
7775 }
7776 getParser().Lex(); // Consume the EndOfStatement.
7777
7778 unsigned NewReg = RegOpnd.getGPR32Reg();
7779 if (IsPicEnabled)
7780 GPReg = NewReg;
7781
7782 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7783 return false;
7784}
7785
7786bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7787 MCAsmParser &Parser = getParser();
7788
7789 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7790 // is used in non-PIC mode.
7791
7792 if (inMips16Mode()) {
7793 reportParseError(".cprestore is not supported in Mips16 mode");
7794 return false;
7795 }
7796
7797 // Get the stack offset value.
7798 const MCExpr *StackOffset;
7799 int64_t StackOffsetVal;
7800 if (Parser.parseExpression(StackOffset)) {
7801 reportParseError("expected stack offset value");
7802 return false;
7803 }
7804
7805 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7806 reportParseError("stack offset is not an absolute expression");
7807 return false;
7808 }
7809
7810 if (StackOffsetVal < 0) {
7811 Warning(Loc, ".cprestore with negative stack offset has no effect");
7812 IsCpRestoreSet = false;
7813 } else {
7814 IsCpRestoreSet = true;
7815 CpRestoreOffset = StackOffsetVal;
7816 }
7817
7818 // If this is not the end of the statement, report an error.
7819 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7820 reportParseError("unexpected token, expected end of statement");
7821 return false;
7822 }
7823
7824 if (!getTargetStreamer().emitDirectiveCpRestore(
7825 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7826 return true;
7827 Parser.Lex(); // Consume the EndOfStatement.
7828 return false;
7829}
7830
7831bool MipsAsmParser::parseDirectiveCPSetup() {
7832 MCAsmParser &Parser = getParser();
7833 unsigned FuncReg;
7834 unsigned Save;
7835 bool SaveIsReg = true;
7836
7838 ParseStatus Res = parseAnyRegister(TmpReg);
7839 if (Res.isNoMatch()) {
7840 reportParseError("expected register containing function address");
7841 return false;
7842 }
7843
7844 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7845 if (!FuncRegOpnd.isGPRAsmReg()) {
7846 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7847 return false;
7848 }
7849
7850 FuncReg = FuncRegOpnd.getGPR32Reg();
7851 TmpReg.clear();
7852
7853 if (!eatComma("unexpected token, expected comma"))
7854 return true;
7855
7856 Res = parseAnyRegister(TmpReg);
7857 if (Res.isNoMatch()) {
7858 const MCExpr *OffsetExpr;
7859 int64_t OffsetVal;
7860 SMLoc ExprLoc = getLexer().getLoc();
7861
7862 if (Parser.parseExpression(OffsetExpr) ||
7863 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7864 reportParseError(ExprLoc, "expected save register or stack offset");
7865 return false;
7866 }
7867
7868 Save = OffsetVal;
7869 SaveIsReg = false;
7870 } else {
7871 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7872 if (!SaveOpnd.isGPRAsmReg()) {
7873 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7874 return false;
7875 }
7876 Save = SaveOpnd.getGPR32Reg();
7877 }
7878
7879 if (!eatComma("unexpected token, expected comma"))
7880 return true;
7881
7882 const MCExpr *Expr;
7883 if (Parser.parseExpression(Expr)) {
7884 reportParseError("expected expression");
7885 return false;
7886 }
7887
7888 if (Expr->getKind() != MCExpr::SymbolRef) {
7889 reportParseError("expected symbol");
7890 return false;
7891 }
7892 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7893
7894 CpSaveLocation = Save;
7895 CpSaveLocationIsRegister = SaveIsReg;
7896
7897 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7898 SaveIsReg);
7899 return false;
7900}
7901
7902bool MipsAsmParser::parseDirectiveCPReturn() {
7903 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7904 CpSaveLocationIsRegister);
7905 return false;
7906}
7907
7908bool MipsAsmParser::parseDirectiveNaN() {
7909 MCAsmParser &Parser = getParser();
7910 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7911 const AsmToken &Tok = Parser.getTok();
7912
7913 if (Tok.getString() == "2008") {
7914 Parser.Lex();
7915 getTargetStreamer().emitDirectiveNaN2008();
7916 return false;
7917 } else if (Tok.getString() == "legacy") {
7918 Parser.Lex();
7919 getTargetStreamer().emitDirectiveNaNLegacy();
7920 return false;
7921 }
7922 }
7923 // If we don't recognize the option passed to the .nan
7924 // directive (e.g. no option or unknown option), emit an error.
7925 reportParseError("invalid option in .nan directive");
7926 return false;
7927}
7928
7929bool MipsAsmParser::parseDirectiveSet() {
7930 const AsmToken &Tok = getParser().getTok();
7931 StringRef IdVal = Tok.getString();
7932 SMLoc Loc = Tok.getLoc();
7933
7934 if (IdVal == "noat")
7935 return parseSetNoAtDirective();
7936 if (IdVal == "at")
7937 return parseSetAtDirective();
7938 if (IdVal == "arch")
7939 return parseSetArchDirective();
7940 if (IdVal == "bopt") {
7941 Warning(Loc, "'bopt' feature is unsupported");
7942 getParser().Lex();
7943 return false;
7944 }
7945 if (IdVal == "nobopt") {
7946 // We're already running in nobopt mode, so nothing to do.
7947 getParser().Lex();
7948 return false;
7949 }
7950 if (IdVal == "fp")
7951 return parseSetFpDirective();
7952 if (IdVal == "oddspreg")
7953 return parseSetOddSPRegDirective();
7954 if (IdVal == "nooddspreg")
7955 return parseSetNoOddSPRegDirective();
7956 if (IdVal == "pop")
7957 return parseSetPopDirective();
7958 if (IdVal == "push")
7959 return parseSetPushDirective();
7960 if (IdVal == "reorder")
7961 return parseSetReorderDirective();
7962 if (IdVal == "noreorder")
7963 return parseSetNoReorderDirective();
7964 if (IdVal == "macro")
7965 return parseSetMacroDirective();
7966 if (IdVal == "nomacro")
7967 return parseSetNoMacroDirective();
7968 if (IdVal == "mips16")
7969 return parseSetMips16Directive();
7970 if (IdVal == "nomips16")
7971 return parseSetNoMips16Directive();
7972 if (IdVal == "nomicromips") {
7973 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7974 getTargetStreamer().emitDirectiveSetNoMicroMips();
7975 getParser().eatToEndOfStatement();
7976 return false;
7977 }
7978 if (IdVal == "micromips") {
7979 if (hasMips64r6()) {
7980 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7981 return false;
7982 }
7983 return parseSetFeature(Mips::FeatureMicroMips);
7984 }
7985 if (IdVal == "mips0")
7986 return parseSetMips0Directive();
7987 if (IdVal == "mips1")
7988 return parseSetFeature(Mips::FeatureMips1);
7989 if (IdVal == "mips2")
7990 return parseSetFeature(Mips::FeatureMips2);
7991 if (IdVal == "mips3")
7992 return parseSetFeature(Mips::FeatureMips3);
7993 if (IdVal == "mips4")
7994 return parseSetFeature(Mips::FeatureMips4);
7995 if (IdVal == "mips5")
7996 return parseSetFeature(Mips::FeatureMips5);
7997 if (IdVal == "mips32")
7998 return parseSetFeature(Mips::FeatureMips32);
7999 if (IdVal == "mips32r2")
8000 return parseSetFeature(Mips::FeatureMips32r2);
8001 if (IdVal == "mips32r3")
8002 return parseSetFeature(Mips::FeatureMips32r3);
8003 if (IdVal == "mips32r5")
8004 return parseSetFeature(Mips::FeatureMips32r5);
8005 if (IdVal == "mips32r6")
8006 return parseSetFeature(Mips::FeatureMips32r6);
8007 if (IdVal == "mips64")
8008 return parseSetFeature(Mips::FeatureMips64);
8009 if (IdVal == "mips64r2")
8010 return parseSetFeature(Mips::FeatureMips64r2);
8011 if (IdVal == "mips64r3")
8012 return parseSetFeature(Mips::FeatureMips64r3);
8013 if (IdVal == "mips64r5")
8014 return parseSetFeature(Mips::FeatureMips64r5);
8015 if (IdVal == "mips64r6") {
8016 if (inMicroMipsMode()) {
8017 Error(Loc, "MIPS64R6 is not supported with microMIPS");
8018 return false;
8019 }
8020 return parseSetFeature(Mips::FeatureMips64r6);
8021 }
8022 if (IdVal == "dsp")
8023 return parseSetFeature(Mips::FeatureDSP);
8024 if (IdVal == "dspr2")
8025 return parseSetFeature(Mips::FeatureDSPR2);
8026 if (IdVal == "nodsp")
8027 return parseSetNoDspDirective();
8028 if (IdVal == "mips3d")
8029 return parseSetFeature(Mips::FeatureMips3D);
8030 if (IdVal == "nomips3d")
8031 return parseSetNoMips3DDirective();
8032 if (IdVal == "msa")
8033 return parseSetMsaDirective();
8034 if (IdVal == "nomsa")
8035 return parseSetNoMsaDirective();
8036 if (IdVal == "mt")
8037 return parseSetMtDirective();
8038 if (IdVal == "nomt")
8039 return parseSetNoMtDirective();
8040 if (IdVal == "softfloat")
8041 return parseSetSoftFloatDirective();
8042 if (IdVal == "hardfloat")
8043 return parseSetHardFloatDirective();
8044 if (IdVal == "crc")
8045 return parseSetFeature(Mips::FeatureCRC);
8046 if (IdVal == "nocrc")
8047 return parseSetNoCRCDirective();
8048 if (IdVal == "virt")
8049 return parseSetFeature(Mips::FeatureVirt);
8050 if (IdVal == "novirt")
8051 return parseSetNoVirtDirective();
8052 if (IdVal == "ginv")
8053 return parseSetFeature(Mips::FeatureGINV);
8054 if (IdVal == "noginv")
8055 return parseSetNoGINVDirective();
8056
8057 // It is just an identifier, look for an assignment.
8058 return parseSetAssignment();
8059}
8060
8061/// parseDirectiveGpWord
8062/// ::= .gpword local_sym
8063bool MipsAsmParser::parseDirectiveGpWord() {
8064 const MCExpr *Value;
8065 if (getParser().parseExpression(Value))
8066 return true;
8067 getTargetStreamer().emitGPRel32Value(Value);
8068 return parseEOL();
8069}
8070
8071/// parseDirectiveGpDWord
8072/// ::= .gpdword local_sym
8073bool MipsAsmParser::parseDirectiveGpDWord() {
8074 const MCExpr *Value;
8075 if (getParser().parseExpression(Value))
8076 return true;
8077 getTargetStreamer().emitGPRel64Value(Value);
8078 return parseEOL();
8079}
8080
8081/// parseDirectiveDtpRelWord
8082/// ::= .dtprelword tls_sym
8083bool MipsAsmParser::parseDirectiveDtpRelWord() {
8084 const MCExpr *Value;
8085 if (getParser().parseExpression(Value))
8086 return true;
8087 getTargetStreamer().emitDTPRel32Value(Value);
8088 return parseEOL();
8089}
8090
8091/// parseDirectiveDtpRelDWord
8092/// ::= .dtpreldword tls_sym
8093bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8094 const MCExpr *Value;
8095 if (getParser().parseExpression(Value))
8096 return true;
8097 getTargetStreamer().emitDTPRel64Value(Value);
8098 return parseEOL();
8099}
8100
8101/// parseDirectiveTpRelWord
8102/// ::= .tprelword tls_sym
8103bool MipsAsmParser::parseDirectiveTpRelWord() {
8104 const MCExpr *Value;
8105 if (getParser().parseExpression(Value))
8106 return true;
8107 getTargetStreamer().emitTPRel32Value(Value);
8108 return parseEOL();
8109}
8110
8111/// parseDirectiveTpRelDWord
8112/// ::= .tpreldword tls_sym
8113bool MipsAsmParser::parseDirectiveTpRelDWord() {
8114 const MCExpr *Value;
8115 if (getParser().parseExpression(Value))
8116 return true;
8117 getTargetStreamer().emitTPRel64Value(Value);
8118 return parseEOL();
8119}
8120
8121bool MipsAsmParser::parseDirectiveOption() {
8122 MCAsmParser &Parser = getParser();
8123 // Get the option token.
8124 AsmToken Tok = Parser.getTok();
8125 // At the moment only identifiers are supported.
8126 if (Tok.isNot(AsmToken::Identifier)) {
8127 return Error(Parser.getTok().getLoc(),
8128 "unexpected token, expected identifier");
8129 }
8130
8131 StringRef Option = Tok.getIdentifier();
8132
8133 if (Option == "pic0") {
8134 // MipsAsmParser needs to know if the current PIC mode changes.
8135 IsPicEnabled = false;
8136
8137 getTargetStreamer().emitDirectiveOptionPic0();
8138 Parser.Lex();
8139 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8140 return Error(Parser.getTok().getLoc(),
8141 "unexpected token, expected end of statement");
8142 }
8143 return false;
8144 }
8145
8146 if (Option == "pic2") {
8147 // MipsAsmParser needs to know if the current PIC mode changes.
8148 IsPicEnabled = true;
8149
8150 getTargetStreamer().emitDirectiveOptionPic2();
8151 Parser.Lex();
8152 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8153 return Error(Parser.getTok().getLoc(),
8154 "unexpected token, expected end of statement");
8155 }
8156 return false;
8157 }
8158
8159 // Unknown option.
8160 Warning(Parser.getTok().getLoc(),
8161 "unknown option, expected 'pic0' or 'pic2'");
8162 Parser.eatToEndOfStatement();
8163 return false;
8164}
8165
8166/// parseInsnDirective
8167/// ::= .insn
8168bool MipsAsmParser::parseInsnDirective() {
8169 // If this is not the end of the statement, report an error.
8170 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8171 reportParseError("unexpected token, expected end of statement");
8172 return false;
8173 }
8174
8175 // The actual label marking happens in
8176 // MipsELFStreamer::createPendingLabelRelocs().
8177 getTargetStreamer().emitDirectiveInsn();
8178
8179 getParser().Lex(); // Eat EndOfStatement token.
8180 return false;
8181}
8182
8183/// parseRSectionDirective
8184/// ::= .rdata
8185bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8186 // If this is not the end of the statement, report an error.
8187 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8188 reportParseError("unexpected token, expected end of statement");
8189 return false;
8190 }
8191
8192 MCSection *ELFSection = getContext().getELFSection(
8194 getParser().getStreamer().switchSection(ELFSection);
8195
8196 getParser().Lex(); // Eat EndOfStatement token.
8197 return false;
8198}
8199
8200/// parseSSectionDirective
8201/// ::= .sbss
8202/// ::= .sdata
8203bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8204 // If this is not the end of the statement, report an error.
8205 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8206 reportParseError("unexpected token, expected end of statement");
8207 return false;
8208 }
8209
8210 MCSection *ELFSection = getContext().getELFSection(
8212 getParser().getStreamer().switchSection(ELFSection);
8213
8214 getParser().Lex(); // Eat EndOfStatement token.
8215 return false;
8216}
8217
8218/// parseDirectiveModule
8219/// ::= .module oddspreg
8220/// ::= .module nooddspreg
8221/// ::= .module fp=value
8222/// ::= .module softfloat
8223/// ::= .module hardfloat
8224/// ::= .module mt
8225/// ::= .module crc
8226/// ::= .module nocrc
8227/// ::= .module virt
8228/// ::= .module novirt
8229/// ::= .module ginv
8230/// ::= .module noginv
8231bool MipsAsmParser::parseDirectiveModule() {
8232 MCAsmParser &Parser = getParser();
8233 AsmLexer &Lexer = getLexer();
8234 SMLoc L = Lexer.getLoc();
8235
8236 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8237 // TODO : get a better message.
8238 reportParseError(".module directive must appear before any code");
8239 return false;
8240 }
8241
8242 StringRef Option;
8243 if (Parser.parseIdentifier(Option)) {
8244 reportParseError("expected .module option identifier");
8245 return false;
8246 }
8247
8248 if (Option == "oddspreg") {
8249 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8250
8251 // Synchronize the abiflags information with the FeatureBits information we
8252 // changed above.
8253 getTargetStreamer().updateABIInfo(*this);
8254
8255 // If printing assembly, use the recently updated abiflags information.
8256 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8257 // emitted at the end).
8258 getTargetStreamer().emitDirectiveModuleOddSPReg();
8259
8260 // If this is not the end of the statement, report an error.
8261 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8262 reportParseError("unexpected token, expected end of statement");
8263 return false;
8264 }
8265
8266 return false; // parseDirectiveModule has finished successfully.
8267 } else if (Option == "nooddspreg") {
8268 if (!isABI_O32()) {
8269 return Error(L, "'.module nooddspreg' requires the O32 ABI");
8270 }
8271
8272 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8273
8274 // Synchronize the abiflags information with the FeatureBits information we
8275 // changed above.
8276 getTargetStreamer().updateABIInfo(*this);
8277
8278 // If printing assembly, use the recently updated abiflags information.
8279 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8280 // emitted at the end).
8281 getTargetStreamer().emitDirectiveModuleOddSPReg();
8282
8283 // If this is not the end of the statement, report an error.
8284 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8285 reportParseError("unexpected token, expected end of statement");
8286 return false;
8287 }
8288
8289 return false; // parseDirectiveModule has finished successfully.
8290 } else if (Option == "fp") {
8291 return parseDirectiveModuleFP();
8292 } else if (Option == "softfloat") {
8293 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8294
8295 // Synchronize the ABI Flags information with the FeatureBits information we
8296 // updated above.
8297 getTargetStreamer().updateABIInfo(*this);
8298
8299 // If printing assembly, use the recently updated ABI Flags information.
8300 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8301 // emitted later).
8302 getTargetStreamer().emitDirectiveModuleSoftFloat();
8303
8304 // If this is not the end of the statement, report an error.
8305 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8306 reportParseError("unexpected token, expected end of statement");
8307 return false;
8308 }
8309
8310 return false; // parseDirectiveModule has finished successfully.
8311 } else if (Option == "hardfloat") {
8312 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8313
8314 // Synchronize the ABI Flags information with the FeatureBits information we
8315 // updated above.
8316 getTargetStreamer().updateABIInfo(*this);
8317
8318 // If printing assembly, use the recently updated ABI Flags information.
8319 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8320 // emitted later).
8321 getTargetStreamer().emitDirectiveModuleHardFloat();
8322
8323 // If this is not the end of the statement, report an error.
8324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8325 reportParseError("unexpected token, expected end of statement");
8326 return false;
8327 }
8328
8329 return false; // parseDirectiveModule has finished successfully.
8330 } else if (Option == "mt") {
8331 setModuleFeatureBits(Mips::FeatureMT, "mt");
8332
8333 // Synchronize the ABI Flags information with the FeatureBits information we
8334 // updated above.
8335 getTargetStreamer().updateABIInfo(*this);
8336
8337 // If printing assembly, use the recently updated ABI Flags information.
8338 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8339 // emitted later).
8340 getTargetStreamer().emitDirectiveModuleMT();
8341
8342 // If this is not the end of the statement, report an error.
8343 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8344 reportParseError("unexpected token, expected end of statement");
8345 return false;
8346 }
8347
8348 return false; // parseDirectiveModule has finished successfully.
8349 } else if (Option == "crc") {
8350 setModuleFeatureBits(Mips::FeatureCRC, "crc");
8351
8352 // Synchronize the ABI Flags information with the FeatureBits information we
8353 // updated above.
8354 getTargetStreamer().updateABIInfo(*this);
8355
8356 // If printing assembly, use the recently updated ABI Flags information.
8357 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8358 // emitted later).
8359 getTargetStreamer().emitDirectiveModuleCRC();
8360
8361 // If this is not the end of the statement, report an error.
8362 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8363 reportParseError("unexpected token, expected end of statement");
8364 return false;
8365 }
8366
8367 return false; // parseDirectiveModule has finished successfully.
8368 } else if (Option == "nocrc") {
8369 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8370
8371 // Synchronize the ABI Flags information with the FeatureBits information we
8372 // updated above.
8373 getTargetStreamer().updateABIInfo(*this);
8374
8375 // If printing assembly, use the recently updated ABI Flags information.
8376 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8377 // emitted later).
8378 getTargetStreamer().emitDirectiveModuleNoCRC();
8379
8380 // If this is not the end of the statement, report an error.
8381 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8382 reportParseError("unexpected token, expected end of statement");
8383 return false;
8384 }
8385
8386 return false; // parseDirectiveModule has finished successfully.
8387 } else if (Option == "virt") {
8388 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8389
8390 // Synchronize the ABI Flags information with the FeatureBits information we
8391 // updated above.
8392 getTargetStreamer().updateABIInfo(*this);
8393
8394 // If printing assembly, use the recently updated ABI Flags information.
8395 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8396 // emitted later).
8397 getTargetStreamer().emitDirectiveModuleVirt();
8398
8399 // If this is not the end of the statement, report an error.
8400 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8401 reportParseError("unexpected token, expected end of statement");
8402 return false;
8403 }
8404
8405 return false; // parseDirectiveModule has finished successfully.
8406 } else if (Option == "novirt") {
8407 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8408
8409 // Synchronize the ABI Flags information with the FeatureBits information we
8410 // updated above.
8411 getTargetStreamer().updateABIInfo(*this);
8412
8413 // If printing assembly, use the recently updated ABI Flags information.
8414 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8415 // emitted later).
8416 getTargetStreamer().emitDirectiveModuleNoVirt();
8417
8418 // If this is not the end of the statement, report an error.
8419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8420 reportParseError("unexpected token, expected end of statement");
8421 return false;
8422 }
8423
8424 return false; // parseDirectiveModule has finished successfully.
8425 } else if (Option == "ginv") {
8426 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8427
8428 // Synchronize the ABI Flags information with the FeatureBits information we
8429 // updated above.
8430 getTargetStreamer().updateABIInfo(*this);
8431
8432 // If printing assembly, use the recently updated ABI Flags information.
8433 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8434 // emitted later).
8435 getTargetStreamer().emitDirectiveModuleGINV();
8436
8437 // If this is not the end of the statement, report an error.
8438 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8439 reportParseError("unexpected token, expected end of statement");
8440 return false;
8441 }
8442
8443 return false; // parseDirectiveModule has finished successfully.
8444 } else if (Option == "noginv") {
8445 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8446
8447 // Synchronize the ABI Flags information with the FeatureBits information we
8448 // updated above.
8449 getTargetStreamer().updateABIInfo(*this);
8450
8451 // If printing assembly, use the recently updated ABI Flags information.
8452 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8453 // emitted later).
8454 getTargetStreamer().emitDirectiveModuleNoGINV();
8455
8456 // If this is not the end of the statement, report an error.
8457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8458 reportParseError("unexpected token, expected end of statement");
8459 return false;
8460 }
8461
8462 return false; // parseDirectiveModule has finished successfully.
8463 } else {
8464 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8465 }
8466}
8467
8468/// parseDirectiveModuleFP
8469/// ::= =32
8470/// ::= =xx
8471/// ::= =64
8472bool MipsAsmParser::parseDirectiveModuleFP() {
8473 MCAsmParser &Parser = getParser();
8474 AsmLexer &Lexer = getLexer();
8475
8476 if (Lexer.isNot(AsmToken::Equal)) {
8477 reportParseError("unexpected token, expected equals sign '='");
8478 return false;
8479 }
8480 Parser.Lex(); // Eat '=' token.
8481
8483 if (!parseFpABIValue(FpABI, ".module"))
8484 return false;
8485
8486 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8487 reportParseError("unexpected token, expected end of statement");
8488 return false;
8489 }
8490
8491 // Synchronize the abiflags information with the FeatureBits information we
8492 // changed above.
8493 getTargetStreamer().updateABIInfo(*this);
8494
8495 // If printing assembly, use the recently updated abiflags information.
8496 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8497 // emitted at the end).
8498 getTargetStreamer().emitDirectiveModuleFP();
8499
8500 Parser.Lex(); // Consume the EndOfStatement.
8501 return false;
8502}
8503
8504bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8505 StringRef Directive) {
8506 MCAsmParser &Parser = getParser();
8507 AsmLexer &Lexer = getLexer();
8508 bool ModuleLevelOptions = Directive == ".module";
8509
8510 if (Lexer.is(AsmToken::Identifier)) {
8511 StringRef Value = Parser.getTok().getString();
8512 Parser.Lex();
8513
8514 if (Value != "xx") {
8515 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8516 return false;
8517 }
8518
8519 if (!isABI_O32()) {
8520 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8521 return false;
8522 }
8523
8524 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8525 if (ModuleLevelOptions) {
8526 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8527 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8528 } else {
8529 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8530 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8531 }
8532 return true;
8533 }
8534
8535 if (Lexer.is(AsmToken::Integer)) {
8536 unsigned Value = Parser.getTok().getIntVal();
8537 Parser.Lex();
8538
8539 if (Value != 32 && Value != 64) {
8540 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8541 return false;
8542 }
8543
8544 if (Value == 32) {
8545 if (!isABI_O32()) {
8546 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8547 return false;
8548 }
8549
8550 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8551 if (ModuleLevelOptions) {
8552 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8553 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8554 } else {
8555 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8556 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8557 }
8558 } else {
8559 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8560 if (ModuleLevelOptions) {
8561 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8562 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8563 } else {
8564 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8565 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8566 }
8567 }
8568
8569 return true;
8570 }
8571
8572 return false;
8573}
8574
8575bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8576 // This returns false if this function recognizes the directive
8577 // regardless of whether it is successfully handles or reports an
8578 // error. Otherwise it returns true to give the generic parser a
8579 // chance at recognizing it.
8580
8581 MCAsmParser &Parser = getParser();
8582 StringRef IDVal = DirectiveID.getString();
8583
8584 if (IDVal == ".cpadd") {
8585 parseDirectiveCpAdd(DirectiveID.getLoc());
8586 return false;
8587 }
8588 if (IDVal == ".cpload") {
8589 parseDirectiveCpLoad(DirectiveID.getLoc());
8590 return false;
8591 }
8592 if (IDVal == ".cprestore") {
8593 parseDirectiveCpRestore(DirectiveID.getLoc());
8594 return false;
8595 }
8596 if (IDVal == ".cplocal") {
8597 parseDirectiveCpLocal(DirectiveID.getLoc());
8598 return false;
8599 }
8600 if (IDVal == ".ent") {
8601 StringRef SymbolName;
8602
8603 if (Parser.parseIdentifier(SymbolName)) {
8604 reportParseError("expected identifier after .ent");
8605 return false;
8606 }
8607
8608 // There's an undocumented extension that allows an integer to
8609 // follow the name of the procedure which AFAICS is ignored by GAS.
8610 // Example: .ent foo,2
8611 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8612 if (getLexer().isNot(AsmToken::Comma)) {
8613 // Even though we accept this undocumented extension for compatibility
8614 // reasons, the additional integer argument does not actually change
8615 // the behaviour of the '.ent' directive, so we would like to discourage
8616 // its use. We do this by not referring to the extended version in
8617 // error messages which are not directly related to its use.
8618 reportParseError("unexpected token, expected end of statement");
8619 return false;
8620 }
8621 Parser.Lex(); // Eat the comma.
8622 const MCExpr *DummyNumber;
8623 int64_t DummyNumberVal;
8624 // If the user was explicitly trying to use the extended version,
8625 // we still give helpful extension-related error messages.
8626 if (Parser.parseExpression(DummyNumber)) {
8627 reportParseError("expected number after comma");
8628 return false;
8629 }
8630 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8631 reportParseError("expected an absolute expression after comma");
8632 return false;
8633 }
8634 }
8635
8636 // If this is not the end of the statement, report an error.
8637 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8638 reportParseError("unexpected token, expected end of statement");
8639 return false;
8640 }
8641
8642 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8643
8644 getTargetStreamer().emitDirectiveEnt(*Sym);
8645 CurrentFn = Sym;
8646 IsCpRestoreSet = false;
8647 return false;
8648 }
8649
8650 if (IDVal == ".end") {
8651 StringRef SymbolName;
8652
8653 if (Parser.parseIdentifier(SymbolName)) {
8654 reportParseError("expected identifier after .end");
8655 return false;
8656 }
8657
8658 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8659 reportParseError("unexpected token, expected end of statement");
8660 return false;
8661 }
8662
8663 if (CurrentFn == nullptr) {
8664 reportParseError(".end used without .ent");
8665 return false;
8666 }
8667
8668 if ((SymbolName != CurrentFn->getName())) {
8669 reportParseError(".end symbol does not match .ent symbol");
8670 return false;
8671 }
8672
8673 getTargetStreamer().emitDirectiveEnd(SymbolName);
8674 CurrentFn = nullptr;
8675 IsCpRestoreSet = false;
8676 return false;
8677 }
8678
8679 if (IDVal == ".frame") {
8680 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8682 ParseStatus Res = parseAnyRegister(TmpReg);
8683 if (Res.isNoMatch() || Res.isFailure()) {
8684 reportParseError("expected stack register");
8685 return false;
8686 }
8687
8688 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8689 if (!StackRegOpnd.isGPRAsmReg()) {
8690 reportParseError(StackRegOpnd.getStartLoc(),
8691 "expected general purpose register");
8692 return false;
8693 }
8694 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8695
8696 if (Parser.getTok().is(AsmToken::Comma))
8697 Parser.Lex();
8698 else {
8699 reportParseError("unexpected token, expected comma");
8700 return false;
8701 }
8702
8703 // Parse the frame size.
8704 const MCExpr *FrameSize;
8705 int64_t FrameSizeVal;
8706
8707 if (Parser.parseExpression(FrameSize)) {
8708 reportParseError("expected frame size value");
8709 return false;
8710 }
8711
8712 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8713 reportParseError("frame size not an absolute expression");
8714 return false;
8715 }
8716
8717 if (Parser.getTok().is(AsmToken::Comma))
8718 Parser.Lex();
8719 else {
8720 reportParseError("unexpected token, expected comma");
8721 return false;
8722 }
8723
8724 // Parse the return register.
8725 TmpReg.clear();
8726 Res = parseAnyRegister(TmpReg);
8727 if (Res.isNoMatch() || Res.isFailure()) {
8728 reportParseError("expected return register");
8729 return false;
8730 }
8731
8732 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8733 if (!ReturnRegOpnd.isGPRAsmReg()) {
8734 reportParseError(ReturnRegOpnd.getStartLoc(),
8735 "expected general purpose register");
8736 return false;
8737 }
8738
8739 // If this is not the end of the statement, report an error.
8740 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8741 reportParseError("unexpected token, expected end of statement");
8742 return false;
8743 }
8744
8745 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8746 ReturnRegOpnd.getGPR32Reg());
8747 IsCpRestoreSet = false;
8748 return false;
8749 }
8750
8751 if (IDVal == ".set") {
8752 parseDirectiveSet();
8753 return false;
8754 }
8755
8756 if (IDVal == ".mask" || IDVal == ".fmask") {
8757 // .mask bitmask, frame_offset
8758 // bitmask: One bit for each register used.
8759 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8760 // first register is expected to be saved.
8761 // Examples:
8762 // .mask 0x80000000, -4
8763 // .fmask 0x80000000, -4
8764 //
8765
8766 // Parse the bitmask
8767 const MCExpr *BitMask;
8768 int64_t BitMaskVal;
8769
8770 if (Parser.parseExpression(BitMask)) {
8771 reportParseError("expected bitmask value");
8772 return false;
8773 }
8774
8775 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8776 reportParseError("bitmask not an absolute expression");
8777 return false;
8778 }
8779
8780 if (Parser.getTok().is(AsmToken::Comma))
8781 Parser.Lex();
8782 else {
8783 reportParseError("unexpected token, expected comma");
8784 return false;
8785 }
8786
8787 // Parse the frame_offset
8788 const MCExpr *FrameOffset;
8789 int64_t FrameOffsetVal;
8790
8791 if (Parser.parseExpression(FrameOffset)) {
8792 reportParseError("expected frame offset value");
8793 return false;
8794 }
8795
8796 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8797 reportParseError("frame offset not an absolute expression");
8798 return false;
8799 }
8800
8801 // If this is not the end of the statement, report an error.
8802 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8803 reportParseError("unexpected token, expected end of statement");
8804 return false;
8805 }
8806
8807 if (IDVal == ".mask")
8808 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8809 else
8810 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8811 return false;
8812 }
8813
8814 if (IDVal == ".nan")
8815 return parseDirectiveNaN();
8816
8817 if (IDVal == ".gpword") {
8818 parseDirectiveGpWord();
8819 return false;
8820 }
8821
8822 if (IDVal == ".gpdword") {
8823 parseDirectiveGpDWord();
8824 return false;
8825 }
8826
8827 if (IDVal == ".dtprelword") {
8828 parseDirectiveDtpRelWord();
8829 return false;
8830 }
8831
8832 if (IDVal == ".dtpreldword") {
8833 parseDirectiveDtpRelDWord();
8834 return false;
8835 }
8836
8837 if (IDVal == ".tprelword") {
8838 parseDirectiveTpRelWord();
8839 return false;
8840 }
8841
8842 if (IDVal == ".tpreldword") {
8843 parseDirectiveTpRelDWord();
8844 return false;
8845 }
8846
8847 if (IDVal == ".option") {
8848 parseDirectiveOption();
8849 return false;
8850 }
8851
8852 if (IDVal == ".abicalls") {
8853 getTargetStreamer().emitDirectiveAbiCalls();
8854 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8855 Error(Parser.getTok().getLoc(),
8856 "unexpected token, expected end of statement");
8857 }
8858 return false;
8859 }
8860
8861 if (IDVal == ".cpsetup") {
8862 parseDirectiveCPSetup();
8863 return false;
8864 }
8865 if (IDVal == ".cpreturn") {
8866 parseDirectiveCPReturn();
8867 return false;
8868 }
8869 if (IDVal == ".module") {
8870 parseDirectiveModule();
8871 return false;
8872 }
8873 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8874 parseInternalDirectiveReallowModule();
8875 return false;
8876 }
8877 if (IDVal == ".insn") {
8878 parseInsnDirective();
8879 return false;
8880 }
8881 if (IDVal == ".rdata") {
8882 parseRSectionDirective(".rodata");
8883 return false;
8884 }
8885 if (IDVal == ".sbss") {
8886 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8887 return false;
8888 }
8889 if (IDVal == ".sdata") {
8890 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8891 return false;
8892 }
8893
8894 return true;
8895}
8896
8897bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8898 // If this is not the end of the statement, report an error.
8899 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8900 reportParseError("unexpected token, expected end of statement");
8901 return false;
8902 }
8903
8904 getTargetStreamer().reallowModuleDirective();
8905
8906 getParser().Lex(); // Eat EndOfStatement token.
8907 return false;
8908}
8909
8910extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
8917
8918#define GET_REGISTER_MATCHER
8919#define GET_MATCHER_IMPLEMENTATION
8920#define GET_MNEMONIC_SPELL_CHECKER
8921#include "MipsGenAsmMatcher.inc"
8922
8923bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8924 // Find the appropriate table for this asm variant.
8925 const MatchEntry *Start, *End;
8926 switch (VariantID) {
8927 default: llvm_unreachable("invalid variant!");
8928 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8929 }
8930 // Search the table.
8931 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8932 return MnemonicRange.first != MnemonicRange.second;
8933}
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
Definition CSEInfo.cpp:27
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
static Value * expandAbs(CallInst *Orig)
#define op(i)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static LVOptions Options
Definition LVOptions.cpp:25
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< StringRef > ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
mir Rename Register Operands
Register Reg
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition VPlanSLP.cpp:247
APInt bitcastToAPInt() const
Definition APFloat.h:1353
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1540
SMLoc getLoc() const
Get the current source location.
Definition AsmLexer.h:115
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Definition AsmLexer.h:121
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition AsmLexer.h:147
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition AsmLexer.h:150
Target independent representation for an assembler token.
Definition MCAsmMacro.h:22
LLVM_ABI SMLoc getLoc() const
Definition AsmLexer.cpp:32
int64_t getIntVal() const
Definition MCAsmMacro.h:108
bool isNot(TokenKind K) const
Definition MCAsmMacro.h:76
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition MCAsmMacro.h:103
bool is(TokenKind K) const
Definition MCAsmMacro.h:75
TokenKind getKind() const
Definition MCAsmMacro.h:74
LLVM_ABI SMRange getLocRange() const
Definition AsmLexer.cpp:38
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Definition MCAsmMacro.h:92
Base class for user error types.
Definition Error.h:354
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
AsmLexer & getLexer()
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
Definition MCExpr.h:299
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition MCExpr.h:446
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition MCExpr.h:449
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:201
@ Div
Signed division.
Definition MCExpr.h:304
@ Shl
Shift left.
Definition MCExpr.h:321
@ LShr
Logical shift right.
Definition MCExpr.h:323
@ Sub
Subtraction.
Definition MCExpr.h:324
@ Mul
Multiplication.
Definition MCExpr.h:317
@ Mod
Signed remainder.
Definition MCExpr.h:316
@ And
Bitwise and.
Definition MCExpr.h:303
@ Or
Bitwise or.
Definition MCExpr.h:319
@ Xor
Bitwise exclusive or.
Definition MCExpr.h:325
@ Add
Addition.
Definition MCExpr.h:302
int64_t getValue() const
Definition MCExpr.h:171
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
Definition MCExpr.cpp:450
@ Unary
Unary expressions.
Definition MCExpr.h:44
@ Constant
Constant expressions.
Definition MCExpr.h:42
@ SymbolRef
References to labels and assigned expressions.
Definition MCExpr.h:43
@ Target
Target specific expression.
Definition MCExpr.h:46
@ Specifier
Expression with a relocation specifier.
Definition MCExpr.h:45
@ Binary
Binary expressions.
Definition MCExpr.h:41
ExprKind getKind() const
Definition MCExpr.h:85
SMLoc getLoc() const
Definition MCExpr.h:86
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getNumOperands() const
Definition MCInst.h:212
SMLoc getLoc() const
Definition MCInst.h:208
void setLoc(SMLoc loc)
Definition MCInst.h:207
unsigned getOpcode() const
Definition MCInst.h:202
void addOperand(const MCOperand Op)
Definition MCInst.h:215
void setOpcode(unsigned Op)
Definition MCInst.h:201
void clear()
Definition MCInst.h:223
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition MCInstrDesc.h:86
uint8_t OperandType
Information about the type of the operand.
Definition MCInstrDesc.h:98
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
void setImm(int64_t Val)
Definition MCInst.h:89
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
constexpr bool isValid() const
Definition MCRegister.h:76
constexpr unsigned id() const
Definition MCRegister.h:74
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:220
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
uint16_t getSpecifier() const
Definition MCExpr.h:233
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition MCSymbol.h:237
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition MCSymbol.h:243
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition MCSymbol.h:267
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
Definition MCSymbol.h:270
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition MCSymbol.h:205
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Definition MCStreamer.h:101
MCContext & getContext()
Unary assembler expressions.
Definition MCExpr.h:243
const MCSymbol * getAddSym() const
Definition MCValue.h:49
int64_t getConstant() const
Definition MCValue.h:44
const MCSymbol * getSubSym() const
Definition MCValue.h:51
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
Represents a location in source code.
Definition SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:36
constexpr const char * getPointer() const
Definition SMLoc.h:34
void push_back(const T &Elt)
iterator end()
Definition StringMap.h:224
iterator find(StringRef Key)
Definition StringMap.h:235
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:480
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:581
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:269
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:151
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
Definition Triple.cpp:2075
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
@ Entry
Definition COFF.h:862
@ SHT_PROGBITS
Definition ELF.h:1140
@ SHT_NOBITS
Definition ELF.h:1147
@ SHF_ALLOC
Definition ELF.h:1240
@ SHF_MIPS_GPREL
Definition ELF.h:1323
@ SHF_WRITE
Definition ELF.h:1237
@ STB_LOCAL
Definition ELF.h:1396
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
Context & getContext() const
Definition BasicBlock.h:99
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:270
Op::Description Desc
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:157
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:159
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:198
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:164
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition Alignment.h:197
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
@ Other
Any other memory.
Definition ModRef.h:68
To bit_cast(const From &from) noexcept
Definition bit.h:90
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition MathExtras.h:191
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:257
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:577
Target & getTheMipsTarget()
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:207
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:853
#define N
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
Definition APFloat.cpp:267
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...