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