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