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