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
17#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/StringRef.h"
21#include "llvm/ADT/Twine.h"
23#include "llvm/MC/MCContext.h"
24#include "llvm/MC/MCExpr.h"
25#include "llvm/MC/MCInst.h"
26#include "llvm/MC/MCInstrDesc.h"
27#include "llvm/MC/MCInstrInfo.h"
37#include "llvm/MC/MCStreamer.h"
39#include "llvm/MC/MCSymbol.h"
40#include "llvm/MC/MCSymbolELF.h"
41#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
74
75namespace {
76
77class MipsAssemblerOptions {
78public:
79 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
80
81 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
82 ATReg = Opts->getATRegIndex();
83 Reorder = Opts->isReorder();
84 Macro = Opts->isMacro();
85 Features = Opts->getFeatures();
86 }
87
88 unsigned getATRegIndex() const { return ATReg; }
89 bool setATRegIndex(unsigned Reg) {
90 if (Reg > 31)
91 return false;
92
93 ATReg = Reg;
94 return true;
95 }
96
97 bool isReorder() const { return Reorder; }
98 void setReorder() { Reorder = true; }
99 void setNoReorder() { Reorder = false; }
100
101 bool isMacro() const { return Macro; }
102 void setMacro() { Macro = true; }
103 void setNoMacro() { Macro = false; }
104
105 const FeatureBitset &getFeatures() const { return Features; }
106 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
107
108 // Set of features that are either architecture features or referenced
109 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
110 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
111 // The reason we need this mask is explained in the selectArch function.
112 // FIXME: Ideally we would like TableGen to generate this information.
113 static const FeatureBitset AllArchRelatedMask;
114
115private:
116 unsigned ATReg = 1;
117 bool Reorder = true;
118 bool Macro = true;
119 FeatureBitset Features;
120};
121
122} // end anonymous namespace
123
124const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
125 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
126 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
127 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
128 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
129 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
130 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
131 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
132 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
133 Mips::FeatureNaN2008
134};
135
136namespace {
137
138class MipsAsmParser : public MCTargetAsmParser {
139 MipsTargetStreamer &getTargetStreamer() {
140 assert(getParser().getStreamer().getTargetStreamer() &&
141 "do not have a target streamer");
142 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
143 return static_cast<MipsTargetStreamer &>(TS);
144 }
145
146 MipsABIInfo ABI;
148 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
149 // nullptr, which indicates that no function is currently
150 // selected. This usually happens after an '.end func'
151 // directive.
152 bool IsLittleEndian;
153 bool IsPicEnabled;
154 bool IsCpRestoreSet;
155 bool CurForbiddenSlotAttr;
156 int CpRestoreOffset;
157 MCRegister GPReg;
158 unsigned CpSaveLocation;
159 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
160 bool CpSaveLocationIsRegister;
161
162 // Map of register aliases created via the .set directive.
163 StringMap<AsmToken> RegisterSets;
164
165 // Print a warning along with its fix-it message at the given range.
166 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
167 SMRange Range, bool ShowColors = true);
168
169 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
170
171#define GET_ASSEMBLER_HEADER
172#include "MipsGenAsmMatcher.inc"
173
174 unsigned
175 checkEarlyTargetMatchPredicate(MCInst &Inst,
176 const OperandVector &Operands) override;
177 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
178
179 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
182 bool MatchingInlineAsm) override;
183
184 /// Parse a register as used in CFI directives
185 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
186 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
187 SMLoc &EndLoc) override;
188
189 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
190
191 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
192
193 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
194
195 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
196 SMLoc NameLoc, OperandVector &Operands) override;
197
198 bool ParseDirective(AsmToken DirectiveID) override;
199
200 ParseStatus parseMemOperand(OperandVector &Operands);
201 ParseStatus matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
202 StringRef Identifier, SMLoc S);
203 ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands,
204 const AsmToken &Token, SMLoc S);
205 ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
206 ParseStatus parseAnyRegister(OperandVector &Operands);
207 ParseStatus parseJumpTarget(OperandVector &Operands);
208 ParseStatus parseInvNum(OperandVector &Operands);
209 ParseStatus parseRegisterList(OperandVector &Operands);
210 const MCExpr *parseRelocExpr();
211
212 bool searchSymbolAlias(OperandVector &Operands);
213
214 bool parseOperand(OperandVector &, StringRef Mnemonic);
215
216 enum MacroExpanderResultTy {
217 MER_NotAMacro,
218 MER_Success,
219 MER_Fail,
220 };
221
222 // Expands assembly pseudo instructions.
223 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
224 MCStreamer &Out,
225 const MCSubtargetInfo *STI);
226
227 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
228 const MCSubtargetInfo *STI);
229
230 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
231 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
232 MCStreamer &Out, const MCSubtargetInfo *STI);
233
234 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, MCRegister DstReg,
235 MCRegister SrcReg, bool Is32BitSym, SMLoc IDLoc,
236 MCStreamer &Out, const MCSubtargetInfo *STI);
237
238 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
239
240 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
241 MCStreamer &Out, const MCSubtargetInfo *STI);
242
243 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
247 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
248 const MCSubtargetInfo *STI);
249 bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
250 MCStreamer &Out, const MCSubtargetInfo *STI);
251
252 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
253 const MCOperand &Offset, bool Is32BitAddress,
254 SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI);
256
257 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI);
259
260 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI, bool IsLoad);
262 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
263 const MCSubtargetInfo *STI, bool IsLoad);
264
265 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
267
268 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
270
271 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
273
274 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI);
276
277 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
278 const MCSubtargetInfo *STI, const bool IsMips64,
279 const bool Signed);
280
281 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
282 MCStreamer &Out, const MCSubtargetInfo *STI);
283
284 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
285 const MCSubtargetInfo *STI);
286
287 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
288 const MCSubtargetInfo *STI);
289
290 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291 const MCSubtargetInfo *STI);
292
293 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
294 const MCSubtargetInfo *STI);
295
296 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
298
299 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
300 const MCSubtargetInfo *STI);
301
302 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
303 const MCSubtargetInfo *STI);
304
305 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
306 const MCSubtargetInfo *STI);
307
308 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
309 MCStreamer &Out, const MCSubtargetInfo *STI);
310 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
312 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI);
314 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
315 const MCSubtargetInfo *STI);
316
317 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
318 const MCSubtargetInfo *STI);
319
320 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
321 const MCSubtargetInfo *STI);
322
323 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
324 const MCSubtargetInfo *STI);
325
326 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
327 const MCSubtargetInfo *STI);
328
329 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
330 const MCSubtargetInfo *STI);
331
332 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
333 const MCSubtargetInfo *STI, bool IsLoad);
334
335 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
336 const MCSubtargetInfo *STI);
337
338 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
339 const MCSubtargetInfo *STI);
340
341 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
342 const MCSubtargetInfo *STI);
343
344 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
345 const MCSubtargetInfo *STI);
346
347 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
348 const MCSubtargetInfo *STI);
349
350 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
351 const MCSubtargetInfo *STI);
352
353 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
354 const MCSubtargetInfo *STI);
355
356 bool reportParseError(const Twine &ErrorMsg);
357 bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
358
359 bool parseSetMips0Directive();
360 bool parseSetArchDirective();
361 bool parseSetFeature(uint64_t Feature);
362 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
363 bool parseDirectiveCpAdd(SMLoc Loc);
364 bool parseDirectiveCpLoad(SMLoc Loc);
365 bool parseDirectiveCpLocal(SMLoc Loc);
366 bool parseDirectiveCpRestore(SMLoc Loc);
367 bool parseDirectiveCPSetup();
368 bool parseDirectiveCPReturn();
369 bool parseDirectiveNaN();
370 bool parseDirectiveSet();
371 bool parseDirectiveOption();
372 bool parseInsnDirective();
373 bool parseRSectionDirective(StringRef Section);
374 bool parseSSectionDirective(StringRef Section, unsigned Type);
375
376 bool parseSetAtDirective();
377 bool parseSetNoAtDirective();
378 bool parseSetMacroDirective();
379 bool parseSetNoMacroDirective();
380 bool parseSetMsaDirective();
381 bool parseSetNoMsaDirective();
382 bool parseSetNoDspDirective();
383 bool parseSetNoMips3DDirective();
384 bool parseSetReorderDirective();
385 bool parseSetNoReorderDirective();
386 bool parseSetMips16Directive();
387 bool parseSetNoMips16Directive();
388 bool parseSetFpDirective();
389 bool parseSetOddSPRegDirective();
390 bool parseSetNoOddSPRegDirective();
391 bool parseSetPopDirective();
392 bool parseSetPushDirective();
393 bool parseSetSoftFloatDirective();
394 bool parseSetHardFloatDirective();
395 bool parseSetMtDirective();
396 bool parseSetNoMtDirective();
397 bool parseSetNoCRCDirective();
398 bool parseSetNoVirtDirective();
399 bool parseSetNoGINVDirective();
400
401 bool parseSetAssignment();
402
403 bool parseDirectiveGpWord();
404 bool parseDirectiveGpDWord();
405 bool parseDirectiveDtpRelWord();
406 bool parseDirectiveDtpRelDWord();
407 bool parseDirectiveTpRelWord();
408 bool parseDirectiveTpRelDWord();
409 bool parseDirectiveModule();
410 bool parseDirectiveModuleFP();
411 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
412 StringRef Directive);
413
414 bool parseInternalDirectiveReallowModule();
415
416 bool eatComma(StringRef ErrorStr);
417
418 int matchCPURegisterName(StringRef Symbol);
419
420 int matchHWRegsRegisterName(StringRef Symbol);
421
422 int matchFPURegisterName(StringRef Name);
423
424 int matchFCCRegisterName(StringRef Name);
425
426 int matchACRegisterName(StringRef Name);
427
428 int matchMSA128RegisterName(StringRef Name);
429
430 int matchMSA128CtrlRegisterName(StringRef Name);
431
432 MCRegister getReg(int RC, int RegNo);
433
434 /// Returns the internal register number for the current AT. Also checks if
435 /// the current AT is unavailable (set to $0) and gives an error if it is.
436 /// This should be used in pseudo-instruction expansions which need AT.
437 MCRegister getATReg(SMLoc Loc);
438
439 bool canUseATReg();
440
441 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
442 const MCSubtargetInfo *STI);
443
444 // Selects a new architecture by updating the FeatureBits with the necessary
445 // info including implied dependencies.
446 // Internally, it clears all the feature bits related to *any* architecture
447 // and selects the new one using the ToggleFeature functionality of the
448 // MCSubtargetInfo object that handles implied dependencies. The reason we
449 // clear all the arch related bits manually is because ToggleFeature only
450 // clears the features that imply the feature being cleared and not the
451 // features implied by the feature being cleared. This is easier to see
452 // with an example:
453 // --------------------------------------------------
454 // | Feature | Implies |
455 // | -------------------------------------------------|
456 // | FeatureMips1 | None |
457 // | FeatureMips2 | FeatureMips1 |
458 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
459 // | FeatureMips4 | FeatureMips3 |
460 // | ... | |
461 // --------------------------------------------------
462 //
463 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
464 // FeatureMipsGP64 | FeatureMips1)
465 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
466 void selectArch(StringRef ArchFeature) {
467 MCSubtargetInfo &STI = copySTI();
468 FeatureBitset FeatureBits = STI.getFeatureBits();
469 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
470 STI.setFeatureBits(FeatureBits);
471 setAvailableFeatures(
472 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
473 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
474 }
475
476 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
477 if (!(getSTI().hasFeature(Feature))) {
478 MCSubtargetInfo &STI = copySTI();
479 setAvailableFeatures(
480 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
481 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
482 }
483 }
484
485 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
486 if (getSTI().hasFeature(Feature)) {
487 MCSubtargetInfo &STI = copySTI();
488 setAvailableFeatures(
489 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
490 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
491 }
492 }
493
494 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
495 setFeatureBits(Feature, FeatureString);
496 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
497 }
498
499 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
500 clearFeatureBits(Feature, FeatureString);
501 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
502 }
503
504public:
505 enum MipsMatchResultTy {
506 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
507 Match_RequiresDifferentOperands,
508 Match_RequiresNoZeroRegister,
509 Match_RequiresSameSrcAndDst,
510 Match_NoFCCRegisterForCurrentISA,
511 Match_NonZeroOperandForSync,
512 Match_NonZeroOperandForMTCX,
513 Match_RequiresPosSizeRange0_32,
514 Match_RequiresPosSizeRange33_64,
515 Match_RequiresPosSizeUImm6,
516#define GET_OPERAND_DIAGNOSTIC_TYPES
517#include "MipsGenAsmMatcher.inc"
518#undef GET_OPERAND_DIAGNOSTIC_TYPES
519 };
520
521 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
522 const MCInstrInfo &MII)
523 : MCTargetAsmParser(sti, MII),
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 (!EmitJalrReloc)
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::S0 && R1 == Mips::RA) ||
1388 (R0 == Mips::S0_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::ZERO ||
2023 Inst.getOperand(1).getReg() == Mips::ZERO_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::ZERO ||
2049 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2050 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2051 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_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::ZERO));
2064 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
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(Mips::T9, MCRegister(), Inst.getOperand(0),
2090 !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);
2098 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2099 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
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 (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
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::A1 && R1 == Mips::A2) ||
2271 (R0 == Mips::A1 && R1 == Mips::A3) ||
2272 (R0 == Mips::A2 && R1 == Mips::A3) ||
2273 (R0 == Mips::A0 && R1 == Mips::S5) ||
2274 (R0 == Mips::A0 && R1 == Mips::S6) ||
2275 (R0 == Mips::A0 && R1 == Mips::A1) ||
2276 (R0 == Mips::A0 && R1 == Mips::A2) ||
2277 (R0 == Mips::A0 && R1 == Mips::A3));
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);
2683 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
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::ZERO && SrcReg != Mips::ZERO_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 == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2974 Res.getConstant() == 0 && !IsLocalSym) {
2975 if (UseXGOT) {
2976 const MCExpr *CallHiExpr =
2978 const MCExpr *CallLoExpr =
2980 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2981 STI);
2982 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2983 IDLoc, STI);
2984 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2985 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2986 } else {
2987 const MCExpr *CallExpr =
2989 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2990 MCOperand::createExpr(CallExpr), IDLoc, STI);
2991 }
2992 return false;
2993 }
2994
2995 MCRegister TmpReg = DstReg;
2996 if (UseSrcReg &&
2997 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2998 SrcReg)) {
2999 // If $rs is the same as $rd, we need to use AT.
3000 // If it is not available we exit.
3001 MCRegister ATReg = getATReg(IDLoc);
3002 if (!ATReg)
3003 return true;
3004 TmpReg = ATReg;
3005 }
3006
3007 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
3008 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
3009 // FIXME: Implement XGOT for microMIPS.
3010 if (UseXGOT) {
3011 // Loading address from XGOT
3012 // External GOT: lui $tmp, %got_hi(symbol)($gp)
3013 // addu $tmp, $tmp, $gp
3014 // lw $tmp, %got_lo(symbol)($tmp)
3015 // >addiu $tmp, $tmp, offset
3016 // >addiu $rd, $tmp, $rs
3017 // The addiu's marked with a '>' may be omitted if they are redundant. If
3018 // this happens then the last instruction must use $rd as the result
3019 // register.
3020 const MCExpr *CallHiExpr =
3022 const MCExpr *CallLoExpr = MCSpecifierExpr::create(
3024
3025 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3026 STI);
3027 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3028 IDLoc, STI);
3029 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3030 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3031
3032 if (Res.getConstant() != 0)
3033 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3035 Res.getConstant(), getContext())),
3036 IDLoc, STI);
3037
3038 if (UseSrcReg)
3039 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3040 IDLoc, STI);
3041 return false;
3042 }
3043
3044 const MCSpecifierExpr *GotExpr = nullptr;
3045 const MCExpr *LoExpr = nullptr;
3046 if (ABI.IsN32() || ABI.IsN64()) {
3047 // The remaining cases are:
3048 // Small offset: ld $tmp, %got_disp(symbol)($gp)
3049 // >daddiu $tmp, $tmp, offset
3050 // >daddu $rd, $tmp, $rs
3051 // The daddiu's marked with a '>' may be omitted if they are redundant. If
3052 // this happens then the last instruction must use $rd as the result
3053 // register.
3055 getContext());
3056 if (Res.getConstant() != 0) {
3057 // Symbols fully resolve with just the %got_disp(symbol) but we
3058 // must still account for any offset to the symbol for
3059 // expressions like symbol+8.
3061
3062 // FIXME: Offsets greater than 16 bits are not yet implemented.
3063 // FIXME: The correct range is a 32-bit sign-extended number.
3064 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3065 Error(IDLoc, "macro instruction uses large offset, which is not "
3066 "currently supported");
3067 return true;
3068 }
3069 }
3070 } else {
3071 // The remaining cases are:
3072 // External GOT: lw $tmp, %got(symbol)($gp)
3073 // >addiu $tmp, $tmp, offset
3074 // >addiu $rd, $tmp, $rs
3075 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3076 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3077 // >addiu $rd, $tmp, $rs
3078 // The addiu's marked with a '>' may be omitted if they are redundant. If
3079 // this happens then the last instruction must use $rd as the result
3080 // register.
3081 if (IsLocalSym) {
3082 GotExpr = MCSpecifierExpr::create(SymExpr, Mips::S_GOT, getContext());
3083 LoExpr = MCSpecifierExpr::create(SymExpr, Mips::S_LO, getContext());
3084 } else {
3085 // External symbols fully resolve the symbol with just the %got(symbol)
3086 // but we must still account for any offset to the symbol for
3087 // expressions like symbol+8.
3088 GotExpr =
3090 if (Res.getConstant() != 0)
3092 }
3093 }
3094
3095 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3096 MCOperand::createExpr(GotExpr), IDLoc, STI);
3097
3098 if (LoExpr)
3099 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3100 MCOperand::createExpr(LoExpr), IDLoc, STI);
3101
3102 if (UseSrcReg)
3103 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3104 IDLoc, STI);
3105
3106 return false;
3107 }
3108
3109 const auto *HiExpr =
3111 const auto *LoExpr =
3113
3114 // This is the 64-bit symbol address expansion.
3115 if (ABI.ArePtrs64bit() && isGP64bit()) {
3116 // We need AT for the 64-bit expansion in the cases where the optional
3117 // source register is the destination register and for the superscalar
3118 // scheduled form.
3119 //
3120 // If it is not available we exit if the destination is the same as the
3121 // source register.
3122
3123 const auto *HighestExpr =
3125 const auto *HigherExpr =
3127
3128 bool RdRegIsRsReg =
3129 UseSrcReg &&
3130 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3131
3132 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3133 MCRegister ATReg = getATReg(IDLoc);
3134
3135 // If $rs is the same as $rd:
3136 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3137 // daddiu $at, $at, %higher(sym)
3138 // dsll $at, $at, 16
3139 // daddiu $at, $at, %hi(sym)
3140 // dsll $at, $at, 16
3141 // daddiu $at, $at, %lo(sym)
3142 // daddu $rd, $at, $rd
3143 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3144 STI);
3145 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3146 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3147 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3148 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3149 IDLoc, STI);
3150 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3151 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3152 IDLoc, STI);
3153 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3154
3155 return false;
3156 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3157 MCRegister ATReg = getATReg(IDLoc);
3158
3159 // If the $rs is different from $rd or if $rs isn't specified and we
3160 // have $at available:
3161 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3162 // lui $at, %hi(sym)
3163 // daddiu $rd, $rd, %higher(sym)
3164 // daddiu $at, $at, %lo(sym)
3165 // dsll32 $rd, $rd, 0
3166 // daddu $rd, $rd, $at
3167 // (daddu $rd, $rd, $rs)
3168 //
3169 // Which is preferred for superscalar issue.
3170 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3171 STI);
3172 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3173 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3174 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3175 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3176 IDLoc, STI);
3177 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3178 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3179 if (UseSrcReg)
3180 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3181
3182 return false;
3183 } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3184 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3185 // Otherwise, synthesize the address in the destination register
3186 // serially:
3187 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3188 // daddiu $rd, $rd, %higher(sym)
3189 // dsll $rd, $rd, 16
3190 // daddiu $rd, $rd, %hi(sym)
3191 // dsll $rd, $rd, 16
3192 // daddiu $rd, $rd, %lo(sym)
3193 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3194 STI);
3195 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3196 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3197 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3198 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3199 MCOperand::createExpr(HiExpr), IDLoc, STI);
3200 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3201 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3202 MCOperand::createExpr(LoExpr), IDLoc, STI);
3203 if (UseSrcReg)
3204 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3205
3206 return false;
3207 } else {
3208 // We have a case where SrcReg == DstReg and we don't have $at
3209 // available. We can't expand this case, so error out appropriately.
3210 assert(SrcReg == DstReg && !canUseATReg() &&
3211 "Could have expanded dla but didn't?");
3212 reportParseError(IDLoc,
3213 "pseudo-instruction requires $at, which is not available");
3214 return true;
3215 }
3216 }
3217
3218 // And now, the 32-bit symbol address expansion:
3219 // If $rs is the same as $rd:
3220 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3221 // ori $at, $at, %lo(sym)
3222 // addu $rd, $at, $rd
3223 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3224 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3225 // ori $rd, $rd, %lo(sym)
3226 // (addu $rd, $rd, $rs)
3227 MCRegister TmpReg = DstReg;
3228 if (UseSrcReg &&
3229 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3230 // If $rs is the same as $rd, we need to use AT.
3231 // If it is not available we exit.
3232 MCRegister ATReg = getATReg(IDLoc);
3233 if (!ATReg)
3234 return true;
3235 TmpReg = ATReg;
3236 }
3237
3238 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3239 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3240 IDLoc, STI);
3241
3242 if (UseSrcReg)
3243 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3244 else
3245 assert(
3246 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3247
3248 return false;
3249}
3250
3251// Each double-precision register DO-D15 overlaps with two of the single
3252// precision registers F0-F31. As an example, all of the following hold true:
3253// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3255 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).contains(Reg))
3256 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3257 switch (Reg.id()) {
3258 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3259 case Mips::ZERO: return Mips::AT;
3260 case Mips::AT: return Mips::V0;
3261 case Mips::V0: return Mips::V1;
3262 case Mips::V1: return Mips::A0;
3263 case Mips::A0: return Mips::A1;
3264 case Mips::A1: return Mips::A2;
3265 case Mips::A2: return Mips::A3;
3266 case Mips::A3: return Mips::T0;
3267 case Mips::T0: return Mips::T1;
3268 case Mips::T1: return Mips::T2;
3269 case Mips::T2: return Mips::T3;
3270 case Mips::T3: return Mips::T4;
3271 case Mips::T4: return Mips::T5;
3272 case Mips::T5: return Mips::T6;
3273 case Mips::T6: return Mips::T7;
3274 case Mips::T7: return Mips::S0;
3275 case Mips::S0: return Mips::S1;
3276 case Mips::S1: return Mips::S2;
3277 case Mips::S2: return Mips::S3;
3278 case Mips::S3: return Mips::S4;
3279 case Mips::S4: return Mips::S5;
3280 case Mips::S5: return Mips::S6;
3281 case Mips::S6: return Mips::S7;
3282 case Mips::S7: return Mips::T8;
3283 case Mips::T8: return Mips::T9;
3284 case Mips::T9: return Mips::K0;
3285 case Mips::K0: return Mips::K1;
3286 case Mips::K1: return Mips::GP;
3287 case Mips::GP: return Mips::SP;
3288 case Mips::SP: return Mips::FP;
3289 case Mips::FP: return Mips::RA;
3290 case Mips::RA: return Mips::ZERO;
3291 case Mips::D0: return Mips::F1;
3292 case Mips::D1: return Mips::F3;
3293 case Mips::D2: return Mips::F5;
3294 case Mips::D3: return Mips::F7;
3295 case Mips::D4: return Mips::F9;
3296 case Mips::D5: return Mips::F11;
3297 case Mips::D6: return Mips::F13;
3298 case Mips::D7: return Mips::F15;
3299 case Mips::D8: return Mips::F17;
3300 case Mips::D9: return Mips::F19;
3301 case Mips::D10: return Mips::F21;
3302 case Mips::D11: return Mips::F23;
3303 case Mips::D12: return Mips::F25;
3304 case Mips::D13: return Mips::F27;
3305 case Mips::D14: return Mips::F29;
3306 case Mips::D15: return Mips::F31;
3307 }
3308}
3309
3310// FIXME: This method is too general. In principle we should compute the number
3311// of instructions required to synthesize the immediate inline compared to
3312// synthesizing the address inline and relying on non .text sections.
3313// For static O32 and N32 this may yield a small benefit, for static N64 this is
3314// likely to yield a much larger benefit as we have to synthesize a 64bit
3315// address to load a 64 bit value.
3316bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3317 MCSymbol *Sym) {
3318 MCRegister ATReg = getATReg(IDLoc);
3319 if (!ATReg)
3320 return true;
3321
3322 if(IsPicEnabled) {
3323 const MCExpr *GotSym = MCSymbolRefExpr::create(Sym, getContext());
3324 const auto *GotExpr =
3326
3327 if(isABI_O32() || isABI_N32()) {
3328 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3329 IDLoc, STI);
3330 } else { //isABI_N64()
3331 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3332 IDLoc, STI);
3333 }
3334 } else { //!IsPicEnabled
3335 const MCExpr *HiSym = MCSymbolRefExpr::create(Sym, getContext());
3336 const auto *HiExpr =
3338
3339 // FIXME: This is technically correct but gives a different result to gas,
3340 // but gas is incomplete there (it has a fixme noting it doesn't work with
3341 // 64-bit addresses).
3342 // FIXME: With -msym32 option, the address expansion for N64 should probably
3343 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3344 // symbol's value is considered sign extended.
3345 if(isABI_O32() || isABI_N32()) {
3346 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3347 } else { //isABI_N64()
3348 const MCExpr *HighestSym = MCSymbolRefExpr::create(Sym, getContext());
3349 const auto *HighestExpr =
3351 const MCExpr *HigherSym = MCSymbolRefExpr::create(Sym, getContext());
3352 const auto *HigherExpr =
3354
3355 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3356 STI);
3357 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3358 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3359 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3360 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3361 IDLoc, STI);
3362 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3363 }
3364 }
3365 return false;
3366}
3367
3369 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3370 // exponent field), convert it to double (e.g. 1 to 1.0)
3371 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3372 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3373 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3374 }
3375 return ImmOp64;
3376}
3377
3379 // Conversion of a double in an uint64_t to a float in a uint32_t,
3380 // retaining the bit pattern of a float.
3381 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3382 float TmpFloat = static_cast<float>(DoubleImm);
3383 return llvm::bit_cast<uint32_t>(TmpFloat);
3384}
3385
3386bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3387 MCStreamer &Out,
3388 const MCSubtargetInfo *STI) {
3389 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3390 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3391 "Invalid instruction operand.");
3392
3393 MCRegister FirstReg = Inst.getOperand(0).getReg();
3394 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3395
3396 uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3397
3398 return loadImmediate(ImmOp32, FirstReg, MCRegister(), true, false, IDLoc, Out,
3399 STI);
3400}
3401
3402bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3403 MCStreamer &Out,
3404 const MCSubtargetInfo *STI) {
3405 MipsTargetStreamer &TOut = getTargetStreamer();
3406 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3407 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3408 "Invalid instruction operand.");
3409
3410 MCRegister FirstReg = Inst.getOperand(0).getReg();
3411 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3412
3413 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3414
3415 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3416
3417 MCRegister TmpReg = Mips::ZERO;
3418 if (ImmOp32 != 0) {
3419 TmpReg = getATReg(IDLoc);
3420 if (!TmpReg)
3421 return true;
3422 }
3423
3424 if (Lo_32(ImmOp64) == 0) {
3425 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3426 true, false, IDLoc, Out, STI))
3427 return true;
3428 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3429 return false;
3430 }
3431
3432 MCSection *CS = getStreamer().getCurrentSectionOnly();
3433 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3434 // where appropriate.
3435 MCSection *ReadOnlySection =
3436 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3437
3438 MCSymbol *Sym = getContext().createTempSymbol();
3439 const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3440 const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3441
3442 getStreamer().switchSection(ReadOnlySection);
3443 getStreamer().emitLabel(Sym, IDLoc);
3444 getStreamer().emitInt32(ImmOp32);
3445 getStreamer().switchSection(CS);
3446
3447 if (emitPartialAddress(TOut, IDLoc, Sym))
3448 return true;
3449 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3450 IDLoc, STI);
3451 return false;
3452}
3453
3454bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3455 MCStreamer &Out,
3456 const MCSubtargetInfo *STI) {
3457 MipsTargetStreamer &TOut = getTargetStreamer();
3458 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3459 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3460 "Invalid instruction operand.");
3461
3462 MCRegister FirstReg = Inst.getOperand(0).getReg();
3463 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3464
3465 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3466
3467 if (Lo_32(ImmOp64) == 0) {
3468 if (isGP64bit()) {
3469 if (loadImmediate(ImmOp64, FirstReg, MCRegister(), false, false, IDLoc,
3470 Out, STI))
3471 return true;
3472 } else {
3473 if (loadImmediate(Hi_32(ImmOp64), FirstReg, MCRegister(), true, false,
3474 IDLoc, Out, STI))
3475 return true;
3476
3477 if (loadImmediate(0, nextReg(FirstReg), MCRegister(), true, false, IDLoc,
3478 Out, STI))
3479 return true;
3480 }
3481 return false;
3482 }
3483
3484 MCSection *CS = getStreamer().getCurrentSectionOnly();
3485 MCSection *ReadOnlySection =
3486 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3487
3488 MCSymbol *Sym = getContext().createTempSymbol();
3489 const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3490 const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3491
3492 getStreamer().switchSection(ReadOnlySection);
3493 getStreamer().emitLabel(Sym, IDLoc);
3494 getStreamer().emitValueToAlignment(Align(8));
3495 getStreamer().emitIntValue(ImmOp64, 8);
3496 getStreamer().switchSection(CS);
3497
3498 MCRegister TmpReg = getATReg(IDLoc);
3499 if (!TmpReg)
3500 return true;
3501
3502 if (emitPartialAddress(TOut, IDLoc, Sym))
3503 return true;
3504
3505 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3506 MCOperand::createExpr(LoExpr), IDLoc, STI);
3507
3508 if (isGP64bit())
3509 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3510 else {
3511 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3512 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3513 }
3514 return false;
3515}
3516
3517bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3518 SMLoc IDLoc, MCStreamer &Out,
3519 const MCSubtargetInfo *STI) {
3520 MipsTargetStreamer &TOut = getTargetStreamer();
3521 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3522 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3523 "Invalid instruction operand.");
3524
3525 MCRegister FirstReg = Inst.getOperand(0).getReg();
3526 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3527
3528 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3529
3530 MCRegister TmpReg = Mips::ZERO;
3531 if (ImmOp64 != 0) {
3532 TmpReg = getATReg(IDLoc);
3533 if (!TmpReg)
3534 return true;
3535 }
3536
3537 if ((Lo_32(ImmOp64) == 0) &&
3538 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3539 if (isGP64bit()) {
3540 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3541 false, false, IDLoc, Out, STI))
3542 return true;
3543 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3544 return false;
3545 }
3546
3547 if (TmpReg != Mips::ZERO &&
3548 loadImmediate(Hi_32(ImmOp64), TmpReg, MCRegister(), true, false, IDLoc,
3549 Out, STI))
3550 return true;
3551
3552 if (hasMips32r2()) {
3553 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3554 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3555 } else {
3556 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3557 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3558 }
3559 return false;
3560 }
3561
3562 MCSection *CS = getStreamer().getCurrentSectionOnly();
3563 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3564 // where appropriate.
3565 MCSection *ReadOnlySection =
3566 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3567
3568 MCSymbol *Sym = getContext().createTempSymbol();
3569 const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3570 const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3571
3572 getStreamer().switchSection(ReadOnlySection);
3573 getStreamer().emitLabel(Sym, IDLoc);
3574 getStreamer().emitValueToAlignment(Align(8));
3575 getStreamer().emitIntValue(ImmOp64, 8);
3576 getStreamer().switchSection(CS);
3577
3578 if (emitPartialAddress(TOut, IDLoc, Sym))
3579 return true;
3580
3581 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3582 MCOperand::createExpr(LoExpr), IDLoc, STI);
3583
3584 return false;
3585}
3586
3587bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3588 MCStreamer &Out,
3589 const MCSubtargetInfo *STI) {
3590 MipsTargetStreamer &TOut = getTargetStreamer();
3591
3592 assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 &&
3593 "unexpected number of operands");
3594
3595 MCOperand Offset = Inst.getOperand(0);
3596 if (Offset.isExpr()) {
3597 Inst.clear();
3598 Inst.setOpcode(Mips::BEQ_MM);
3599 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3600 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3601 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3602 } else {
3603 assert(Offset.isImm() && "expected immediate operand kind");
3604 if (isInt<11>(Offset.getImm())) {
3605 // If offset fits into 11 bits then this instruction becomes microMIPS
3606 // 16-bit unconditional branch instruction.
3607 if (inMicroMipsMode())
3608 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3609 } else {
3610 if (!isInt<17>(Offset.getImm()))
3611 return Error(IDLoc, "branch target out of range");
3612 if (offsetToAlignment(Offset.getImm(), Align(2)))
3613 return Error(IDLoc, "branch to misaligned address");
3614 Inst.clear();
3615 Inst.setOpcode(Mips::BEQ_MM);
3616 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3617 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3618 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3619 }
3620 }
3621 Out.emitInstruction(Inst, *STI);
3622
3623 // If .set reorder is active and branch instruction has a delay slot,
3624 // emit a NOP after it.
3625 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3626 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3627 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3628
3629 return false;
3630}
3631
3632bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3633 const MCSubtargetInfo *STI) {
3634 MipsTargetStreamer &TOut = getTargetStreamer();
3635 const MCOperand &DstRegOp = Inst.getOperand(0);
3636 assert(DstRegOp.isReg() && "expected register operand kind");
3637
3638 const MCOperand &ImmOp = Inst.getOperand(1);
3639 assert(ImmOp.isImm() && "expected immediate operand kind");
3640
3641 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3642 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3643 "expected immediate or expression operand");
3644
3645 bool IsLikely = false;
3646
3647 unsigned OpCode = 0;
3648 switch(Inst.getOpcode()) {
3649 case Mips::BneImm:
3650 OpCode = Mips::BNE;
3651 break;
3652 case Mips::BeqImm:
3653 OpCode = Mips::BEQ;
3654 break;
3655 case Mips::BEQLImmMacro:
3656 OpCode = Mips::BEQL;
3657 IsLikely = true;
3658 break;
3659 case Mips::BNELImmMacro:
3660 OpCode = Mips::BNEL;
3661 IsLikely = true;
3662 break;
3663 default:
3664 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3665 break;
3666 }
3667
3668 int64_t ImmValue = ImmOp.getImm();
3669 if (ImmValue == 0) {
3670 if (IsLikely) {
3671 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3672 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3673 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3674 } else
3675 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3676 STI);
3677 } else {
3678 warnIfNoMacro(IDLoc);
3679
3680 MCRegister ATReg = getATReg(IDLoc);
3681 if (!ATReg)
3682 return true;
3683
3684 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(), true, IDLoc,
3685 Out, STI))
3686 return true;
3687
3688 if (IsLikely && MemOffsetOp.isExpr()) {
3689 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3690 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3691 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3692 } else
3693 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3694 }
3695 return false;
3696}
3697
3698void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3699 const MCSubtargetInfo *STI, bool IsLoad) {
3700 unsigned NumOp = Inst.getNumOperands();
3701 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3702 unsigned StartOp = NumOp == 3 ? 0 : 1;
3703
3704 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3705 assert(DstRegOp.isReg() && "expected register operand kind");
3706 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3707 assert(BaseRegOp.isReg() && "expected register operand kind");
3708 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3709
3710 MipsTargetStreamer &TOut = getTargetStreamer();
3711 unsigned OpCode = Inst.getOpcode();
3712 MCRegister DstReg = DstRegOp.getReg();
3713 MCRegister BaseReg = BaseRegOp.getReg();
3714 MCRegister TmpReg = DstReg;
3715
3716 const MCInstrDesc &Desc = MII.get(OpCode);
3717 int16_t DstRegClass =
3718 MII.getOpRegClassID(Desc.operands()[StartOp],
3720 unsigned DstRegClassID =
3721 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3722 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3723 (DstRegClassID == Mips::GPR64RegClassID);
3724
3725 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3726 // At this point we need AT to perform the expansions
3727 // and we exit if it is not available.
3728 TmpReg = getATReg(IDLoc);
3729 if (!TmpReg)
3730 return;
3731 }
3732
3733 auto emitInstWithOffset = [&](const MCOperand &Off) {
3734 if (NumOp == 3)
3735 TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3736 else
3737 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3738 };
3739
3740 if (OffsetOp.isImm()) {
3741 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3742 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3743
3744 // If msb of LoOffset is 1(negative number) we must increment
3745 // HiOffset to account for the sign-extension of the low part.
3746 if (LoOffset & 0x8000)
3747 HiOffset += 0x10000;
3748
3749 bool IsLargeOffset = HiOffset != 0;
3750
3751 if (IsLargeOffset) {
3752 bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3753 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm, true, IDLoc,
3754 Out, STI))
3755 return;
3756 }
3757
3758 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3759 TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3760 TmpReg, BaseReg, IDLoc, STI);
3761 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3762 return;
3763 }
3764
3765 if (OffsetOp.isExpr()) {
3766 if (inPicMode()) {
3767 // FIXME:
3768 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3769 // do not exceed 16-bit.
3770 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3771 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3772 // of GOT entries.
3773 MCValue Res;
3774 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr)) {
3775 Error(IDLoc, "expected relocatable expression");
3776 return;
3777 }
3778 if (Res.getSubSym()) {
3779 Error(IDLoc, "expected relocatable expression with only one symbol");
3780 return;
3781 }
3782
3783 loadAndAddSymbolAddress(
3785 BaseReg, !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3786 emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3787 } else {
3788 // FIXME: Implement 64-bit case.
3789 // 1) lw $8, sym => lui $8, %hi(sym)
3790 // lw $8, %lo(sym)($8)
3791 // 2) sw $8, sym => lui $at, %hi(sym)
3792 // sw $8, %lo(sym)($at)
3793 const MCExpr *OffExpr = OffsetOp.getExpr();
3794 MCOperand LoOperand = MCOperand::createExpr(
3796 MCOperand HiOperand = MCOperand::createExpr(
3798
3799 if (ABI.IsN64()) {
3800 MCOperand HighestOperand = MCOperand::createExpr(
3802 MCOperand HigherOperand = MCOperand::createExpr(
3804
3805 TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3806 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3807 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3808 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3809 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3810 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3811 TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3812 emitInstWithOffset(LoOperand);
3813 } else {
3814 // Generate the base address in TmpReg.
3815 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3816 if (BaseReg != Mips::ZERO)
3817 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3818 // Emit the load or store with the adjusted base and offset.
3819 emitInstWithOffset(LoOperand);
3820 }
3821 }
3822 return;
3823 }
3824
3825 llvm_unreachable("unexpected operand type");
3826}
3827
3828void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3829 const MCSubtargetInfo *STI, bool IsLoad) {
3830 unsigned NumOp = Inst.getNumOperands();
3831 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3832 unsigned StartOp = NumOp == 3 ? 0 : 1;
3833
3834 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3835 assert(DstRegOp.isReg() && "expected register operand kind");
3836 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3837 assert(BaseRegOp.isReg() && "expected register operand kind");
3838 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3839
3840 MipsTargetStreamer &TOut = getTargetStreamer();
3841 unsigned OpCode = Inst.getOpcode();
3842 MCRegister DstReg = DstRegOp.getReg();
3843 MCRegister BaseReg = BaseRegOp.getReg();
3844 MCRegister TmpReg = DstReg;
3845
3846 const MCInstrDesc &Desc = MII.get(OpCode);
3847 int16_t DstRegClass =
3848 MII.getOpRegClassID(Desc.operands()[StartOp],
3850
3851 unsigned DstRegClassID =
3852 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3853 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3854 (DstRegClassID == Mips::GPR64RegClassID);
3855
3856 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3857 // At this point we need AT to perform the expansions
3858 // and we exit if it is not available.
3859 TmpReg = getATReg(IDLoc);
3860 if (!TmpReg)
3861 return;
3862 }
3863
3864 auto emitInst = [&]() {
3865 if (NumOp == 3)
3866 TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3867 else
3868 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3869 IDLoc, STI);
3870 };
3871
3872 if (OffsetOp.isImm()) {
3873 loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3874 IDLoc, Out, STI);
3875 emitInst();
3876 return;
3877 }
3878
3879 if (OffsetOp.isExpr()) {
3880 loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3881 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3882 emitInst();
3883 return;
3884 }
3885
3886 llvm_unreachable("unexpected operand type");
3887}
3888
3889bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3890 MCStreamer &Out,
3891 const MCSubtargetInfo *STI) {
3892 unsigned OpNum = Inst.getNumOperands();
3893 unsigned Opcode = Inst.getOpcode();
3894 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3895
3896 assert(Inst.getOperand(OpNum - 1).isImm() &&
3897 Inst.getOperand(OpNum - 2).isReg() &&
3898 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3899
3900 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3901 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3902 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3903 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3904 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3905 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3906 // It can be implemented as SWM16 or LWM16 instruction.
3907 if (inMicroMipsMode() && hasMips32r6())
3908 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3909 else
3910 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3911 }
3912
3913 Inst.setOpcode(NewOpcode);
3914 Out.emitInstruction(Inst, *STI);
3915 return false;
3916}
3917
3918bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3919 MCStreamer &Out,
3920 const MCSubtargetInfo *STI) {
3921 MipsTargetStreamer &TOut = getTargetStreamer();
3922 bool EmittedNoMacroWarning = false;
3923 unsigned PseudoOpcode = Inst.getOpcode();
3924 MCRegister SrcReg = Inst.getOperand(0).getReg();
3925 const MCOperand &TrgOp = Inst.getOperand(1);
3926 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3927
3928 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3929 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3930
3931 MCRegister TrgReg;
3932 if (TrgOp.isReg())
3933 TrgReg = TrgOp.getReg();
3934 else if (TrgOp.isImm()) {
3935 warnIfNoMacro(IDLoc);
3936 EmittedNoMacroWarning = true;
3937
3938 TrgReg = getATReg(IDLoc);
3939 if (!TrgReg)
3940 return true;
3941
3942 switch(PseudoOpcode) {
3943 default:
3944 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3945 case Mips::BLTImmMacro:
3946 PseudoOpcode = Mips::BLT;
3947 break;
3948 case Mips::BLEImmMacro:
3949 PseudoOpcode = Mips::BLE;
3950 break;
3951 case Mips::BGEImmMacro:
3952 PseudoOpcode = Mips::BGE;
3953 break;
3954 case Mips::BGTImmMacro:
3955 PseudoOpcode = Mips::BGT;
3956 break;
3957 case Mips::BLTUImmMacro:
3958 PseudoOpcode = Mips::BLTU;
3959 break;
3960 case Mips::BLEUImmMacro:
3961 PseudoOpcode = Mips::BLEU;
3962 break;
3963 case Mips::BGEUImmMacro:
3964 PseudoOpcode = Mips::BGEU;
3965 break;
3966 case Mips::BGTUImmMacro:
3967 PseudoOpcode = Mips::BGTU;
3968 break;
3969 case Mips::BLTLImmMacro:
3970 PseudoOpcode = Mips::BLTL;
3971 break;
3972 case Mips::BLELImmMacro:
3973 PseudoOpcode = Mips::BLEL;
3974 break;
3975 case Mips::BGELImmMacro:
3976 PseudoOpcode = Mips::BGEL;
3977 break;
3978 case Mips::BGTLImmMacro:
3979 PseudoOpcode = Mips::BGTL;
3980 break;
3981 case Mips::BLTULImmMacro:
3982 PseudoOpcode = Mips::BLTUL;
3983 break;
3984 case Mips::BLEULImmMacro:
3985 PseudoOpcode = Mips::BLEUL;
3986 break;
3987 case Mips::BGEULImmMacro:
3988 PseudoOpcode = Mips::BGEUL;
3989 break;
3990 case Mips::BGTULImmMacro:
3991 PseudoOpcode = Mips::BGTUL;
3992 break;
3993 }
3994
3995 if (loadImmediate(TrgOp.getImm(), TrgReg, MCRegister(), !isGP64bit(), false,
3996 IDLoc, Out, STI))
3997 return true;
3998 }
3999
4000 switch (PseudoOpcode) {
4001 case Mips::BLT:
4002 case Mips::BLTU:
4003 case Mips::BLTL:
4004 case Mips::BLTUL:
4005 AcceptsEquality = false;
4006 ReverseOrderSLT = false;
4007 IsUnsigned =
4008 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4009 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4010 ZeroSrcOpcode = Mips::BGTZ;
4011 ZeroTrgOpcode = Mips::BLTZ;
4012 break;
4013 case Mips::BLE:
4014 case Mips::BLEU:
4015 case Mips::BLEL:
4016 case Mips::BLEUL:
4017 AcceptsEquality = true;
4018 ReverseOrderSLT = true;
4019 IsUnsigned =
4020 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4021 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4022 ZeroSrcOpcode = Mips::BGEZ;
4023 ZeroTrgOpcode = Mips::BLEZ;
4024 break;
4025 case Mips::BGE:
4026 case Mips::BGEU:
4027 case Mips::BGEL:
4028 case Mips::BGEUL:
4029 AcceptsEquality = true;
4030 ReverseOrderSLT = false;
4031 IsUnsigned =
4032 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4033 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4034 ZeroSrcOpcode = Mips::BLEZ;
4035 ZeroTrgOpcode = Mips::BGEZ;
4036 break;
4037 case Mips::BGT:
4038 case Mips::BGTU:
4039 case Mips::BGTL:
4040 case Mips::BGTUL:
4041 AcceptsEquality = false;
4042 ReverseOrderSLT = true;
4043 IsUnsigned =
4044 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4045 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4046 ZeroSrcOpcode = Mips::BLTZ;
4047 ZeroTrgOpcode = Mips::BGTZ;
4048 break;
4049 default:
4050 llvm_unreachable("unknown opcode for branch pseudo-instruction");
4051 }
4052
4053 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4054 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4055 if (IsSrcRegZero && IsTrgRegZero) {
4056 // FIXME: All of these Opcode-specific if's are needed for compatibility
4057 // with GAS' behaviour. However, they may not generate the most efficient
4058 // code in some circumstances.
4059 if (PseudoOpcode == Mips::BLT) {
4060 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4061 IDLoc, STI);
4062 return false;
4063 }
4064 if (PseudoOpcode == Mips::BLE) {
4065 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4066 IDLoc, STI);
4067 Warning(IDLoc, "branch is always taken");
4068 return false;
4069 }
4070 if (PseudoOpcode == Mips::BGE) {
4071 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4072 IDLoc, STI);
4073 Warning(IDLoc, "branch is always taken");
4074 return false;
4075 }
4076 if (PseudoOpcode == Mips::BGT) {
4077 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4078 IDLoc, STI);
4079 return false;
4080 }
4081 if (PseudoOpcode == Mips::BGTU) {
4082 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4083 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4084 return false;
4085 }
4086 if (AcceptsEquality) {
4087 // If both registers are $0 and the pseudo-branch accepts equality, it
4088 // will always be taken, so we emit an unconditional branch.
4089 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4090 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4091 Warning(IDLoc, "branch is always taken");
4092 return false;
4093 }
4094 // If both registers are $0 and the pseudo-branch does not accept
4095 // equality, it will never be taken, so we don't have to emit anything.
4096 return false;
4097 }
4098 if (IsSrcRegZero || IsTrgRegZero) {
4099 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4100 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4101 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4102 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4103 // the pseudo-branch will never be taken, so we don't emit anything.
4104 // This only applies to unsigned pseudo-branches.
4105 return false;
4106 }
4107 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4108 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4109 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4110 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4111 // the pseudo-branch will always be taken, so we emit an unconditional
4112 // branch.
4113 // This only applies to unsigned pseudo-branches.
4114 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4115 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4116 Warning(IDLoc, "branch is always taken");
4117 return false;
4118 }
4119 if (IsUnsigned) {
4120 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4121 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4122 // the pseudo-branch will be taken only when the non-zero register is
4123 // different from 0, so we emit a BNEZ.
4124 //
4125 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4126 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4127 // the pseudo-branch will be taken only when the non-zero register is
4128 // equal to 0, so we emit a BEQZ.
4129 //
4130 // Because only BLEU and BGEU branch on equality, we can use the
4131 // AcceptsEquality variable to decide when to emit the BEQZ.
4132 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4133 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4134 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4135 return false;
4136 }
4137 // If we have a signed pseudo-branch and one of the registers is $0,
4138 // we can use an appropriate compare-to-zero branch. We select which one
4139 // to use in the switch statement above.
4140 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4141 IsSrcRegZero ? TrgReg : SrcReg,
4142 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4143 return false;
4144 }
4145
4146 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4147 // expansions. If it is not available, we return.
4148 MCRegister ATRegNum = getATReg(IDLoc);
4149 if (!ATRegNum)
4150 return true;
4151
4152 if (!EmittedNoMacroWarning)
4153 warnIfNoMacro(IDLoc);
4154
4155 // SLT fits well with 2 of our 4 pseudo-branches:
4156 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4157 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4158 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4159 // This is accomplished by using a BNEZ with the result of the SLT.
4160 //
4161 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4162 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4163 // Because only BGE and BLE branch on equality, we can use the
4164 // AcceptsEquality variable to decide when to emit the BEQZ.
4165 // Note that the order of the SLT arguments doesn't change between
4166 // opposites.
4167 //
4168 // The same applies to the unsigned variants, except that SLTu is used
4169 // instead of SLT.
4170 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4171 ReverseOrderSLT ? TrgReg : SrcReg,
4172 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4173
4174 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4175 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4176 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4177 STI);
4178 return false;
4179}
4180
4181// Expand a integer division macro.
4182//
4183// Notably we don't have to emit a warning when encountering $rt as the $zero
4184// register, or 0 as an immediate. processInstruction() has already done that.
4185//
4186// The destination register can only be $zero when expanding (S)DivIMacro or
4187// D(S)DivMacro.
4188
4189bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4190 const MCSubtargetInfo *STI,
4191 const bool IsMips64, const bool Signed) {
4192 MipsTargetStreamer &TOut = getTargetStreamer();
4193
4194 warnIfNoMacro(IDLoc);
4195
4196 const MCOperand &RdRegOp = Inst.getOperand(0);
4197 assert(RdRegOp.isReg() && "expected register operand kind");
4198 MCRegister RdReg = RdRegOp.getReg();
4199
4200 const MCOperand &RsRegOp = Inst.getOperand(1);
4201 assert(RsRegOp.isReg() && "expected register operand kind");
4202 MCRegister RsReg = RsRegOp.getReg();
4203
4204 MCRegister RtReg;
4205 int64_t ImmValue;
4206
4207 const MCOperand &RtOp = Inst.getOperand(2);
4208 assert((RtOp.isReg() || RtOp.isImm()) &&
4209 "expected register or immediate operand kind");
4210 if (RtOp.isReg())
4211 RtReg = RtOp.getReg();
4212 else
4213 ImmValue = RtOp.getImm();
4214
4215 unsigned DivOp;
4216 unsigned ZeroReg;
4217 unsigned SubOp;
4218
4219 if (IsMips64) {
4220 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4221 ZeroReg = Mips::ZERO_64;
4222 SubOp = Mips::DSUB;
4223 } else {
4224 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4225 ZeroReg = Mips::ZERO;
4226 SubOp = Mips::SUB;
4227 }
4228
4229 bool UseTraps = useTraps();
4230
4231 unsigned Opcode = Inst.getOpcode();
4232 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4233 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4234 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4235 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4236
4237 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4238 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4239 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4240 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4241
4242 if (RtOp.isImm()) {
4243 MCRegister ATReg = getATReg(IDLoc);
4244 if (!ATReg)
4245 return true;
4246
4247 if (!NoZeroDivCheck && ImmValue == 0) {
4248 if (UseTraps)
4249 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4250 else
4251 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4252 return false;
4253 }
4254
4255 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4256 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4257 return false;
4258 } else if (isDiv && ImmValue == 1) {
4259 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4260 return false;
4261 } else if (isDiv && Signed && ImmValue == -1) {
4262 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4263 return false;
4264 } else {
4265 if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue),
4266 false, Inst.getLoc(), Out, STI))
4267 return true;
4268 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4269 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4270 return false;
4271 }
4272 return true;
4273 }
4274
4275 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4276 // break, insert the trap/break and exit. This gives a different result to
4277 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4278 // are handled equivalently. As the observed behaviour is the same, we're ok.
4279 if (!NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4280 if (UseTraps) {
4281 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4282 return false;
4283 }
4284 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4285 return false;
4286 }
4287
4288 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4289 // not expand to macro sequence.
4290 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4291 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4292 return false;
4293 }
4294
4295 // Temporary label for first branch traget
4296 MCContext &Context = TOut.getContext();
4297 MCSymbol *BrTarget;
4298 MCOperand LabelOp;
4299
4300 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4301 if (!NoZeroDivCheck) {
4302 if (UseTraps) {
4303 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4304 } else {
4305 // Branch to the li instruction.
4306 BrTarget = Context.createTempSymbol();
4307 LabelOp =
4309 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4310 TOut.emitNop(IDLoc, STI);
4311 }
4312
4313 if (!UseTraps)
4314 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4315
4316 if (!UseTraps)
4317 TOut.getStreamer().emitLabel(BrTarget);
4318 }
4319
4320 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4321 return false;
4322}
4323
4324bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4325 SMLoc IDLoc, MCStreamer &Out,
4326 const MCSubtargetInfo *STI) {
4327 MipsTargetStreamer &TOut = getTargetStreamer();
4328
4329 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4330 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4331 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4332
4333 MCRegister FirstReg = Inst.getOperand(0).getReg();
4334 MCRegister SecondReg = Inst.getOperand(1).getReg();
4335 MCRegister ThirdReg = Inst.getOperand(2).getReg();
4336
4337 if (hasMips1() && !hasMips2()) {
4338 MCRegister ATReg = getATReg(IDLoc);
4339 if (!ATReg)
4340 return true;
4341 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4342 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4343 TOut.emitNop(IDLoc, STI);
4344 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4345 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4346 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4347 TOut.emitNop(IDLoc, STI);
4348 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4349 : Mips::CVT_W_S,
4350 FirstReg, SecondReg, IDLoc, STI);
4351 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4352 TOut.emitNop(IDLoc, STI);
4353 return false;
4354 }
4355
4356 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4357 : Mips::TRUNC_W_S,
4358 FirstReg, SecondReg, IDLoc, STI);
4359
4360 return false;
4361}
4362
4363bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4364 MCStreamer &Out, const MCSubtargetInfo *STI) {
4365 if (hasMips32r6() || hasMips64r6()) {
4366 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4367 }
4368
4369 const MCOperand &DstRegOp = Inst.getOperand(0);
4370 assert(DstRegOp.isReg() && "expected register operand kind");
4371 const MCOperand &SrcRegOp = Inst.getOperand(1);
4372 assert(SrcRegOp.isReg() && "expected register operand kind");
4373 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4374 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4375
4376 MipsTargetStreamer &TOut = getTargetStreamer();
4377 MCRegister DstReg = DstRegOp.getReg();
4378 MCRegister SrcReg = SrcRegOp.getReg();
4379 int64_t OffsetValue = OffsetImmOp.getImm();
4380
4381 // NOTE: We always need AT for ULHU, as it is always used as the source
4382 // register for one of the LBu's.
4383 warnIfNoMacro(IDLoc);
4384 MCRegister ATReg = getATReg(IDLoc);
4385 if (!ATReg)
4386 return true;
4387
4388 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4389 if (IsLargeOffset) {
4390 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4391 IDLoc, Out, STI))
4392 return true;
4393 }
4394
4395 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4396 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4397 if (isLittle())
4398 std::swap(FirstOffset, SecondOffset);
4399
4400 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4401 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4402
4403 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4404 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4405
4406 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4407 FirstOffset, IDLoc, STI);
4408 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4409 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4410 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4411
4412 return false;
4413}
4414
4415bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4416 const MCSubtargetInfo *STI) {
4417 if (hasMips32r6() || hasMips64r6()) {
4418 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4419 }
4420
4421 const MCOperand &DstRegOp = Inst.getOperand(0);
4422 assert(DstRegOp.isReg() && "expected register operand kind");
4423 const MCOperand &SrcRegOp = Inst.getOperand(1);
4424 assert(SrcRegOp.isReg() && "expected register operand kind");
4425 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4426 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4427
4428 MipsTargetStreamer &TOut = getTargetStreamer();
4429 MCRegister DstReg = DstRegOp.getReg();
4430 MCRegister SrcReg = SrcRegOp.getReg();
4431 int64_t OffsetValue = OffsetImmOp.getImm();
4432
4433 warnIfNoMacro(IDLoc);
4434 MCRegister ATReg = getATReg(IDLoc);
4435 if (!ATReg)
4436 return true;
4437
4438 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4439 if (IsLargeOffset) {
4440 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4441 IDLoc, Out, STI))
4442 return true;
4443 }
4444
4445 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4446 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4447 if (isLittle())
4448 std::swap(FirstOffset, SecondOffset);
4449
4450 if (IsLargeOffset) {
4451 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4452 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4453 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4454 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4455 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4456 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4457 } else {
4458 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4459 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4460 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4461 }
4462
4463 return false;
4464}
4465
4466bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4467 const MCSubtargetInfo *STI) {
4468 if (hasMips32r6() || hasMips64r6()) {
4469 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4470 }
4471
4472 const MCOperand &DstRegOp = Inst.getOperand(0);
4473 assert(DstRegOp.isReg() && "expected register operand kind");
4474 const MCOperand &SrcRegOp = Inst.getOperand(1);
4475 assert(SrcRegOp.isReg() && "expected register operand kind");
4476 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4477 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4478
4479 MipsTargetStreamer &TOut = getTargetStreamer();
4480 MCRegister DstReg = DstRegOp.getReg();
4481 MCRegister SrcReg = SrcRegOp.getReg();
4482 int64_t OffsetValue = OffsetImmOp.getImm();
4483
4484 // Compute left/right load/store offsets.
4485 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4486 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4487 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4488 if (isLittle())
4489 std::swap(LxlOffset, LxrOffset);
4490
4491 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4492 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4493 MCRegister TmpReg = SrcReg;
4494 if (IsLargeOffset || DoMove) {
4495 warnIfNoMacro(IDLoc);
4496 TmpReg = getATReg(IDLoc);
4497 if (!TmpReg)
4498 return true;
4499 }
4500
4501 if (IsLargeOffset) {
4502 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4503 IDLoc, Out, STI))
4504 return true;
4505 }
4506
4507 if (DoMove)
4508 std::swap(DstReg, TmpReg);
4509
4510 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4511 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4512 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4513 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4514
4515 if (DoMove)
4516 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4517
4518 return false;
4519}
4520
4521bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4522 const MCSubtargetInfo *STI) {
4523 MipsTargetStreamer &TOut = getTargetStreamer();
4524
4525 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4526 assert(Inst.getOperand(0).isReg() &&
4527 Inst.getOperand(1).isReg() &&
4528 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4529
4530 MCRegister DstReg = Inst.getOperand(0).getReg();
4531 MCRegister SrcReg = Inst.getOperand(1).getReg();
4532 MCRegister OpReg = Inst.getOperand(2).getReg();
4533 unsigned OpCode;
4534
4535 warnIfNoMacro(IDLoc);
4536
4537 switch (Inst.getOpcode()) {
4538 case Mips::SGE:
4539 OpCode = Mips::SLT;
4540 break;
4541 case Mips::SGEU:
4542 OpCode = Mips::SLTu;
4543 break;
4544 default:
4545 llvm_unreachable("unexpected 'sge' opcode");
4546 }
4547
4548 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4549 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4550 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4551
4552 return false;
4553}
4554
4555bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4556 const MCSubtargetInfo *STI) {
4557 MipsTargetStreamer &TOut = getTargetStreamer();
4558
4559 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4560 assert(Inst.getOperand(0).isReg() &&
4561 Inst.getOperand(1).isReg() &&
4562 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4563
4564 MCRegister DstReg = Inst.getOperand(0).getReg();
4565 MCRegister SrcReg = Inst.getOperand(1).getReg();
4566 int64_t ImmValue = Inst.getOperand(2).getImm();
4567 unsigned OpRegCode, OpImmCode;
4568
4569 warnIfNoMacro(IDLoc);
4570
4571 switch (Inst.getOpcode()) {
4572 case Mips::SGEImm:
4573 case Mips::SGEImm64:
4574 OpRegCode = Mips::SLT;
4575 OpImmCode = Mips::SLTi;
4576 break;
4577 case Mips::SGEUImm:
4578 case Mips::SGEUImm64:
4579 OpRegCode = Mips::SLTu;
4580 OpImmCode = Mips::SLTiu;
4581 break;
4582 default:
4583 llvm_unreachable("unexpected 'sge' opcode with immediate");
4584 }
4585
4586 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4587 if (isInt<16>(ImmValue)) {
4588 // Use immediate version of STL.
4589 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4590 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4591 } else {
4592 MCRegister ImmReg = DstReg;
4593 if (DstReg == SrcReg) {
4594 MCRegister ATReg = getATReg(Inst.getLoc());
4595 if (!ATReg)
4596 return true;
4597 ImmReg = ATReg;
4598 }
4599
4600 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue),
4601 false, IDLoc, Out, STI))
4602 return true;
4603
4604 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4605 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4606 }
4607
4608 return false;
4609}
4610
4611bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4612 const MCSubtargetInfo *STI) {
4613 MipsTargetStreamer &TOut = getTargetStreamer();
4614
4615 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4616 assert(Inst.getOperand(0).isReg() &&
4617 Inst.getOperand(1).isReg() &&
4618 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4619
4620 MCRegister DstReg = Inst.getOperand(0).getReg();
4621 MCRegister SrcReg = Inst.getOperand(1).getReg();
4622 MCRegister ImmReg = DstReg;
4623 int64_t ImmValue = Inst.getOperand(2).getImm();
4624 unsigned OpCode;
4625
4626 warnIfNoMacro(IDLoc);
4627
4628 switch (Inst.getOpcode()) {
4629 case Mips::SGTImm:
4630 case Mips::SGTImm64:
4631 OpCode = Mips::SLT;
4632 break;
4633 case Mips::SGTUImm:
4634 case Mips::SGTUImm64:
4635 OpCode = Mips::SLTu;
4636 break;
4637 default:
4638 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4639 }
4640
4641 if (DstReg == SrcReg) {
4642 MCRegister ATReg = getATReg(Inst.getLoc());
4643 if (!ATReg)
4644 return true;
4645 ImmReg = ATReg;
4646 }
4647
4648 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4649 IDLoc, Out, STI))
4650 return true;
4651
4652 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4653 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4654
4655 return false;
4656}
4657
4658bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4659 const MCSubtargetInfo *STI) {
4660 MipsTargetStreamer &TOut = getTargetStreamer();
4661
4662 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4663 assert(Inst.getOperand(0).isReg() &&
4664 Inst.getOperand(1).isReg() &&
4665 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4666
4667 MCRegister DstReg = Inst.getOperand(0).getReg();
4668 MCRegister SrcReg = Inst.getOperand(1).getReg();
4669 MCRegister OpReg = Inst.getOperand(2).getReg();
4670 unsigned OpCode;
4671
4672 warnIfNoMacro(IDLoc);
4673
4674 switch (Inst.getOpcode()) {
4675 case Mips::SLE:
4676 OpCode = Mips::SLT;
4677 break;
4678 case Mips::SLEU:
4679 OpCode = Mips::SLTu;
4680 break;
4681 default:
4682 llvm_unreachable("unexpected 'sge' opcode");
4683 }
4684
4685 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4686 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4687 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4688
4689 return false;
4690}
4691
4692bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4693 const MCSubtargetInfo *STI) {
4694 MipsTargetStreamer &TOut = getTargetStreamer();
4695
4696 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4697 assert(Inst.getOperand(0).isReg() &&
4698 Inst.getOperand(1).isReg() &&
4699 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4700
4701 MCRegister DstReg = Inst.getOperand(0).getReg();
4702 MCRegister SrcReg = Inst.getOperand(1).getReg();
4703 int64_t ImmValue = Inst.getOperand(2).getImm();
4704 unsigned OpRegCode;
4705
4706 warnIfNoMacro(IDLoc);
4707
4708 switch (Inst.getOpcode()) {
4709 case Mips::SLEImm:
4710 case Mips::SLEImm64:
4711 OpRegCode = Mips::SLT;
4712 break;
4713 case Mips::SLEUImm:
4714 case Mips::SLEUImm64:
4715 OpRegCode = Mips::SLTu;
4716 break;
4717 default:
4718 llvm_unreachable("unexpected 'sge' opcode with immediate");
4719 }
4720
4721 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4722 MCRegister ImmReg = DstReg;
4723 if (DstReg == SrcReg) {
4724 MCRegister ATReg = getATReg(Inst.getLoc());
4725 if (!ATReg)
4726 return true;
4727 ImmReg = ATReg;
4728 }
4729
4730 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4731 IDLoc, Out, STI))
4732 return true;
4733
4734 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4735 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4736
4737 return false;
4738}
4739
4740bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4741 MCStreamer &Out,
4742 const MCSubtargetInfo *STI) {
4743 MipsTargetStreamer &TOut = getTargetStreamer();
4744
4745 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4746 assert(Inst.getOperand(0).isReg() &&
4747 Inst.getOperand(1).isReg() &&
4748 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4749
4750 MCRegister ATReg;
4751 MCRegister FinalDstReg;
4752 MCRegister DstReg = Inst.getOperand(0).getReg();
4753 MCRegister SrcReg = Inst.getOperand(1).getReg();
4754 int64_t ImmValue = Inst.getOperand(2).getImm();
4755
4756 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4757
4758 unsigned FinalOpcode = Inst.getOpcode();
4759
4760 if (DstReg == SrcReg) {
4761 ATReg = getATReg(Inst.getLoc());
4762 if (!ATReg)
4763 return true;
4764 FinalDstReg = DstReg;
4765 DstReg = ATReg;
4766 }
4767
4768 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit, false,
4769 Inst.getLoc(), Out, STI)) {
4770 switch (FinalOpcode) {
4771 default:
4772 llvm_unreachable("unimplemented expansion");
4773 case Mips::ADDi:
4774 FinalOpcode = Mips::ADD;
4775 break;
4776 case Mips::ADDiu:
4777 FinalOpcode = Mips::ADDu;
4778 break;
4779 case Mips::ANDi:
4780 FinalOpcode = Mips::AND;
4781 break;
4782 case Mips::NORImm:
4783 FinalOpcode = Mips::NOR;
4784 break;
4785 case Mips::ORi:
4786 FinalOpcode = Mips::OR;
4787 break;
4788 case Mips::SLTi:
4789 FinalOpcode = Mips::SLT;
4790 break;
4791 case Mips::SLTiu:
4792 FinalOpcode = Mips::SLTu;
4793 break;
4794 case Mips::XORi:
4795 FinalOpcode = Mips::XOR;
4796 break;
4797 case Mips::ADDi_MM:
4798 FinalOpcode = Mips::ADD_MM;
4799 break;
4800 case Mips::ADDiu_MM:
4801 FinalOpcode = Mips::ADDu_MM;
4802 break;
4803 case Mips::ANDi_MM:
4804 FinalOpcode = Mips::AND_MM;
4805 break;
4806 case Mips::ORi_MM:
4807 FinalOpcode = Mips::OR_MM;
4808 break;
4809 case Mips::SLTi_MM:
4810 FinalOpcode = Mips::SLT_MM;
4811 break;
4812 case Mips::SLTiu_MM:
4813 FinalOpcode = Mips::SLTu_MM;
4814 break;
4815 case Mips::XORi_MM:
4816 FinalOpcode = Mips::XOR_MM;
4817 break;
4818 case Mips::ANDi64:
4819 FinalOpcode = Mips::AND64;
4820 break;
4821 case Mips::NORImm64:
4822 FinalOpcode = Mips::NOR64;
4823 break;
4824 case Mips::ORi64:
4825 FinalOpcode = Mips::OR64;
4826 break;
4827 case Mips::SLTImm64:
4828 FinalOpcode = Mips::SLT64;
4829 break;
4830 case Mips::SLTUImm64:
4831 FinalOpcode = Mips::SLTu64;
4832 break;
4833 case Mips::XORi64:
4834 FinalOpcode = Mips::XOR64;
4835 break;
4836 }
4837
4838 if (!FinalDstReg)
4839 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4840 else
4841 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4842 return false;
4843 }
4844 return true;
4845}
4846
4847bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4848 const MCSubtargetInfo *STI) {
4849 MipsTargetStreamer &TOut = getTargetStreamer();
4850 MCRegister ATReg;
4851 MCRegister DReg = Inst.getOperand(0).getReg();
4852 MCRegister SReg = Inst.getOperand(1).getReg();
4853 MCRegister TReg = Inst.getOperand(2).getReg();
4854 MCRegister TmpReg = DReg;
4855
4856 unsigned FirstShift = Mips::NOP;
4857 unsigned SecondShift = Mips::NOP;
4858
4859 if (hasMips32r2()) {
4860 if (DReg == SReg) {
4861 TmpReg = getATReg(Inst.getLoc());
4862 if (!TmpReg)
4863 return true;
4864 }
4865
4866 if (Inst.getOpcode() == Mips::ROL) {
4867 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4868 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4869 return false;
4870 }
4871
4872 if (Inst.getOpcode() == Mips::ROR) {
4873 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4874 return false;
4875 }
4876
4877 return true;
4878 }
4879
4880 if (hasMips32()) {
4881 switch (Inst.getOpcode()) {
4882 default:
4883 llvm_unreachable("unexpected instruction opcode");
4884 case Mips::ROL:
4885 FirstShift = Mips::SRLV;
4886 SecondShift = Mips::SLLV;
4887 break;
4888 case Mips::ROR:
4889 FirstShift = Mips::SLLV;
4890 SecondShift = Mips::SRLV;
4891 break;
4892 }
4893
4894 ATReg = getATReg(Inst.getLoc());
4895 if (!ATReg)
4896 return true;
4897
4898 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4899 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4900 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4901 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4902
4903 return false;
4904 }
4905
4906 return true;
4907}
4908
4909bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4910 MCStreamer &Out,
4911 const MCSubtargetInfo *STI) {
4912 MipsTargetStreamer &TOut = getTargetStreamer();
4913 MCRegister ATReg;
4914 MCRegister DReg = Inst.getOperand(0).getReg();
4915 MCRegister SReg = Inst.getOperand(1).getReg();
4916 int64_t ImmValue = Inst.getOperand(2).getImm();
4917
4918 unsigned FirstShift = Mips::NOP;
4919 unsigned SecondShift = Mips::NOP;
4920
4921 if (hasMips32r2()) {
4922 if (Inst.getOpcode() == Mips::ROLImm) {
4923 uint64_t MaxShift = 32;
4924 uint64_t ShiftValue = ImmValue;
4925 if (ImmValue != 0)
4926 ShiftValue = MaxShift - ImmValue;
4927 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4928 return false;
4929 }
4930
4931 if (Inst.getOpcode() == Mips::RORImm) {
4932 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4933 return false;
4934 }
4935
4936 return true;
4937 }
4938
4939 if (hasMips32()) {
4940 if (ImmValue == 0) {
4941 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4942 return false;
4943 }
4944
4945 switch (Inst.getOpcode()) {
4946 default:
4947 llvm_unreachable("unexpected instruction opcode");
4948 case Mips::ROLImm:
4949 FirstShift = Mips::SLL;
4950 SecondShift = Mips::SRL;
4951 break;
4952 case Mips::RORImm:
4953 FirstShift = Mips::SRL;
4954 SecondShift = Mips::SLL;
4955 break;
4956 }
4957
4958 ATReg = getATReg(Inst.getLoc());
4959 if (!ATReg)
4960 return true;
4961
4962 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4963 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4964 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4965
4966 return false;
4967 }
4968
4969 return true;
4970}
4971
4972bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4973 const MCSubtargetInfo *STI) {
4974 MipsTargetStreamer &TOut = getTargetStreamer();
4975 MCRegister ATReg;
4976 MCRegister DReg = Inst.getOperand(0).getReg();
4977 MCRegister SReg = Inst.getOperand(1).getReg();
4978 MCRegister TReg = Inst.getOperand(2).getReg();
4979 MCRegister TmpReg = DReg;
4980
4981 unsigned FirstShift = Mips::NOP;
4982 unsigned SecondShift = Mips::NOP;
4983
4984 if (hasMips64r2()) {
4985 if (TmpReg == SReg) {
4986 TmpReg = getATReg(Inst.getLoc());
4987 if (!TmpReg)
4988 return true;
4989 }
4990
4991 if (Inst.getOpcode() == Mips::DROL) {
4992 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4993 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4994 return false;
4995 }
4996
4997 if (Inst.getOpcode() == Mips::DROR) {
4998 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4999 return false;
5000 }
5001
5002 return true;
5003 }
5004
5005 if (hasMips64()) {
5006 switch (Inst.getOpcode()) {
5007 default:
5008 llvm_unreachable("unexpected instruction opcode");
5009 case Mips::DROL:
5010 FirstShift = Mips::DSRLV;
5011 SecondShift = Mips::DSLLV;
5012 break;
5013 case Mips::DROR:
5014 FirstShift = Mips::DSLLV;
5015 SecondShift = Mips::DSRLV;
5016 break;
5017 }
5018
5019 ATReg = getATReg(Inst.getLoc());
5020 if (!ATReg)
5021 return true;
5022
5023 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5024 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5025 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5026 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5027
5028 return false;
5029 }
5030
5031 return true;
5032}
5033
5034bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5035 MCStreamer &Out,
5036 const MCSubtargetInfo *STI) {
5037 MipsTargetStreamer &TOut = getTargetStreamer();
5038 MCRegister ATReg;
5039 MCRegister DReg = Inst.getOperand(0).getReg();
5040 MCRegister SReg = Inst.getOperand(1).getReg();
5041 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5042
5043 unsigned FirstShift = Mips::NOP;
5044 unsigned SecondShift = Mips::NOP;
5045
5046 MCInst TmpInst;
5047
5048 if (hasMips64r2()) {
5049 unsigned FinalOpcode = Mips::NOP;
5050 if (ImmValue == 0)
5051 FinalOpcode = Mips::DROTR;
5052 else if (ImmValue % 32 == 0)
5053 FinalOpcode = Mips::DROTR32;
5054 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5055 if (Inst.getOpcode() == Mips::DROLImm)
5056 FinalOpcode = Mips::DROTR32;
5057 else
5058 FinalOpcode = Mips::DROTR;
5059 } else if (ImmValue >= 33) {
5060 if (Inst.getOpcode() == Mips::DROLImm)
5061 FinalOpcode = Mips::DROTR;
5062 else
5063 FinalOpcode = Mips::DROTR32;
5064 }
5065
5066 uint64_t ShiftValue = ImmValue % 32;
5067 if (Inst.getOpcode() == Mips::DROLImm)
5068 ShiftValue = (32 - ImmValue % 32) % 32;
5069
5070 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5071
5072 return false;
5073 }
5074
5075 if (hasMips64()) {
5076 if (ImmValue == 0) {
5077 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5078 return false;
5079 }
5080
5081 switch (Inst.getOpcode()) {
5082 default:
5083 llvm_unreachable("unexpected instruction opcode");
5084 case Mips::DROLImm:
5085 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5086 FirstShift = Mips::DSLL;
5087 SecondShift = Mips::DSRL32;
5088 }
5089 if (ImmValue == 32) {
5090 FirstShift = Mips::DSLL32;
5091 SecondShift = Mips::DSRL32;
5092 }
5093 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5094 FirstShift = Mips::DSLL32;
5095 SecondShift = Mips::DSRL;
5096 }
5097 break;
5098 case Mips::DRORImm:
5099 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5100 FirstShift = Mips::DSRL;
5101 SecondShift = Mips::DSLL32;
5102 }
5103 if (ImmValue == 32) {
5104 FirstShift = Mips::DSRL32;
5105 SecondShift = Mips::DSLL32;
5106 }
5107 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5108 FirstShift = Mips::DSRL32;
5109 SecondShift = Mips::DSLL;
5110 }
5111 break;
5112 }
5113
5114 ATReg = getATReg(Inst.getLoc());
5115 if (!ATReg)
5116 return true;
5117
5118 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5119 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5120 Inst.getLoc(), STI);
5121 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5122
5123 return false;
5124 }
5125
5126 return true;
5127}
5128
5129bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5130 const MCSubtargetInfo *STI) {
5131 MipsTargetStreamer &TOut = getTargetStreamer();
5132 MCRegister FirstRegOp = Inst.getOperand(0).getReg();
5133 MCRegister SecondRegOp = Inst.getOperand(1).getReg();
5134
5135 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5136 if (FirstRegOp != SecondRegOp)
5137 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5138 else
5139 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5140 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5141
5142 return false;
5143}
5144
5145bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5146 const MCSubtargetInfo *STI) {
5147 MipsTargetStreamer &TOut = getTargetStreamer();
5148 MCRegister ATReg;
5149 MCRegister DstReg = Inst.getOperand(0).getReg();
5150 MCRegister SrcReg = Inst.getOperand(1).getReg();
5151 int32_t ImmValue = Inst.getOperand(2).getImm();
5152
5153 ATReg = getATReg(IDLoc);
5154 if (!ATReg)
5155 return true;
5156
5157 loadImmediate(ImmValue, ATReg, MCRegister(), true, false, IDLoc, Out, STI);
5158
5159 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5160 SrcReg, ATReg, IDLoc, STI);
5161
5162 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5163
5164 return false;
5165}
5166
5167bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5168 const MCSubtargetInfo *STI) {
5169 MipsTargetStreamer &TOut = getTargetStreamer();
5170 MCRegister ATReg;
5171 MCRegister DstReg = Inst.getOperand(0).getReg();
5172 MCRegister SrcReg = Inst.getOperand(1).getReg();
5173 MCRegister TmpReg = Inst.getOperand(2).getReg();
5174
5175 ATReg = getATReg(Inst.getLoc());
5176 if (!ATReg)
5177 return true;
5178
5179 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5180 SrcReg, TmpReg, IDLoc, STI);
5181
5182 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5183
5184 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5185 DstReg, DstReg, 0x1F, IDLoc, STI);
5186
5187 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5188
5189 if (useTraps()) {
5190 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5191 } else {
5192 MCContext &Context = TOut.getContext();
5193 MCSymbol * BrTarget = Context.createTempSymbol();
5194 MCOperand LabelOp =
5196
5197 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5198 if (AssemblerOptions.back()->isReorder())
5199 TOut.emitNop(IDLoc, STI);
5200 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5201
5202 TOut.getStreamer().emitLabel(BrTarget);
5203 }
5204 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5205
5206 return false;
5207}
5208
5209bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5210 const MCSubtargetInfo *STI) {
5211 MipsTargetStreamer &TOut = getTargetStreamer();
5212 MCRegister ATReg;
5213 MCRegister DstReg = Inst.getOperand(0).getReg();
5214 MCRegister SrcReg = Inst.getOperand(1).getReg();
5215 MCRegister TmpReg = Inst.getOperand(2).getReg();
5216
5217 ATReg = getATReg(IDLoc);
5218 if (!ATReg)
5219 return true;
5220
5221 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5222 SrcReg, TmpReg, IDLoc, STI);
5223
5224 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5225 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5226 if (useTraps()) {
5227 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5228 } else {
5229 MCContext &Context = TOut.getContext();
5230 MCSymbol * BrTarget = Context.createTempSymbol();
5231 MCOperand LabelOp =
5233
5234 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5235 if (AssemblerOptions.back()->isReorder())
5236 TOut.emitNop(IDLoc, STI);
5237 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5238
5239 TOut.getStreamer().emitLabel(BrTarget);
5240 }
5241
5242 return false;
5243}
5244
5245bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5246 const MCSubtargetInfo *STI) {
5247 MipsTargetStreamer &TOut = getTargetStreamer();
5248 MCRegister DstReg = Inst.getOperand(0).getReg();
5249 MCRegister SrcReg = Inst.getOperand(1).getReg();
5250 MCRegister TmpReg = Inst.getOperand(2).getReg();
5251
5252 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5253 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5254
5255 return false;
5256}
5257
5258// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5259// lw $<reg+1>>, offset+4($reg2)'
5260// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5261// sw $<reg+1>>, offset+4($reg2)'
5262// for O32.
5263bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5264 MCStreamer &Out,
5265 const MCSubtargetInfo *STI,
5266 bool IsLoad) {
5267 if (!isABI_O32())
5268 return true;
5269
5270 warnIfNoMacro(IDLoc);
5271
5272 MipsTargetStreamer &TOut = getTargetStreamer();
5273 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5274 MCRegister FirstReg = Inst.getOperand(0).getReg();
5275 MCRegister SecondReg = nextReg(FirstReg);
5276 MCRegister BaseReg = Inst.getOperand(1).getReg();
5277 if (!SecondReg)
5278 return true;
5279
5280 warnIfRegIndexIsAT(FirstReg, IDLoc);
5281
5282 assert(Inst.getOperand(2).isImm() &&
5283 "Offset for load macro is not immediate!");
5284
5285 MCOperand &FirstOffset = Inst.getOperand(2);
5286 signed NextOffset = FirstOffset.getImm() + 4;
5287 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5288
5289 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5290 return true;
5291
5292 // For loads, clobber the base register with the second load instead of the
5293 // first if the BaseReg == FirstReg.
5294 if (FirstReg != BaseReg || !IsLoad) {
5295 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5296 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5297 } else {
5298 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5299 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5300 }
5301
5302 return false;
5303}
5304
5305
5306// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5307// swc1 $<reg>, offset+4($reg2)'
5308// or if little endian to 'swc1 $<reg>, offset($reg2);
5309// swc1 $<reg+1>, offset+4($reg2)'
5310// for Mips1.
5311bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5312 MCStreamer &Out,
5313 const MCSubtargetInfo *STI) {
5314 if (!isABI_O32())
5315 return true;
5316
5317 warnIfNoMacro(IDLoc);
5318
5319 MipsTargetStreamer &TOut = getTargetStreamer();
5320 unsigned Opcode = Mips::SWC1;
5321 MCRegister FirstReg = Inst.getOperand(0).getReg();
5322 MCRegister SecondReg = nextReg(FirstReg);
5323 MCRegister BaseReg = Inst.getOperand(1).getReg();
5324 if (!SecondReg)
5325 return true;
5326
5327 warnIfRegIndexIsAT(FirstReg, IDLoc);
5328
5329 assert(Inst.getOperand(2).isImm() &&
5330 "Offset for macro is not immediate!");
5331
5332 MCOperand &FirstOffset = Inst.getOperand(2);
5333 signed NextOffset = FirstOffset.getImm() + 4;
5334 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5335
5336 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5337 return true;
5338
5339 if (!IsLittleEndian)
5340 std::swap(FirstReg, SecondReg);
5341
5342 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5343 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5344
5345 return false;
5346}
5347
5348bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5349 const MCSubtargetInfo *STI) {
5350 MipsTargetStreamer &TOut = getTargetStreamer();
5351
5352 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5353 assert(Inst.getOperand(0).isReg() &&
5354 Inst.getOperand(1).isReg() &&
5355 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5356
5357 MCRegister DstReg = Inst.getOperand(0).getReg();
5358 MCRegister SrcReg = Inst.getOperand(1).getReg();
5359 MCRegister OpReg = Inst.getOperand(2).getReg();
5360
5361 warnIfNoMacro(IDLoc);
5362
5363 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5364 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5365 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5366 return false;
5367 }
5368
5369 MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5370 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5371 return false;
5372}
5373
5374bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5375 const MCSubtargetInfo *STI) {
5376 MipsTargetStreamer &TOut = getTargetStreamer();
5377
5378 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5379 assert(Inst.getOperand(0).isReg() &&
5380 Inst.getOperand(1).isReg() &&
5381 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5382
5383 MCRegister DstReg = Inst.getOperand(0).getReg();
5384 MCRegister SrcReg = Inst.getOperand(1).getReg();
5385 int64_t Imm = Inst.getOperand(2).getImm();
5386
5387 warnIfNoMacro(IDLoc);
5388
5389 if (Imm == 0) {
5390 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5391 return false;
5392 }
5393
5394 if (SrcReg == Mips::ZERO) {
5395 Warning(IDLoc, "comparison is always false");
5396 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5397 DstReg, SrcReg, SrcReg, IDLoc, STI);
5398 return false;
5399 }
5400
5401 unsigned Opc;
5402 if (Imm > -0x8000 && Imm < 0) {
5403 Imm = -Imm;
5404 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5405 } else {
5406 Opc = Mips::XORi;
5407 }
5408
5409 if (!isUInt<16>(Imm)) {
5410 MCRegister ATReg = getATReg(IDLoc);
5411 if (!ATReg)
5412 return true;
5413
5414 if (loadImmediate(Imm, ATReg, MCRegister(), true, isGP64bit(), IDLoc, Out,
5415 STI))
5416 return true;
5417
5418 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5419 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5420 return false;
5421 }
5422
5423 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5424 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5425 return false;
5426}
5427
5428bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5429 const MCSubtargetInfo *STI) {
5430
5431 MipsTargetStreamer &TOut = getTargetStreamer();
5432
5433 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5434 assert(Inst.getOperand(0).isReg() &&
5435 Inst.getOperand(1).isReg() &&
5436 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5437
5438 MCRegister DstReg = Inst.getOperand(0).getReg();
5439 MCRegister SrcReg = Inst.getOperand(1).getReg();
5440 MCRegister OpReg = Inst.getOperand(2).getReg();
5441
5442 warnIfNoMacro(IDLoc);
5443
5444 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5445 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5446 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5447 return false;
5448 }
5449
5450 MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5451 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5452 return false;
5453}
5454
5455bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5456 const MCSubtargetInfo *STI) {
5457 MipsTargetStreamer &TOut = getTargetStreamer();
5458
5459 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5460 assert(Inst.getOperand(0).isReg() &&
5461 Inst.getOperand(1).isReg() &&
5462 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5463
5464 MCRegister DstReg = Inst.getOperand(0).getReg();
5465 MCRegister SrcReg = Inst.getOperand(1).getReg();
5466 int64_t ImmValue = Inst.getOperand(2).getImm();
5467
5468 warnIfNoMacro(IDLoc);
5469
5470 if (ImmValue == 0) {
5471 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5472 return false;
5473 }
5474
5475 if (SrcReg == Mips::ZERO) {
5476 Warning(IDLoc, "comparison is always true");
5477 if (loadImmediate(1, DstReg, MCRegister(), true, false, IDLoc, Out, STI))
5478 return true;
5479 return false;
5480 }
5481
5482 unsigned Opc;
5483 if (ImmValue > -0x8000 && ImmValue < 0) {
5484 ImmValue = -ImmValue;
5485 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5486 } else {
5487 Opc = Mips::XORi;
5488 }
5489
5490 if (isUInt<16>(ImmValue)) {
5491 TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5492 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5493 return false;
5494 }
5495
5496 MCRegister ATReg = getATReg(IDLoc);
5497 if (!ATReg)
5498 return true;
5499
5500 if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue), false,
5501 IDLoc, Out, STI))
5502 return true;
5503
5504 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5505 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5506 return false;
5507}
5508
5509// Map the DSP accumulator and control register to the corresponding gpr
5510// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5511// do not map the DSP registers contigously to gpr registers.
5512static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5513 switch (Inst.getOpcode()) {
5514 case Mips::MFTLO:
5515 case Mips::MTTLO:
5516 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5517 case Mips::AC0:
5518 return Mips::ZERO;
5519 case Mips::AC1:
5520 return Mips::A0;
5521 case Mips::AC2:
5522 return Mips::T0;
5523 case Mips::AC3:
5524 return Mips::T4;
5525 default:
5526 llvm_unreachable("Unknown register for 'mttr' alias!");
5527 }
5528 case Mips::MFTHI:
5529 case Mips::MTTHI:
5530 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5531 case Mips::AC0:
5532 return Mips::AT;
5533 case Mips::AC1:
5534 return Mips::A1;
5535 case Mips::AC2:
5536 return Mips::T1;
5537 case Mips::AC3:
5538 return Mips::T5;
5539 default:
5540 llvm_unreachable("Unknown register for 'mttr' alias!");
5541 }
5542 case Mips::MFTACX:
5543 case Mips::MTTACX:
5544 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5545 case Mips::AC0:
5546 return Mips::V0;
5547 case Mips::AC1:
5548 return Mips::A2;
5549 case Mips::AC2:
5550 return Mips::T2;
5551 case Mips::AC3:
5552 return Mips::T6;
5553 default:
5554 llvm_unreachable("Unknown register for 'mttr' alias!");
5555 }
5556 case Mips::MFTDSP:
5557 case Mips::MTTDSP:
5558 return Mips::S0;
5559 default:
5560 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5561 }
5562}
5563
5564// Map the floating point register operand to the corresponding register
5565// operand.
5566static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5567 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg().id()) {
5568 case Mips::F0: return Mips::ZERO;
5569 case Mips::F1: return Mips::AT;
5570 case Mips::F2: return Mips::V0;
5571 case Mips::F3: return Mips::V1;
5572 case Mips::F4: return Mips::A0;
5573 case Mips::F5: return Mips::A1;
5574 case Mips::F6: return Mips::A2;
5575 case Mips::F7: return Mips::A3;
5576 case Mips::F8: return Mips::T0;
5577 case Mips::F9: return Mips::T1;
5578 case Mips::F10: return Mips::T2;
5579 case Mips::F11: return Mips::T3;
5580 case Mips::F12: return Mips::T4;
5581 case Mips::F13: return Mips::T5;
5582 case Mips::F14: return Mips::T6;
5583 case Mips::F15: return Mips::T7;
5584 case Mips::F16: return Mips::S0;
5585 case Mips::F17: return Mips::S1;
5586 case Mips::F18: return Mips::S2;
5587 case Mips::F19: return Mips::S3;
5588 case Mips::F20: return Mips::S4;
5589 case Mips::F21: return Mips::S5;
5590 case Mips::F22: return Mips::S6;
5591 case Mips::F23: return Mips::S7;
5592 case Mips::F24: return Mips::T8;
5593 case Mips::F25: return Mips::T9;
5594 case Mips::F26: return Mips::K0;
5595 case Mips::F27: return Mips::K1;
5596 case Mips::F28: return Mips::GP;
5597 case Mips::F29: return Mips::SP;
5598 case Mips::F30: return Mips::FP;
5599 case Mips::F31: return Mips::RA;
5600 default: llvm_unreachable("Unknown register for mttc1 alias!");
5601 }
5602}
5603
5604// Map the coprocessor operand the corresponding gpr register operand.
5605static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5606 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg().id()) {
5607 case Mips::COP00: return Mips::ZERO;
5608 case Mips::COP01: return Mips::AT;
5609 case Mips::COP02: return Mips::V0;
5610 case Mips::COP03: return Mips::V1;
5611 case Mips::COP04: return Mips::A0;
5612 case Mips::COP05: return Mips::A1;
5613 case Mips::COP06: return Mips::A2;
5614 case Mips::COP07: return Mips::A3;
5615 case Mips::COP08: return Mips::T0;
5616 case Mips::COP09: return Mips::T1;
5617 case Mips::COP010: return Mips::T2;
5618 case Mips::COP011: return Mips::T3;
5619 case Mips::COP012: return Mips::T4;
5620 case Mips::COP013: return Mips::T5;
5621 case Mips::COP014: return Mips::T6;
5622 case Mips::COP015: return Mips::T7;
5623 case Mips::COP016: return Mips::S0;
5624 case Mips::COP017: return Mips::S1;
5625 case Mips::COP018: return Mips::S2;
5626 case Mips::COP019: return Mips::S3;
5627 case Mips::COP020: return Mips::S4;
5628 case Mips::COP021: return Mips::S5;
5629 case Mips::COP022: return Mips::S6;
5630 case Mips::COP023: return Mips::S7;
5631 case Mips::COP024: return Mips::T8;
5632 case Mips::COP025: return Mips::T9;
5633 case Mips::COP026: return Mips::K0;
5634 case Mips::COP027: return Mips::K1;
5635 case Mips::COP028: return Mips::GP;
5636 case Mips::COP029: return Mips::SP;
5637 case Mips::COP030: return Mips::FP;
5638 case Mips::COP031: return Mips::RA;
5639 default: llvm_unreachable("Unknown register for mttc0 alias!");
5640 }
5641}
5642
5643/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5644/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5645bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5646 const MCSubtargetInfo *STI) {
5647 MipsTargetStreamer &TOut = getTargetStreamer();
5648 MCRegister rd;
5649 unsigned u = 1;
5650 unsigned sel = 0;
5651 unsigned h = 0;
5652 bool IsMFTR = false;
5653 switch (Inst.getOpcode()) {
5654 case Mips::MFTC0:
5655 IsMFTR = true;
5656 [[fallthrough]];
5657 case Mips::MTTC0:
5658 u = 0;
5659 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5660 sel = Inst.getOperand(2).getImm();
5661 break;
5662 case Mips::MFTGPR:
5663 IsMFTR = true;
5664 [[fallthrough]];
5665 case Mips::MTTGPR:
5666 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5667 break;
5668 case Mips::MFTLO:
5669 case Mips::MFTHI:
5670 case Mips::MFTACX:
5671 case Mips::MFTDSP:
5672 IsMFTR = true;
5673 [[fallthrough]];
5674 case Mips::MTTLO:
5675 case Mips::MTTHI:
5676 case Mips::MTTACX:
5677 case Mips::MTTDSP:
5678 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5679 sel = 1;
5680 break;
5681 case Mips::MFTHC1:
5682 h = 1;
5683 [[fallthrough]];
5684 case Mips::MFTC1:
5685 IsMFTR = true;
5686 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5687 sel = 2;
5688 break;
5689 case Mips::MTTHC1:
5690 h = 1;
5691 [[fallthrough]];
5692 case Mips::MTTC1:
5693 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5694 sel = 2;
5695 break;
5696 case Mips::CFTC1:
5697 IsMFTR = true;
5698 [[fallthrough]];
5699 case Mips::CTTC1:
5700 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5701 sel = 3;
5702 break;
5703 }
5704 MCRegister Op0 = IsMFTR ? Inst.getOperand(0).getReg() : MCRegister(rd);
5705 MCRegister Op1 =
5706 IsMFTR ? MCRegister(rd)
5707 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5708 : Inst.getOperand(0).getReg());
5709
5710 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5711 STI);
5712 return false;
5713}
5714
5715bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5716 const MCSubtargetInfo *STI) {
5717 assert(Inst.getNumOperands() == 3 && "expected three operands");
5718 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5719 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5720
5721 warnIfNoMacro(IDLoc);
5722
5723 MipsTargetStreamer &TOut = getTargetStreamer();
5724 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5725 MCRegister RtReg = Inst.getOperand(0).getReg();
5726 MCRegister BaseReg = Inst.getOperand(1).getReg();
5727 const MCOperand &BaseOp = Inst.getOperand(2);
5728
5729 if (BaseOp.isImm()) {
5730 int64_t ImmValue = BaseOp.getImm();
5731 if (ImmValue == 0) {
5732 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5733 return false;
5734 }
5735 }
5736
5737 MCRegister ATReg = getATReg(IDLoc);
5738 if (!ATReg)
5739 return true;
5740
5741 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5742 return true;
5743
5744 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5745 return false;
5746}
5747
5748unsigned
5749MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5750 const OperandVector &Operands) {
5751 switch (Inst.getOpcode()) {
5752 default:
5753 return Match_Success;
5754 case Mips::DATI:
5755 case Mips::DAHI:
5756 if (static_cast<MipsOperand &>(*Operands[1])
5757 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5758 return Match_Success;
5759 return Match_RequiresSameSrcAndDst;
5760 }
5761}
5762
5763unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5764 switch (Inst.getOpcode()) {
5765 // As described by the MIPSR6 spec, daui must not use the zero operand for
5766 // its source operand.
5767 case Mips::DAUI:
5768 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5769 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5770 return Match_RequiresNoZeroRegister;
5771 return Match_Success;
5772 // As described by the Mips32r2 spec, the registers Rd and Rs for
5773 // jalr.hb must be different.
5774 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5775 // and registers Rd and Base for microMIPS lwp instruction
5776 case Mips::JALR_HB:
5777 case Mips::JALR_HB64:
5778 case Mips::JALRC_HB_MMR6:
5779 case Mips::JALRC_MMR6:
5780 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5781 return Match_RequiresDifferentSrcAndDst;
5782 return Match_Success;
5783 case Mips::LWP_MM:
5784 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5785 return Match_RequiresDifferentSrcAndDst;
5786 return Match_Success;
5787 case Mips::SYNC:
5788 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5789 return Match_NonZeroOperandForSync;
5790 return Match_Success;
5791 case Mips::MFC0:
5792 case Mips::MTC0:
5793 case Mips::MTC2:
5794 case Mips::MFC2:
5795 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5796 return Match_NonZeroOperandForMTCX;
5797 return Match_Success;
5798 // As described the MIPSR6 spec, the compact branches that compare registers
5799 // must:
5800 // a) Not use the zero register.
5801 // b) Not use the same register twice.
5802 // c) rs < rt for bnec, beqc.
5803 // NB: For this case, the encoding will swap the operands as their
5804 // ordering doesn't matter. GAS performs this transformation too.
5805 // Hence, that constraint does not have to be enforced.
5806 //
5807 // The compact branches that branch iff the signed addition of two registers
5808 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5809 // operand swapping. They do not have restriction of using the zero register.
5810 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5811 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5812 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5813 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5814 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5815 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5816 case Mips::BLEZC64:
5817 case Mips::BGEZC64:
5818 case Mips::BGTZC64:
5819 case Mips::BLTZC64:
5820 case Mips::BEQZC64:
5821 case Mips::BNEZC64:
5822 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5823 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5824 return Match_RequiresNoZeroRegister;
5825 return Match_Success;
5826 case Mips::BGEC: case Mips::BGEC_MMR6:
5827 case Mips::BLTC: case Mips::BLTC_MMR6:
5828 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5829 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5830 case Mips::BEQC: case Mips::BEQC_MMR6:
5831 case Mips::BNEC: case Mips::BNEC_MMR6:
5832 case Mips::BGEC64:
5833 case Mips::BLTC64:
5834 case Mips::BGEUC64:
5835 case Mips::BLTUC64:
5836 case Mips::BEQC64:
5837 case Mips::BNEC64:
5838 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5839 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5840 return Match_RequiresNoZeroRegister;
5841 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5842 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5843 return Match_RequiresNoZeroRegister;
5844 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5845 return Match_RequiresDifferentOperands;
5846 return Match_Success;
5847 case Mips::DINS: {
5848 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5849 "Operands must be immediates for dins!");
5850 const signed Pos = Inst.getOperand(2).getImm();
5851 const signed Size = Inst.getOperand(3).getImm();
5852 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5853 return Match_RequiresPosSizeRange0_32;
5854 return Match_Success;
5855 }
5856 case Mips::DINSM:
5857 case Mips::DINSU: {
5858 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5859 "Operands must be immediates for dinsm/dinsu!");
5860 const signed Pos = Inst.getOperand(2).getImm();
5861 const signed Size = Inst.getOperand(3).getImm();
5862 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5863 return Match_RequiresPosSizeRange33_64;
5864 return Match_Success;
5865 }
5866 case Mips::DEXT: {
5867 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5868 "Operands must be immediates for DEXTM!");
5869 const signed Pos = Inst.getOperand(2).getImm();
5870 const signed Size = Inst.getOperand(3).getImm();
5871 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5872 return Match_RequiresPosSizeUImm6;
5873 return Match_Success;
5874 }
5875 case Mips::DEXTM:
5876 case Mips::DEXTU: {
5877 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5878 "Operands must be immediates for dextm/dextu!");
5879 const signed Pos = Inst.getOperand(2).getImm();
5880 const signed Size = Inst.getOperand(3).getImm();
5881 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5882 return Match_RequiresPosSizeRange33_64;
5883 return Match_Success;
5884 }
5885 case Mips::CRC32B: case Mips::CRC32CB:
5886 case Mips::CRC32H: case Mips::CRC32CH:
5887 case Mips::CRC32W: case Mips::CRC32CW:
5888 case Mips::CRC32D: case Mips::CRC32CD:
5889 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5890 return Match_RequiresSameSrcAndDst;
5891 return Match_Success;
5892 }
5893
5894 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5895 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5896 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5897 return Match_NoFCCRegisterForCurrentISA;
5898
5899 return Match_Success;
5900
5901}
5902
5905 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5906 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5907 if (ErrorLoc == SMLoc())
5908 return Loc;
5909 return ErrorLoc;
5910 }
5911 return Loc;
5912}
5913
5914bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5916 MCStreamer &Out,
5917 uint64_t &ErrorInfo,
5918 bool MatchingInlineAsm) {
5919 MCInst Inst;
5920 unsigned MatchResult =
5921 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5922
5923 switch (MatchResult) {
5924 case Match_Success:
5925 if (processInstruction(Inst, IDLoc, Out, STI))
5926 return true;
5927 return false;
5928 case Match_MissingFeature:
5929 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5930 return true;
5931 case Match_InvalidTiedOperand:
5932 Error(IDLoc, "operand must match destination register");
5933 return true;
5934 case Match_InvalidOperand: {
5935 SMLoc ErrorLoc = IDLoc;
5936 if (ErrorInfo != ~0ULL) {
5937 if (ErrorInfo >= Operands.size())
5938 return Error(IDLoc, "too few operands for instruction");
5939
5940 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5941 if (ErrorLoc == SMLoc())
5942 ErrorLoc = IDLoc;
5943 }
5944
5945 return Error(ErrorLoc, "invalid operand for instruction");
5946 }
5947 case Match_NonZeroOperandForSync:
5948 return Error(IDLoc,
5949 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5950 case Match_NonZeroOperandForMTCX:
5951 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5952 case Match_MnemonicFail:
5953 return Error(IDLoc, "invalid instruction");
5954 case Match_RequiresDifferentSrcAndDst:
5955 return Error(IDLoc, "source and destination must be different");
5956 case Match_RequiresDifferentOperands:
5957 return Error(IDLoc, "registers must be different");
5958 case Match_RequiresNoZeroRegister:
5959 return Error(IDLoc, "invalid operand ($zero) for instruction");
5960 case Match_RequiresSameSrcAndDst:
5961 return Error(IDLoc, "source and destination must match");
5962 case Match_NoFCCRegisterForCurrentISA:
5963 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5964 "non-zero fcc register doesn't exist in current ISA level");
5965 case Match_Immz:
5966 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5967 case Match_UImm1_0:
5968 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5969 "expected 1-bit unsigned immediate");
5970 case Match_UImm2_0:
5971 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5972 "expected 2-bit unsigned immediate");
5973 case Match_UImm2_1:
5974 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5975 "expected immediate in range 1 .. 4");
5976 case Match_UImm3_0:
5977 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5978 "expected 3-bit unsigned immediate");
5979 case Match_UImm4_0:
5980 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5981 "expected 4-bit unsigned immediate");
5982 case Match_SImm4_0:
5983 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5984 "expected 4-bit signed immediate");
5985 case Match_UImm5_0:
5986 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5987 "expected 5-bit unsigned immediate");
5988 case Match_SImm5_0:
5989 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5990 "expected 5-bit signed immediate");
5991 case Match_UImm5_1:
5992 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5993 "expected immediate in range 1 .. 32");
5994 case Match_UImm5_32:
5995 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5996 "expected immediate in range 32 .. 63");
5997 case Match_UImm5_33:
5998 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5999 "expected immediate in range 33 .. 64");
6000 case Match_UImm5_0_Report_UImm6:
6001 // This is used on UImm5 operands that have a corresponding UImm5_32
6002 // operand to avoid confusing the user.
6003 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6004 "expected 6-bit unsigned immediate");
6005 case Match_UImm5_Lsl2:
6006 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6007 "expected both 7-bit unsigned immediate and multiple of 4");
6008 case Match_UImmRange2_64:
6009 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6010 "expected immediate in range 2 .. 64");
6011 case Match_UImm6_0:
6012 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6013 "expected 6-bit unsigned immediate");
6014 case Match_UImm6_Lsl2:
6015 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6016 "expected both 8-bit unsigned immediate and multiple of 4");
6017 case Match_SImm6_0:
6018 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6019 "expected 6-bit signed immediate");
6020 case Match_UImm7_0:
6021 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6022 "expected 7-bit unsigned immediate");
6023 case Match_UImm7_N1:
6024 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6025 "expected immediate in range -1 .. 126");
6026 case Match_SImm7_Lsl2:
6027 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6028 "expected both 9-bit signed immediate and multiple of 4");
6029 case Match_UImm8_0:
6030 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6031 "expected 8-bit unsigned immediate");
6032 case Match_UImm10_0:
6033 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6034 "expected 10-bit unsigned immediate");
6035 case Match_SImm10_0:
6036 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6037 "expected 10-bit signed immediate");
6038 case Match_SImm11_0:
6039 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6040 "expected 11-bit signed immediate");
6041 case Match_UImm16:
6042 case Match_UImm16_Relaxed:
6043 case Match_UImm16_AltRelaxed:
6044 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6045 "expected 16-bit unsigned immediate");
6046 case Match_SImm16:
6047 case Match_SImm16_Relaxed:
6048 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6049 "expected 16-bit signed immediate");
6050 case Match_SImm18_Lsl3:
6051 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6052 "expected both 18-bit signed immediate and multiple of 8");
6053 case Match_SImm19_Lsl2:
6054 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6055 "expected both 19-bit signed immediate and multiple of 4");
6056 case Match_UImm20_0:
6057 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6058 "expected 20-bit unsigned immediate");
6059 case Match_UImm26_0:
6060 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6061 "expected 26-bit unsigned immediate");
6062 case Match_SImm32:
6063 case Match_SImm32_Relaxed:
6064 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6065 "expected 32-bit signed immediate");
6066 case Match_UImm32_Coerced:
6067 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6068 "expected 32-bit immediate");
6069 case Match_MemSImm9:
6070 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6071 "expected memory with 9-bit signed offset");
6072 case Match_MemSImm10:
6073 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6074 "expected memory with 10-bit signed offset");
6075 case Match_MemSImm10Lsl1:
6076 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6077 "expected memory with 11-bit signed offset and multiple of 2");
6078 case Match_MemSImm10Lsl2:
6079 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6080 "expected memory with 12-bit signed offset and multiple of 4");
6081 case Match_MemSImm10Lsl3:
6082 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6083 "expected memory with 13-bit signed offset and multiple of 8");
6084 case Match_MemSImm11:
6085 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6086 "expected memory with 11-bit signed offset");
6087 case Match_MemSImm12:
6088 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6089 "expected memory with 12-bit signed offset");
6090 case Match_MemSImm16:
6091 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6092 "expected memory with 16-bit signed offset");
6093 case Match_MemSImmPtr:
6094 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6095 "expected memory with 32-bit signed offset");
6096 case Match_RequiresPosSizeRange0_32: {
6097 SMLoc ErrorStart = Operands[3]->getStartLoc();
6098 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6099 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6100 SMRange(ErrorStart, ErrorEnd));
6101 }
6102 case Match_RequiresPosSizeUImm6: {
6103 SMLoc ErrorStart = Operands[3]->getStartLoc();
6104 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6105 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6106 SMRange(ErrorStart, ErrorEnd));
6107 }
6108 case Match_RequiresPosSizeRange33_64: {
6109 SMLoc ErrorStart = Operands[3]->getStartLoc();
6110 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6111 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6112 SMRange(ErrorStart, ErrorEnd));
6113 }
6114 }
6115
6116 llvm_unreachable("Implement any new match types added!");
6117}
6118
6119void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6120 if (RegIndex && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6121 Warning(Loc, "used $at (currently $" + Twine(RegIndex.id()) +
6122 ") without \".set noat\"");
6123}
6124
6125void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6126 if (!AssemblerOptions.back()->isMacro())
6127 Warning(Loc, "macro instruction expanded into multiple instructions");
6128}
6129
6130void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6131 const OperandVector &Operands) {
6132 assert(
6133 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
6134 "Unexpected instruction!");
6135 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6136 MCRegister NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6137 Inst.addOperand(MCOperand::createReg(NextReg));
6138 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6139}
6140
6141void
6142MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6143 SMRange Range, bool ShowColors) {
6144 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6145 Range, SMFixIt(Range, FixMsg),
6146 ShowColors);
6147}
6148
6149int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6150 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
6151 bool IsDeprecated;
6152 int Index = MIPS_MC::getCPURegisterIndex(Name, MRI, ABI.getRegAltNameIndex(),
6153 &IsDeprecated);
6154 if (IsDeprecated) {
6155 MCRegister Reg = MRI.getRegClass(Mips::GPR32RegClassID).getRegister(Index);
6156 AsmToken RegTok = getLexer().peekTok();
6157 StringRef FixedName =
6158 MipsInstPrinter::getRegisterName(Reg, ABI.getRegAltNameIndex());
6159 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6160 "Did you mean $" + FixedName + "?",
6161 RegTok.getLocRange());
6162 }
6163 return Index;
6164}
6165
6166int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6167 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
6168 MCRegister Reg = MIPS_MC::matchRegisterName(Name, MRI, Mips::HWRegsRegClassID,
6169 Mips::RegAliasName);
6170 return Reg ? MRI.getEncodingValue(Reg) : -1;
6171}
6172
6173int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6174 if (Name[0] == 'f') {
6175 StringRef NumString = Name.substr(1);
6176 unsigned IntVal;
6177 if (NumString.getAsInteger(10, IntVal))
6178 return -1; // This is not an integer.
6179 if (IntVal > 31) // Maximum index for fpu register.
6180 return -1;
6181 return IntVal;
6182 }
6183 return -1;
6184}
6185
6186int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6187 if (Name.starts_with("fcc")) {
6188 StringRef NumString = Name.substr(3);
6189 unsigned IntVal;
6190 if (NumString.getAsInteger(10, IntVal))
6191 return -1; // This is not an integer.
6192 if (IntVal > 7) // There are only 8 fcc registers.
6193 return -1;
6194 return IntVal;
6195 }
6196 return -1;
6197}
6198
6199int MipsAsmParser::matchACRegisterName(StringRef Name) {
6200 if (Name.starts_with("ac")) {
6201 StringRef NumString = Name.substr(2);
6202 unsigned IntVal;
6203 if (NumString.getAsInteger(10, IntVal))
6204 return -1; // This is not an integer.
6205 if (IntVal > 3) // There are only 3 acc registers.
6206 return -1;
6207 return IntVal;
6208 }
6209 return -1;
6210}
6211
6212int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6213 unsigned IntVal;
6214
6215 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6216 return -1;
6217
6218 if (IntVal > 31)
6219 return -1;
6220
6221 return IntVal;
6222}
6223
6224int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6225 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
6226 MCRegister Reg = MIPS_MC::matchRegisterName(
6227 Name, MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6228 return Reg ? MRI.getEncodingValue(Reg) : -1;
6229}
6230
6231bool MipsAsmParser::canUseATReg() {
6232 return AssemblerOptions.back()->getATRegIndex() != 0;
6233}
6234
6235MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6236 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6237 if (ATIndex == 0) {
6238 reportParseError(Loc,
6239 "pseudo-instruction requires $at, which is not available");
6240 return 0;
6241 }
6242 MCRegister AT = getReg(
6243 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6244 return AT;
6245}
6246
6247MCRegister MipsAsmParser::getReg(int RC, int RegNo) {
6248 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6249}
6250
6251// Parse an expression with optional relocation operator prefixes (e.g. %lo).
6252// Some weird expressions allowed by gas are not supported for simplicity,
6253// e.g. "%lo foo", "(%lo(foo))", "%lo(foo)+1".
6254const MCExpr *MipsAsmParser::parseRelocExpr() {
6255 auto getOp = [](StringRef Op) {
6256 return StringSwitch<Mips::Specifier>(Op)
6257 .Case("call16", Mips::S_GOT_CALL)
6258 .Case("call_hi", Mips::S_CALL_HI16)
6259 .Case("call_lo", Mips::S_CALL_LO16)
6260 .Case("dtprel_hi", Mips::S_DTPREL_HI)
6261 .Case("dtprel_lo", Mips::S_DTPREL_LO)
6262 .Case("got", Mips::S_GOT)
6263 .Case("got_disp", Mips::S_GOT_DISP)
6264 .Case("got_hi", Mips::S_GOT_HI16)
6265 .Case("got_lo", Mips::S_GOT_LO16)
6266 .Case("got_ofst", Mips::S_GOT_OFST)
6267 .Case("got_page", Mips::S_GOT_PAGE)
6268 .Case("gottprel", Mips::S_GOTTPREL)
6269 .Case("gp_rel", Mips::S_GPREL)
6270 .Case("hi", Mips::S_HI)
6271 .Case("higher", Mips::S_HIGHER)
6272 .Case("highest", Mips::S_HIGHEST)
6273 .Case("lo", Mips::S_LO)
6274 .Case("neg", Mips::S_NEG)
6275 .Case("pcrel_hi", Mips::S_PCREL_HI16)
6276 .Case("pcrel_lo", Mips::S_PCREL_LO16)
6277 .Case("tlsgd", Mips::S_TLSGD)
6278 .Case("tlsldm", Mips::S_TLSLDM)
6279 .Case("tprel_hi", Mips::S_TPREL_HI)
6280 .Case("tprel_lo", Mips::S_TPREL_LO)
6281 .Default(Mips::S_None);
6282 };
6283
6284 MCAsmParser &Parser = getParser();
6285 StringRef Name;
6286 const MCExpr *Res = nullptr;
6288 while (parseOptionalToken(AsmToken::Percent)) {
6289 if (Parser.parseIdentifier(Name) ||
6290 Parser.parseToken(AsmToken::LParen, "expected '('"))
6291 return nullptr;
6292 auto Op = getOp(Name);
6293 if (Op == Mips::S_None) {
6294 Error(Parser.getTok().getLoc(), "invalid relocation operator");
6295 return nullptr;
6296 }
6297 Ops.push_back(Op);
6298 }
6299 if (Parser.parseExpression(Res))
6300 return nullptr;
6301 while (Ops.size()) {
6302 if (Parser.parseToken(AsmToken::RParen, "expected ')'"))
6303 return nullptr;
6304 Res = MCSpecifierExpr::create(Res, Ops.pop_back_val(), getContext());
6305 }
6306 return Res;
6307}
6308
6309bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6310 MCAsmParser &Parser = getParser();
6311 LLVM_DEBUG(dbgs() << "parseOperand\n");
6312
6313 // Check if the current operand has a custom associated parser, if so, try to
6314 // custom parse the operand, or fallback to the general approach.
6315 // Setting the third parameter to true tells the parser to keep parsing even
6316 // if the operands are not supported with the current feature set. In this
6317 // case, the instruction matcher will output a "instruction requires a CPU
6318 // feature not currently enabled" error. If this were false, the parser would
6319 // stop here and output a less useful "invalid operand" error.
6320 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic, true);
6321 if (Res.isSuccess())
6322 return false;
6323 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6324 // there was a match, but an error occurred, in which case, just return that
6325 // the operand parsing failed.
6326 if (Res.isFailure())
6327 return true;
6328
6329 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6330
6331 switch (getLexer().getKind()) {
6332 case AsmToken::Dollar: {
6333 // Parse the register.
6334 SMLoc S = Parser.getTok().getLoc();
6335
6336 // Almost all registers have been parsed by custom parsers. There is only
6337 // one exception to this. $zero (and it's alias $0) will reach this point
6338 // for div, divu, and similar instructions because it is not an operand
6339 // to the instruction definition but an explicit register. Special case
6340 // this situation for now.
6341 if (!parseAnyRegister(Operands).isNoMatch())
6342 return false;
6343
6344 // Maybe it is a symbol reference.
6345 StringRef Identifier;
6346 if (Parser.parseIdentifier(Identifier))
6347 return true;
6348
6349 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6350 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
6351 // Otherwise create a symbol reference.
6352 const MCExpr *SymRef = MCSymbolRefExpr::create(Sym, getContext());
6353
6354 Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this));
6355 return false;
6356 }
6357 default: {
6358 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6359 const MCExpr *Expr = parseRelocExpr();
6360 if (!Expr)
6361 return true;
6362 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6363 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6364 return false;
6365 }
6366 } // switch(getLexer().getKind())
6367 return true;
6368}
6369
6370bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
6371 SMLoc &EndLoc) {
6372 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6373}
6374
6375ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6376 SMLoc &EndLoc) {
6378 ParseStatus Res = parseAnyRegister(Operands);
6379 if (Res.isSuccess()) {
6380 assert(Operands.size() == 1);
6381 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6382 StartLoc = Operand.getStartLoc();
6383 EndLoc = Operand.getEndLoc();
6384
6385 // AFAIK, we only support numeric registers and named GPR's in CFI
6386 // directives.
6387 // Don't worry about eating tokens before failing. Using an unrecognised
6388 // register is a parse error.
6389 if (Operand.isGPRAsmReg()) {
6390 // Resolve to GPR32 or GPR64 appropriately.
6391 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6392 }
6393
6394 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6395 }
6396
6397 assert(Operands.size() == 0);
6398 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6399}
6400
6401ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6402 MCAsmParser &Parser = getParser();
6403 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6404 const MCExpr *IdVal = nullptr;
6405 SMLoc S;
6406 bool isParenExpr = false;
6407 ParseStatus Res = ParseStatus::NoMatch;
6408 // First operand is the offset.
6409 S = Parser.getTok().getLoc();
6410
6411 if (getLexer().getKind() == AsmToken::LParen) {
6412 Parser.Lex();
6413 isParenExpr = true;
6414 }
6415
6416 if (getLexer().getKind() != AsmToken::Dollar) {
6417 IdVal = parseRelocExpr();
6418 if (!IdVal)
6419 return ParseStatus::Failure;
6420 if (isParenExpr && Parser.parseRParen())
6421 return ParseStatus::Failure;
6422
6423 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6424 if (Tok.isNot(AsmToken::LParen)) {
6425 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6426 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6427 SMLoc E =
6429 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6430 return ParseStatus::Success;
6431 }
6432 if (Tok.is(AsmToken::EndOfStatement)) {
6433 SMLoc E =
6435
6436 // Zero register assumed, add a memory operand with ZERO as its base.
6437 // "Base" will be managed by k_Memory.
6438 auto Base = MipsOperand::createGPRReg(
6439 0, "0", getContext().getRegisterInfo(), S, E, *this);
6440 Operands.push_back(
6441 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6442 return ParseStatus::Success;
6443 }
6444 MCBinaryExpr::Opcode Opcode;
6445 // GAS and LLVM treat comparison operators different. GAS will generate -1
6446 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6447 // highly unlikely to be found in a memory offset expression, we don't
6448 // handle them.
6449 switch (Tok.getKind()) {
6450 case AsmToken::Plus:
6451 Opcode = MCBinaryExpr::Add;
6452 Parser.Lex();
6453 break;
6454 case AsmToken::Minus:
6455 Opcode = MCBinaryExpr::Sub;
6456 Parser.Lex();
6457 break;
6458 case AsmToken::Star:
6459 Opcode = MCBinaryExpr::Mul;
6460 Parser.Lex();
6461 break;
6462 case AsmToken::Pipe:
6463 Opcode = MCBinaryExpr::Or;
6464 Parser.Lex();
6465 break;
6466 case AsmToken::Amp:
6467 Opcode = MCBinaryExpr::And;
6468 Parser.Lex();
6469 break;
6470 case AsmToken::LessLess:
6471 Opcode = MCBinaryExpr::Shl;
6472 Parser.Lex();
6473 break;
6475 Opcode = MCBinaryExpr::LShr;
6476 Parser.Lex();
6477 break;
6478 case AsmToken::Caret:
6479 Opcode = MCBinaryExpr::Xor;
6480 Parser.Lex();
6481 break;
6482 case AsmToken::Slash:
6483 Opcode = MCBinaryExpr::Div;
6484 Parser.Lex();
6485 break;
6486 case AsmToken::Percent:
6487 Opcode = MCBinaryExpr::Mod;
6488 Parser.Lex();
6489 break;
6490 default:
6491 return Error(Parser.getTok().getLoc(), "'(' or expression expected");
6492 }
6493 const MCExpr * NextExpr;
6494 if (getParser().parseExpression(NextExpr))
6495 return ParseStatus::Failure;
6496 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6497 }
6498
6499 Parser.Lex(); // Eat the '(' token.
6500 }
6501
6502 Res = parseAnyRegister(Operands);
6503 if (!Res.isSuccess())
6504 return Res;
6505
6506 if (Parser.getTok().isNot(AsmToken::RParen))
6507 return Error(Parser.getTok().getLoc(), "')' expected");
6508
6509 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6510
6511 Parser.Lex(); // Eat the ')' token.
6512
6513 if (!IdVal)
6514 IdVal = MCConstantExpr::create(0, getContext());
6515
6516 // Replace the register operand with the memory operand.
6517 std::unique_ptr<MipsOperand> op(
6518 static_cast<MipsOperand *>(Operands.back().release()));
6519 // Remove the register from the operands.
6520 // "op" will be managed by k_Memory.
6521 Operands.pop_back();
6522 // Add the memory operand.
6523 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6524 int64_t Imm;
6525 if (IdVal->evaluateAsAbsolute(Imm))
6527 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6528 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6529 getContext());
6530 }
6531
6532 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6533 return ParseStatus::Success;
6534}
6535
6536bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6537 MCAsmParser &Parser = getParser();
6538 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6539 if (!Sym)
6540 return false;
6541
6542 SMLoc S = Parser.getTok().getLoc();
6543 if (Sym->isVariable()) {
6544 const MCExpr *Expr = Sym->getVariableValue();
6545 if (Expr->getKind() == MCExpr::SymbolRef) {
6546 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6547 StringRef DefSymbol = Ref->getSymbol().getName();
6548 if (DefSymbol.starts_with("$")) {
6549 ParseStatus Res =
6550 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6551 if (Res.isSuccess()) {
6552 Parser.Lex();
6553 return true;
6554 }
6555 if (Res.isFailure())
6556 llvm_unreachable("Should never fail");
6557 }
6558 }
6559 } else if (Sym->isUndefined()) {
6560 // If symbol is unset, it might be created in the `parseSetAssignment`
6561 // routine as an alias for a numeric register name.
6562 // Lookup in the aliases list.
6563 auto Entry = RegisterSets.find(Sym->getName());
6564 if (Entry != RegisterSets.end()) {
6565 ParseStatus Res =
6566 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6567 if (Res.isSuccess()) {
6568 Parser.Lex();
6569 return true;
6570 }
6571 }
6572 }
6573
6574 return false;
6575}
6576
6577ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6578 OperandVector &Operands, StringRef Identifier, SMLoc S) {
6579 int Index = matchCPURegisterName(Identifier);
6580 if (Index != -1) {
6581 Operands.push_back(MipsOperand::createGPRReg(
6582 Index, Identifier, getContext().getRegisterInfo(), S,
6583 getLexer().getLoc(), *this));
6584 return ParseStatus::Success;
6585 }
6586
6587 Index = matchHWRegsRegisterName(Identifier);
6588 if (Index != -1) {
6589 Operands.push_back(MipsOperand::createHWRegsReg(
6590 Index, Identifier, getContext().getRegisterInfo(), S,
6591 getLexer().getLoc(), *this));
6592 return ParseStatus::Success;
6593 }
6594
6595 Index = matchFPURegisterName(Identifier);
6596 if (Index != -1) {
6597 Operands.push_back(MipsOperand::createFGRReg(
6598 Index, Identifier, getContext().getRegisterInfo(), S,
6599 getLexer().getLoc(), *this));
6600 return ParseStatus::Success;
6601 }
6602
6603 Index = matchFCCRegisterName(Identifier);
6604 if (Index != -1) {
6605 Operands.push_back(MipsOperand::createFCCReg(
6606 Index, Identifier, getContext().getRegisterInfo(), S,
6607 getLexer().getLoc(), *this));
6608 return ParseStatus::Success;
6609 }
6610
6611 Index = matchACRegisterName(Identifier);
6612 if (Index != -1) {
6613 Operands.push_back(MipsOperand::createACCReg(
6614 Index, Identifier, getContext().getRegisterInfo(), S,
6615 getLexer().getLoc(), *this));
6616 return ParseStatus::Success;
6617 }
6618
6619 Index = matchMSA128RegisterName(Identifier);
6620 if (Index != -1) {
6621 Operands.push_back(MipsOperand::createMSA128Reg(
6622 Index, Identifier, getContext().getRegisterInfo(), S,
6623 getLexer().getLoc(), *this));
6624 return ParseStatus::Success;
6625 }
6626
6627 Index = matchMSA128CtrlRegisterName(Identifier);
6628 if (Index != -1) {
6629 Operands.push_back(MipsOperand::createMSACtrlReg(
6630 Index, Identifier, getContext().getRegisterInfo(), S,
6631 getLexer().getLoc(), *this));
6632 return ParseStatus::Success;
6633 }
6634
6635 return ParseStatus::NoMatch;
6636}
6637
6638ParseStatus
6639MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6640 const AsmToken &Token, SMLoc S) {
6641 if (Token.is(AsmToken::Identifier)) {
6642 LLVM_DEBUG(dbgs() << ".. identifier\n");
6643 StringRef Identifier = Token.getIdentifier();
6644 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6645 }
6646 if (Token.is(AsmToken::Integer)) {
6647 LLVM_DEBUG(dbgs() << ".. integer\n");
6648 int64_t RegNum = Token.getIntVal();
6649 if (RegNum < 0 || RegNum > 31) {
6650 // Show the error, but treat invalid register
6651 // number as a normal one to continue parsing
6652 // and catch other possible errors.
6653 Error(getLexer().getLoc(), "invalid register number");
6654 }
6655 Operands.push_back(MipsOperand::createNumericReg(
6656 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6657 Token.getLoc(), *this));
6658 return ParseStatus::Success;
6659 }
6660
6661 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6662
6663 return ParseStatus::NoMatch;
6664}
6665
6666ParseStatus
6667MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6668 auto Token = getLexer().peekTok(false);
6669 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6670}
6671
6672ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6673 MCAsmParser &Parser = getParser();
6674 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6675
6676 auto Token = Parser.getTok();
6677
6678 SMLoc S = Token.getLoc();
6679
6680 if (Token.isNot(AsmToken::Dollar)) {
6681 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6682 if (Token.is(AsmToken::Identifier)) {
6683 if (searchSymbolAlias(Operands))
6684 return ParseStatus::Success;
6685 }
6686 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6687 return ParseStatus::NoMatch;
6688 }
6689 LLVM_DEBUG(dbgs() << ".. $\n");
6690
6691 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6692 if (Res.isSuccess()) {
6693 Parser.Lex(); // $
6694 Parser.Lex(); // identifier
6695 }
6696 return Res;
6697}
6698
6699ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6700 MCAsmParser &Parser = getParser();
6701 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6702
6703 SMLoc S = getLexer().getLoc();
6704
6705 // Registers are a valid target and have priority over symbols.
6706 ParseStatus Res = parseAnyRegister(Operands);
6707 if (!Res.isNoMatch())
6708 return Res;
6709
6710 // Integers and expressions are acceptable
6711 const MCExpr *Expr = nullptr;
6712 if (Parser.parseExpression(Expr)) {
6713 // We have no way of knowing if a symbol was consumed so we must ParseFail
6714 return ParseStatus::Failure;
6715 }
6716 Operands.push_back(
6717 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6718 return ParseStatus::Success;
6719}
6720
6721ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) {
6722 MCAsmParser &Parser = getParser();
6723 const MCExpr *IdVal;
6724 // If the first token is '$' we may have register operand. We have to reject
6725 // cases where it is not a register. Complicating the matter is that
6726 // register names are not reserved across all ABIs.
6727 // Peek past the dollar to see if it's a register name for this ABI.
6728 SMLoc S = Parser.getTok().getLoc();
6729 if (Parser.getTok().is(AsmToken::Dollar)) {
6730 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6733 }
6734 if (getParser().parseExpression(IdVal))
6735 return ParseStatus::Failure;
6736 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6737 if (!MCE)
6738 return ParseStatus::NoMatch;
6739 int64_t Val = MCE->getValue();
6740 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6741 Operands.push_back(MipsOperand::CreateImm(
6742 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6743 return ParseStatus::Success;
6744}
6745
6746ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6747 MCAsmParser &Parser = getParser();
6749 MCRegister Reg;
6750 MCRegister PrevReg;
6751 bool RegRange = false;
6753
6754 if (Parser.getTok().isNot(AsmToken::Dollar))
6755 return ParseStatus::Failure;
6756
6757 SMLoc S = Parser.getTok().getLoc();
6758 while (parseAnyRegister(TmpOperands).isSuccess()) {
6759 SMLoc E = getLexer().getLoc();
6760 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*TmpOperands.back());
6761 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6762 if (RegRange) {
6763 // Remove last register operand because registers from register range
6764 // should be inserted first.
6765 if ((isGP64bit() && Reg == Mips::RA_64) ||
6766 (!isGP64bit() && Reg == Mips::RA)) {
6767 Regs.push_back(Reg);
6768 } else {
6769 MCRegister TmpReg = PrevReg + 1;
6770 while (TmpReg <= Reg) {
6771 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6772 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6773 isGP64bit()))
6774 return Error(E, "invalid register operand");
6775
6776 PrevReg = TmpReg;
6777 Regs.push_back(TmpReg);
6778 TmpReg = TmpReg.id() + 1;
6779 }
6780 }
6781
6782 RegRange = false;
6783 } else {
6784 if (!PrevReg.isValid() &&
6785 ((isGP64bit() && (Reg != Mips::S0_64) && (Reg != Mips::RA_64)) ||
6786 (!isGP64bit() && (Reg != Mips::S0) && (Reg != Mips::RA))))
6787 return Error(E, "$16 or $31 expected");
6788 if (!(((Reg == Mips::FP || Reg == Mips::RA ||
6789 (Reg >= Mips::S0 && Reg <= Mips::S7)) &&
6790 !isGP64bit()) ||
6791 ((Reg == Mips::FP_64 || Reg == Mips::RA_64 ||
6792 (Reg >= Mips::S0_64 && Reg <= Mips::S7_64)) &&
6793 isGP64bit())))
6794 return Error(E, "invalid register operand");
6795 if (PrevReg.isValid() && (Reg != PrevReg + 1) &&
6796 ((Reg != Mips::FP && Reg != Mips::RA && !isGP64bit()) ||
6797 (Reg != Mips::FP_64 && Reg != Mips::RA_64 && isGP64bit())))
6798 return Error(E, "consecutive register numbers expected");
6799
6800 Regs.push_back(Reg);
6801 }
6802
6803 if (Parser.getTok().is(AsmToken::Minus))
6804 RegRange = true;
6805
6806 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6807 !Parser.getTok().isNot(AsmToken::Comma))
6808 return Error(E, "',' or '-' expected");
6809
6810 Lex(); // Consume comma or minus
6811 if (Parser.getTok().isNot(AsmToken::Dollar))
6812 break;
6813
6814 PrevReg = Reg;
6815 }
6816
6817 SMLoc E = Parser.getTok().getLoc();
6818 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6819 parseMemOperand(Operands);
6820 return ParseStatus::Success;
6821}
6822
6823/// Sometimes (i.e. load/stores) the operand may be followed immediately by
6824/// either this.
6825/// ::= '(', register, ')'
6826/// handle it before we iterate so we don't get tripped up by the lack of
6827/// a comma.
6828bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6829 MCAsmParser &Parser = getParser();
6830 if (getLexer().is(AsmToken::LParen)) {
6831 Operands.push_back(
6832 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6833 Parser.Lex();
6834 if (parseOperand(Operands, Name)) {
6835 SMLoc Loc = getLexer().getLoc();
6836 return Error(Loc, "unexpected token in argument list");
6837 }
6838 if (Parser.getTok().isNot(AsmToken::RParen)) {
6839 SMLoc Loc = getLexer().getLoc();
6840 return Error(Loc, "unexpected token, expected ')'");
6841 }
6842 Operands.push_back(
6843 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6844 Parser.Lex();
6845 }
6846 return false;
6847}
6848
6849/// Sometimes (i.e. in MSA) the operand may be followed immediately by
6850/// either one of these.
6851/// ::= '[', register, ']'
6852/// ::= '[', integer, ']'
6853/// handle it before we iterate so we don't get tripped up by the lack of
6854/// a comma.
6855bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6857 MCAsmParser &Parser = getParser();
6858 if (getLexer().is(AsmToken::LBrac)) {
6859 Operands.push_back(
6860 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6861 Parser.Lex();
6862 if (parseOperand(Operands, Name)) {
6863 SMLoc Loc = getLexer().getLoc();
6864 return Error(Loc, "unexpected token in argument list");
6865 }
6866 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6867 SMLoc Loc = getLexer().getLoc();
6868 return Error(Loc, "unexpected token, expected ']'");
6869 }
6870 Operands.push_back(
6871 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6872 Parser.Lex();
6873 }
6874 return false;
6875}
6876
6877static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6878 unsigned VariantID = 0);
6879
6880bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6881 const MCParsedAsmOperand &Op2) const {
6882 // This target-overriden function exists to maintain current behaviour for
6883 // e.g.
6884 // dahi $3, $3, 0x5678
6885 // as tested in test/MC/Mips/mips64r6/valid.s.
6886 // FIXME: Should this test actually fail with an error? If so, then remove
6887 // this overloaded method.
6888 if (!Op1.isReg() || !Op2.isReg())
6889 return true;
6890 return Op1.getReg() == Op2.getReg();
6891}
6892
6893bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6894 SMLoc NameLoc, OperandVector &Operands) {
6895 MCAsmParser &Parser = getParser();
6896 LLVM_DEBUG(dbgs() << "parseInstruction\n");
6897
6898 // We have reached first instruction, module directive are now forbidden.
6899 getTargetStreamer().forbidModuleDirective();
6900
6901 // Check if we have valid mnemonic
6902 if (!mnemonicIsValid(Name, 0)) {
6903 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6904 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6905 return Error(NameLoc, "unknown instruction" + Suggestion);
6906 }
6907 // First operand in MCInst is instruction mnemonic.
6908 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6909
6910 // Read the remaining operands.
6911 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6912 // Read the first operand.
6913 if (parseOperand(Operands, Name)) {
6914 SMLoc Loc = getLexer().getLoc();
6915 return Error(Loc, "unexpected token in argument list");
6916 }
6917 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6918 return true;
6919 // AFAIK, parenthesis suffixes are never on the first operand
6920
6921 while (getLexer().is(AsmToken::Comma)) {
6922 Parser.Lex(); // Eat the comma.
6923 // Parse and remember the operand.
6924 if (parseOperand(Operands, Name)) {
6925 SMLoc Loc = getLexer().getLoc();
6926 return Error(Loc, "unexpected token in argument list");
6927 }
6928 // Parse bracket and parenthesis suffixes before we iterate
6929 if (getLexer().is(AsmToken::LBrac)) {
6930 if (parseBracketSuffix(Name, Operands))
6931 return true;
6932 } else if (getLexer().is(AsmToken::LParen) &&
6933 parseParenSuffix(Name, Operands))
6934 return true;
6935 }
6936 }
6937 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6938 SMLoc Loc = getLexer().getLoc();
6939 return Error(Loc, "unexpected token in argument list");
6940 }
6941 Parser.Lex(); // Consume the EndOfStatement.
6942 return false;
6943}
6944
6945// FIXME: Given that these have the same name, these should both be
6946// consistent on affecting the Parser.
6947bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
6948 SMLoc Loc = getLexer().getLoc();
6949 return Error(Loc, ErrorMsg);
6950}
6951
6952bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
6953 return Error(Loc, ErrorMsg);
6954}
6955
6956bool MipsAsmParser::parseSetNoAtDirective() {
6957 MCAsmParser &Parser = getParser();
6958 // Line should look like: ".set noat".
6959
6960 // Set the $at register to $0.
6961 AssemblerOptions.back()->setATRegIndex(0);
6962
6963 Parser.Lex(); // Eat "noat".
6964
6965 // If this is not the end of the statement, report an error.
6966 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6967 reportParseError("unexpected token, expected end of statement");
6968 return false;
6969 }
6970
6971 getTargetStreamer().emitDirectiveSetNoAt();
6972 Parser.Lex(); // Consume the EndOfStatement.
6973 return false;
6974}
6975
6976bool MipsAsmParser::parseSetAtDirective() {
6977 // Line can be: ".set at", which sets $at to $1
6978 // or ".set at=$reg", which sets $at to $reg.
6979 MCAsmParser &Parser = getParser();
6980 Parser.Lex(); // Eat "at".
6981
6982 if (getLexer().is(AsmToken::EndOfStatement)) {
6983 // No register was specified, so we set $at to $1.
6984 AssemblerOptions.back()->setATRegIndex(1);
6985
6986 getTargetStreamer().emitDirectiveSetAt();
6987 Parser.Lex(); // Consume the EndOfStatement.
6988 return false;
6989 }
6990
6991 if (getLexer().isNot(AsmToken::Equal)) {
6992 reportParseError("unexpected token, expected equals sign");
6993 return false;
6994 }
6995 Parser.Lex(); // Eat "=".
6996
6997 if (getLexer().isNot(AsmToken::Dollar)) {
6998 if (getLexer().is(AsmToken::EndOfStatement)) {
6999 reportParseError("no register specified");
7000 return false;
7001 } else {
7002 reportParseError("unexpected token, expected dollar sign '$'");
7003 return false;
7004 }
7005 }
7006 Parser.Lex(); // Eat "$".
7007
7008 // Find out what "reg" is.
7009 unsigned AtRegNo;
7010 const AsmToken &Reg = Parser.getTok();
7011 if (Reg.is(AsmToken::Identifier)) {
7012 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7013 } else if (Reg.is(AsmToken::Integer)) {
7014 AtRegNo = Reg.getIntVal();
7015 } else {
7016 reportParseError("unexpected token, expected identifier or integer");
7017 return false;
7018 }
7019
7020 // Check if $reg is a valid register. If it is, set $at to $reg.
7021 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7022 reportParseError("invalid register");
7023 return false;
7024 }
7025 Parser.Lex(); // Eat "reg".
7026
7027 // If this is not the end of the statement, report an error.
7028 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7029 reportParseError("unexpected token, expected end of statement");
7030 return false;
7031 }
7032
7033 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7034
7035 Parser.Lex(); // Consume the EndOfStatement.
7036 return false;
7037}
7038
7039bool MipsAsmParser::parseSetReorderDirective() {
7040 MCAsmParser &Parser = getParser();
7041 Parser.Lex();
7042 // If this is not the end of the statement, report an error.
7043 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7044 reportParseError("unexpected token, expected end of statement");
7045 return false;
7046 }
7047 AssemblerOptions.back()->setReorder();
7048 getTargetStreamer().emitDirectiveSetReorder();
7049 Parser.Lex(); // Consume the EndOfStatement.
7050 return false;
7051}
7052
7053bool MipsAsmParser::parseSetNoReorderDirective() {
7054 MCAsmParser &Parser = getParser();
7055 Parser.Lex();
7056 // If this is not the end of the statement, report an error.
7057 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7058 reportParseError("unexpected token, expected end of statement");
7059 return false;
7060 }
7061 AssemblerOptions.back()->setNoReorder();
7062 getTargetStreamer().emitDirectiveSetNoReorder();
7063 Parser.Lex(); // Consume the EndOfStatement.
7064 return false;
7065}
7066
7067bool MipsAsmParser::parseSetMacroDirective() {
7068 MCAsmParser &Parser = getParser();
7069 Parser.Lex();
7070 // If this is not the end of the statement, report an error.
7071 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7072 reportParseError("unexpected token, expected end of statement");
7073 return false;
7074 }
7075 AssemblerOptions.back()->setMacro();
7076 getTargetStreamer().emitDirectiveSetMacro();
7077 Parser.Lex(); // Consume the EndOfStatement.
7078 return false;
7079}
7080
7081bool MipsAsmParser::parseSetNoMacroDirective() {
7082 MCAsmParser &Parser = getParser();
7083 Parser.Lex();
7084 // If this is not the end of the statement, report an error.
7085 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7086 reportParseError("unexpected token, expected end of statement");
7087 return false;
7088 }
7089 if (AssemblerOptions.back()->isReorder()) {
7090 reportParseError("`noreorder' must be set before `nomacro'");
7091 return false;
7092 }
7093 AssemblerOptions.back()->setNoMacro();
7094 getTargetStreamer().emitDirectiveSetNoMacro();
7095 Parser.Lex(); // Consume the EndOfStatement.
7096 return false;
7097}
7098
7099bool MipsAsmParser::parseSetMsaDirective() {
7100 MCAsmParser &Parser = getParser();
7101 Parser.Lex();
7102
7103 // If this is not the end of the statement, report an error.
7104 if (getLexer().isNot(AsmToken::EndOfStatement))
7105 return reportParseError("unexpected token, expected end of statement");
7106
7107 setFeatureBits(Mips::FeatureMSA, "msa");
7108 getTargetStreamer().emitDirectiveSetMsa();
7109 return false;
7110}
7111
7112bool MipsAsmParser::parseSetNoMsaDirective() {
7113 MCAsmParser &Parser = getParser();
7114 Parser.Lex();
7115
7116 // If this is not the end of the statement, report an error.
7117 if (getLexer().isNot(AsmToken::EndOfStatement))
7118 return reportParseError("unexpected token, expected end of statement");
7119
7120 clearFeatureBits(Mips::FeatureMSA, "msa");
7121 getTargetStreamer().emitDirectiveSetNoMsa();
7122 return false;
7123}
7124
7125bool MipsAsmParser::parseSetNoDspDirective() {
7126 MCAsmParser &Parser = getParser();
7127 Parser.Lex(); // Eat "nodsp".
7128
7129 // If this is not the end of the statement, report an error.
7130 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7131 reportParseError("unexpected token, expected end of statement");
7132 return false;
7133 }
7134
7135 clearFeatureBits(Mips::FeatureDSP, "dsp");
7136 getTargetStreamer().emitDirectiveSetNoDsp();
7137 return false;
7138}
7139
7140bool MipsAsmParser::parseSetNoMips3DDirective() {
7141 MCAsmParser &Parser = getParser();
7142 Parser.Lex(); // Eat "nomips3d".
7143
7144 // If this is not the end of the statement, report an error.
7145 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7146 reportParseError("unexpected token, expected end of statement");
7147 return false;
7148 }
7149
7150 clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7151 getTargetStreamer().emitDirectiveSetNoMips3D();
7152 return false;
7153}
7154
7155bool MipsAsmParser::parseSetMips16Directive() {
7156 MCAsmParser &Parser = getParser();
7157 Parser.Lex(); // Eat "mips16".
7158
7159 // If this is not the end of the statement, report an error.
7160 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7161 reportParseError("unexpected token, expected end of statement");
7162 return false;
7163 }
7164
7165 setFeatureBits(Mips::FeatureMips16, "mips16");
7166 getTargetStreamer().emitDirectiveSetMips16();
7167 Parser.Lex(); // Consume the EndOfStatement.
7168 return false;
7169}
7170
7171bool MipsAsmParser::parseSetNoMips16Directive() {
7172 MCAsmParser &Parser = getParser();
7173 Parser.Lex(); // Eat "nomips16".
7174
7175 // If this is not the end of the statement, report an error.
7176 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7177 reportParseError("unexpected token, expected end of statement");
7178 return false;
7179 }
7180
7181 clearFeatureBits(Mips::FeatureMips16, "mips16");
7182 getTargetStreamer().emitDirectiveSetNoMips16();
7183 Parser.Lex(); // Consume the EndOfStatement.
7184 return false;
7185}
7186
7187bool MipsAsmParser::parseSetFpDirective() {
7188 MCAsmParser &Parser = getParser();
7190 // Line can be: .set fp=32
7191 // .set fp=xx
7192 // .set fp=64
7193 Parser.Lex(); // Eat fp token
7194 AsmToken Tok = Parser.getTok();
7195 if (Tok.isNot(AsmToken::Equal)) {
7196 reportParseError("unexpected token, expected equals sign '='");
7197 return false;
7198 }
7199 Parser.Lex(); // Eat '=' token.
7200 Tok = Parser.getTok();
7201
7202 if (!parseFpABIValue(FpAbiVal, ".set"))
7203 return false;
7204
7205 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7206 reportParseError("unexpected token, expected end of statement");
7207 return false;
7208 }
7209 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7210 Parser.Lex(); // Consume the EndOfStatement.
7211 return false;
7212}
7213
7214bool MipsAsmParser::parseSetOddSPRegDirective() {
7215 MCAsmParser &Parser = getParser();
7216
7217 Parser.Lex(); // Eat "oddspreg".
7218 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7219 reportParseError("unexpected token, expected end of statement");
7220 return false;
7221 }
7222
7223 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7224 getTargetStreamer().emitDirectiveSetOddSPReg();
7225 return false;
7226}
7227
7228bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7229 MCAsmParser &Parser = getParser();
7230
7231 Parser.Lex(); // Eat "nooddspreg".
7232 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7233 reportParseError("unexpected token, expected end of statement");
7234 return false;
7235 }
7236
7237 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7238 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7239 return false;
7240}
7241
7242bool MipsAsmParser::parseSetMtDirective() {
7243 MCAsmParser &Parser = getParser();
7244 Parser.Lex(); // Eat "mt".
7245
7246 // If this is not the end of the statement, report an error.
7247 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7248 reportParseError("unexpected token, expected end of statement");
7249 return false;
7250 }
7251
7252 setFeatureBits(Mips::FeatureMT, "mt");
7253 getTargetStreamer().emitDirectiveSetMt();
7254 Parser.Lex(); // Consume the EndOfStatement.
7255 return false;
7256}
7257
7258bool MipsAsmParser::parseSetNoMtDirective() {
7259 MCAsmParser &Parser = getParser();
7260 Parser.Lex(); // Eat "nomt".
7261
7262 // If this is not the end of the statement, report an error.
7263 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7264 reportParseError("unexpected token, expected end of statement");
7265 return false;
7266 }
7267
7268 clearFeatureBits(Mips::FeatureMT, "mt");
7269
7270 getTargetStreamer().emitDirectiveSetNoMt();
7271 Parser.Lex(); // Consume the EndOfStatement.
7272 return false;
7273}
7274
7275bool MipsAsmParser::parseSetNoCRCDirective() {
7276 MCAsmParser &Parser = getParser();
7277 Parser.Lex(); // Eat "nocrc".
7278
7279 // If this is not the end of the statement, report an error.
7280 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7281 reportParseError("unexpected token, expected end of statement");
7282 return false;
7283 }
7284
7285 clearFeatureBits(Mips::FeatureCRC, "crc");
7286
7287 getTargetStreamer().emitDirectiveSetNoCRC();
7288 Parser.Lex(); // Consume the EndOfStatement.
7289 return false;
7290}
7291
7292bool MipsAsmParser::parseSetNoVirtDirective() {
7293 MCAsmParser &Parser = getParser();
7294 Parser.Lex(); // Eat "novirt".
7295
7296 // If this is not the end of the statement, report an error.
7297 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7298 reportParseError("unexpected token, expected end of statement");
7299 return false;
7300 }
7301
7302 clearFeatureBits(Mips::FeatureVirt, "virt");
7303
7304 getTargetStreamer().emitDirectiveSetNoVirt();
7305 Parser.Lex(); // Consume the EndOfStatement.
7306 return false;
7307}
7308
7309bool MipsAsmParser::parseSetNoGINVDirective() {
7310 MCAsmParser &Parser = getParser();
7311 Parser.Lex(); // Eat "noginv".
7312
7313 // If this is not the end of the statement, report an error.
7314 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7315 reportParseError("unexpected token, expected end of statement");
7316 return false;
7317 }
7318
7319 clearFeatureBits(Mips::FeatureGINV, "ginv");
7320
7321 getTargetStreamer().emitDirectiveSetNoGINV();
7322 Parser.Lex(); // Consume the EndOfStatement.
7323 return false;
7324}
7325
7326bool MipsAsmParser::parseSetPopDirective() {
7327 MCAsmParser &Parser = getParser();
7328 SMLoc Loc = getLexer().getLoc();
7329
7330 Parser.Lex();
7331 if (getLexer().isNot(AsmToken::EndOfStatement))
7332 return reportParseError("unexpected token, expected end of statement");
7333
7334 // Always keep an element on the options "stack" to prevent the user
7335 // from changing the initial options. This is how we remember them.
7336 if (AssemblerOptions.size() == 2)
7337 return reportParseError(Loc, ".set pop with no .set push");
7338
7339 MCSubtargetInfo &STI = copySTI();
7340 AssemblerOptions.pop_back();
7341 setAvailableFeatures(
7342 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7343 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7344
7345 getTargetStreamer().emitDirectiveSetPop();
7346 return false;
7347}
7348
7349bool MipsAsmParser::parseSetPushDirective() {
7350 MCAsmParser &Parser = getParser();
7351 Parser.Lex();
7352 if (getLexer().isNot(AsmToken::EndOfStatement))
7353 return reportParseError("unexpected token, expected end of statement");
7354
7355 // Create a copy of the current assembler options environment and push it.
7356 AssemblerOptions.push_back(
7357 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7358
7359 getTargetStreamer().emitDirectiveSetPush();
7360 return false;
7361}
7362
7363bool MipsAsmParser::parseSetSoftFloatDirective() {
7364 MCAsmParser &Parser = getParser();
7365 Parser.Lex();
7366 if (getLexer().isNot(AsmToken::EndOfStatement))
7367 return reportParseError("unexpected token, expected end of statement");
7368
7369 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7370 getTargetStreamer().emitDirectiveSetSoftFloat();
7371 return false;
7372}
7373
7374bool MipsAsmParser::parseSetHardFloatDirective() {
7375 MCAsmParser &Parser = getParser();
7376 Parser.Lex();
7377 if (getLexer().isNot(AsmToken::EndOfStatement))
7378 return reportParseError("unexpected token, expected end of statement");
7379
7380 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7381 getTargetStreamer().emitDirectiveSetHardFloat();
7382 return false;
7383}
7384
7385bool MipsAsmParser::parseSetAssignment() {
7386 StringRef Name;
7387 MCAsmParser &Parser = getParser();
7388
7389 if (Parser.parseIdentifier(Name))
7390 return reportParseError("expected identifier after .set");
7391
7392 if (getLexer().isNot(AsmToken::Comma))
7393 return reportParseError("unexpected token, expected comma");
7394 Lex(); // Eat comma
7395
7396 if (getLexer().is(AsmToken::Dollar) &&
7397 getLexer().peekTok().is(AsmToken::Integer)) {
7398 // Parse assignment of a numeric register:
7399 // .set r1,$1
7400 Parser.Lex(); // Eat $.
7401 RegisterSets[Name] = Parser.getTok();
7402 Parser.Lex(); // Eat identifier.
7403 getContext().getOrCreateSymbol(Name);
7404 return false;
7405 }
7406
7407 MCSymbol *Sym;
7408 const MCExpr *Value;
7409 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7410 Parser, Sym, Value))
7411 return true;
7412 getStreamer().emitAssignment(Sym, Value);
7413
7414 return false;
7415}
7416
7417bool MipsAsmParser::parseSetMips0Directive() {
7418 MCAsmParser &Parser = getParser();
7419 Parser.Lex();
7420 if (getLexer().isNot(AsmToken::EndOfStatement))
7421 return reportParseError("unexpected token, expected end of statement");
7422
7423 // Reset assembler options to their initial values.
7424 MCSubtargetInfo &STI = copySTI();
7425 setAvailableFeatures(
7426 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7427 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7428 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7429
7430 getTargetStreamer().emitDirectiveSetMips0();
7431 return false;
7432}
7433
7434bool MipsAsmParser::parseSetArchDirective() {
7435 MCAsmParser &Parser = getParser();
7436 Parser.Lex();
7437 if (getLexer().isNot(AsmToken::Equal))
7438 return reportParseError("unexpected token, expected equals sign");
7439
7440 Parser.Lex();
7441 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7442 if (Arch.empty())
7443 return reportParseError("expected arch identifier");
7444
7445 StringRef ArchFeatureName =
7446 StringSwitch<StringRef>(Arch)
7447 .Case("mips1", "mips1")
7448 .Case("mips2", "mips2")
7449 .Case("mips3", "mips3")
7450 .Case("mips4", "mips4")
7451 .Case("mips5", "mips5")
7452 .Case("mips32", "mips32")
7453 .Case("mips32r2", "mips32r2")
7454 .Case("mips32r3", "mips32r3")
7455 .Case("mips32r5", "mips32r5")
7456 .Case("mips32r6", "mips32r6")
7457 .Case("mips64", "mips64")
7458 .Case("mips64r2", "mips64r2")
7459 .Case("mips64r3", "mips64r3")
7460 .Case("mips64r5", "mips64r5")
7461 .Case("mips64r6", "mips64r6")
7462 .Case("octeon", "cnmips")
7463 .Case("octeon+", "cnmipsp")
7464 .Case("r4000", "mips3") // This is an implementation of Mips3.
7465 .Default("");
7466
7467 if (ArchFeatureName.empty())
7468 return reportParseError("unsupported architecture");
7469
7470 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7471 return reportParseError("mips64r6 does not support microMIPS");
7472
7473 selectArch(ArchFeatureName);
7474 getTargetStreamer().emitDirectiveSetArch(Arch);
7475 return false;
7476}
7477
7478bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7479 MCAsmParser &Parser = getParser();
7480 Parser.Lex();
7481 if (getLexer().isNot(AsmToken::EndOfStatement))
7482 return reportParseError("unexpected token, expected end of statement");
7483
7484 switch (Feature) {
7485 default:
7486 llvm_unreachable("Unimplemented feature");
7487 case Mips::FeatureMips3D:
7488 setFeatureBits(Mips::FeatureMips3D, "mips3d");
7489 getTargetStreamer().emitDirectiveSetMips3D();
7490 break;
7491 case Mips::FeatureDSP:
7492 setFeatureBits(Mips::FeatureDSP, "dsp");
7493 getTargetStreamer().emitDirectiveSetDsp();
7494 break;
7495 case Mips::FeatureDSPR2:
7496 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7497 getTargetStreamer().emitDirectiveSetDspr2();
7498 break;
7499 case Mips::FeatureMicroMips:
7500 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7501 getTargetStreamer().emitDirectiveSetMicroMips();
7502 break;
7503 case Mips::FeatureMips1:
7504 selectArch("mips1");
7505 getTargetStreamer().emitDirectiveSetMips1();
7506 break;
7507 case Mips::FeatureMips2:
7508 selectArch("mips2");
7509 getTargetStreamer().emitDirectiveSetMips2();
7510 break;
7511 case Mips::FeatureMips3:
7512 selectArch("mips3");
7513 getTargetStreamer().emitDirectiveSetMips3();
7514 break;
7515 case Mips::FeatureMips4:
7516 selectArch("mips4");
7517 getTargetStreamer().emitDirectiveSetMips4();
7518 break;
7519 case Mips::FeatureMips5:
7520 selectArch("mips5");
7521 getTargetStreamer().emitDirectiveSetMips5();
7522 break;
7523 case Mips::FeatureMips32:
7524 selectArch("mips32");
7525 getTargetStreamer().emitDirectiveSetMips32();
7526 break;
7527 case Mips::FeatureMips32r2:
7528 selectArch("mips32r2");
7529 getTargetStreamer().emitDirectiveSetMips32R2();
7530 break;
7531 case Mips::FeatureMips32r3:
7532 selectArch("mips32r3");
7533 getTargetStreamer().emitDirectiveSetMips32R3();
7534 break;
7535 case Mips::FeatureMips32r5:
7536 selectArch("mips32r5");
7537 getTargetStreamer().emitDirectiveSetMips32R5();
7538 break;
7539 case Mips::FeatureMips32r6:
7540 selectArch("mips32r6");
7541 getTargetStreamer().emitDirectiveSetMips32R6();
7542 break;
7543 case Mips::FeatureMips64:
7544 selectArch("mips64");
7545 getTargetStreamer().emitDirectiveSetMips64();
7546 break;
7547 case Mips::FeatureMips64r2:
7548 selectArch("mips64r2");
7549 getTargetStreamer().emitDirectiveSetMips64R2();
7550 break;
7551 case Mips::FeatureMips64r3:
7552 selectArch("mips64r3");
7553 getTargetStreamer().emitDirectiveSetMips64R3();
7554 break;
7555 case Mips::FeatureMips64r5:
7556 selectArch("mips64r5");
7557 getTargetStreamer().emitDirectiveSetMips64R5();
7558 break;
7559 case Mips::FeatureMips64r6:
7560 selectArch("mips64r6");
7561 getTargetStreamer().emitDirectiveSetMips64R6();
7562 break;
7563 case Mips::FeatureCRC:
7564 setFeatureBits(Mips::FeatureCRC, "crc");
7565 getTargetStreamer().emitDirectiveSetCRC();
7566 break;
7567 case Mips::FeatureVirt:
7568 setFeatureBits(Mips::FeatureVirt, "virt");
7569 getTargetStreamer().emitDirectiveSetVirt();
7570 break;
7571 case Mips::FeatureGINV:
7572 setFeatureBits(Mips::FeatureGINV, "ginv");
7573 getTargetStreamer().emitDirectiveSetGINV();
7574 break;
7575 }
7576 return false;
7577}
7578
7579bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7580 MCAsmParser &Parser = getParser();
7581 if (getLexer().isNot(AsmToken::Comma)) {
7582 SMLoc Loc = getLexer().getLoc();
7583 return Error(Loc, ErrorStr);
7584 }
7585
7586 Parser.Lex(); // Eat the comma.
7587 return true;
7588}
7589
7590// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7591// In this class, it is only used for .cprestore.
7592// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7593// MipsTargetELFStreamer and MipsAsmParser.
7594bool MipsAsmParser::isPicAndNotNxxAbi() {
7595 return inPicMode() && !(isABI_N32() || isABI_N64());
7596}
7597
7598bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7600 ParseStatus Res = parseAnyRegister(Reg);
7601 if (Res.isNoMatch() || Res.isFailure()) {
7602 reportParseError("expected register");
7603 return false;
7604 }
7605
7606 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7607 if (!RegOpnd.isGPRAsmReg()) {
7608 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7609 return false;
7610 }
7611
7612 // If this is not the end of the statement, report an error.
7613 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7614 reportParseError("unexpected token, expected end of statement");
7615 return false;
7616 }
7617 getParser().Lex(); // Consume the EndOfStatement.
7618
7619 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7620 return false;
7621}
7622
7623bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7624 if (AssemblerOptions.back()->isReorder())
7625 Warning(Loc, ".cpload should be inside a noreorder section");
7626
7627 if (inMips16Mode()) {
7628 reportParseError(".cpload is not supported in Mips16 mode");
7629 return false;
7630 }
7631
7633 ParseStatus Res = parseAnyRegister(Reg);
7634 if (Res.isNoMatch() || Res.isFailure()) {
7635 reportParseError("expected register containing function address");
7636 return false;
7637 }
7638
7639 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7640 if (!RegOpnd.isGPRAsmReg()) {
7641 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7642 return false;
7643 }
7644
7645 // If this is not the end of the statement, report an error.
7646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7647 reportParseError("unexpected token, expected end of statement");
7648 return false;
7649 }
7650
7651 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7652 return false;
7653}
7654
7655bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7656 if (!isABI_N32() && !isABI_N64()) {
7657 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7658 return false;
7659 }
7660
7662 ParseStatus Res = parseAnyRegister(Reg);
7663 if (Res.isNoMatch() || Res.isFailure()) {
7664 reportParseError("expected register containing global pointer");
7665 return false;
7666 }
7667
7668 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7669 if (!RegOpnd.isGPRAsmReg()) {
7670 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7671 return false;
7672 }
7673
7674 // If this is not the end of the statement, report an error.
7675 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7676 reportParseError("unexpected token, expected end of statement");
7677 return false;
7678 }
7679 getParser().Lex(); // Consume the EndOfStatement.
7680
7681 MCRegister NewReg = RegOpnd.getGPR32Reg();
7682 if (IsPicEnabled)
7683 GPReg = NewReg;
7684
7685 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7686 return false;
7687}
7688
7689bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7690 MCAsmParser &Parser = getParser();
7691
7692 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7693 // is used in non-PIC mode.
7694
7695 if (inMips16Mode()) {
7696 reportParseError(".cprestore is not supported in Mips16 mode");
7697 return false;
7698 }
7699
7700 // Get the stack offset value.
7701 const MCExpr *StackOffset;
7702 int64_t StackOffsetVal;
7703 if (Parser.parseExpression(StackOffset)) {
7704 reportParseError("expected stack offset value");
7705 return false;
7706 }
7707
7708 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7709 reportParseError("stack offset is not an absolute expression");
7710 return false;
7711 }
7712
7713 if (StackOffsetVal < 0) {
7714 Warning(Loc, ".cprestore with negative stack offset has no effect");
7715 IsCpRestoreSet = false;
7716 } else {
7717 IsCpRestoreSet = true;
7718 CpRestoreOffset = StackOffsetVal;
7719 }
7720
7721 // If this is not the end of the statement, report an error.
7722 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7723 reportParseError("unexpected token, expected end of statement");
7724 return false;
7725 }
7726
7727 if (!getTargetStreamer().emitDirectiveCpRestore(
7728 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7729 return true;
7730 Parser.Lex(); // Consume the EndOfStatement.
7731 return false;
7732}
7733
7734bool MipsAsmParser::parseDirectiveCPSetup() {
7735 MCAsmParser &Parser = getParser();
7736 unsigned Save;
7737 bool SaveIsReg = true;
7738
7740 ParseStatus Res = parseAnyRegister(TmpReg);
7741 if (Res.isNoMatch()) {
7742 reportParseError("expected register containing function address");
7743 return false;
7744 }
7745
7746 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7747 if (!FuncRegOpnd.isGPRAsmReg()) {
7748 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7749 return false;
7750 }
7751
7752 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7753 TmpReg.clear();
7754
7755 if (!eatComma("unexpected token, expected comma"))
7756 return true;
7757
7758 Res = parseAnyRegister(TmpReg);
7759 if (Res.isNoMatch()) {
7760 const MCExpr *OffsetExpr;
7761 int64_t OffsetVal;
7762 SMLoc ExprLoc = getLexer().getLoc();
7763
7764 if (Parser.parseExpression(OffsetExpr) ||
7765 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7766 reportParseError(ExprLoc, "expected save register or stack offset");
7767 return false;
7768 }
7769
7770 Save = OffsetVal;
7771 SaveIsReg = false;
7772 } else {
7773 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7774 if (!SaveOpnd.isGPRAsmReg()) {
7775 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7776 return false;
7777 }
7778 Save = SaveOpnd.getGPR32Reg().id();
7779 }
7780
7781 if (!eatComma("unexpected token, expected comma"))
7782 return true;
7783
7784 const MCExpr *Expr;
7785 if (Parser.parseExpression(Expr)) {
7786 reportParseError("expected expression");
7787 return false;
7788 }
7789
7790 if (Expr->getKind() != MCExpr::SymbolRef) {
7791 reportParseError("expected symbol");
7792 return false;
7793 }
7794 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7795
7796 CpSaveLocation = Save;
7797 CpSaveLocationIsRegister = SaveIsReg;
7798
7799 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7800 SaveIsReg);
7801 return false;
7802}
7803
7804bool MipsAsmParser::parseDirectiveCPReturn() {
7805 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7806 CpSaveLocationIsRegister);
7807 return false;
7808}
7809
7810bool MipsAsmParser::parseDirectiveNaN() {
7811 MCAsmParser &Parser = getParser();
7812 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7813 const AsmToken &Tok = Parser.getTok();
7814
7815 if (Tok.getString() == "2008") {
7816 Parser.Lex();
7817 getTargetStreamer().emitDirectiveNaN2008();
7818 return false;
7819 } else if (Tok.getString() == "legacy") {
7820 Parser.Lex();
7821 getTargetStreamer().emitDirectiveNaNLegacy();
7822 return false;
7823 }
7824 }
7825 // If we don't recognize the option passed to the .nan
7826 // directive (e.g. no option or unknown option), emit an error.
7827 reportParseError("invalid option in .nan directive");
7828 return false;
7829}
7830
7831bool MipsAsmParser::parseDirectiveSet() {
7832 const AsmToken &Tok = getParser().getTok();
7833 StringRef IdVal = Tok.getString();
7834 SMLoc Loc = Tok.getLoc();
7835
7836 if (IdVal == "noat")
7837 return parseSetNoAtDirective();
7838 if (IdVal == "at")
7839 return parseSetAtDirective();
7840 if (IdVal == "arch")
7841 return parseSetArchDirective();
7842 if (IdVal == "bopt") {
7843 Warning(Loc, "'bopt' feature is unsupported");
7844 getParser().Lex();
7845 return false;
7846 }
7847 if (IdVal == "nobopt") {
7848 // We're already running in nobopt mode, so nothing to do.
7849 getParser().Lex();
7850 return false;
7851 }
7852 if (IdVal == "fp")
7853 return parseSetFpDirective();
7854 if (IdVal == "oddspreg")
7855 return parseSetOddSPRegDirective();
7856 if (IdVal == "nooddspreg")
7857 return parseSetNoOddSPRegDirective();
7858 if (IdVal == "pop")
7859 return parseSetPopDirective();
7860 if (IdVal == "push")
7861 return parseSetPushDirective();
7862 if (IdVal == "reorder")
7863 return parseSetReorderDirective();
7864 if (IdVal == "noreorder")
7865 return parseSetNoReorderDirective();
7866 if (IdVal == "macro")
7867 return parseSetMacroDirective();
7868 if (IdVal == "nomacro")
7869 return parseSetNoMacroDirective();
7870 if (IdVal == "mips16")
7871 return parseSetMips16Directive();
7872 if (IdVal == "nomips16")
7873 return parseSetNoMips16Directive();
7874 if (IdVal == "nomicromips") {
7875 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7876 getTargetStreamer().emitDirectiveSetNoMicroMips();
7877 getParser().eatToEndOfStatement();
7878 return false;
7879 }
7880 if (IdVal == "micromips") {
7881 if (hasMips64r6()) {
7882 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7883 return false;
7884 }
7885 return parseSetFeature(Mips::FeatureMicroMips);
7886 }
7887 if (IdVal == "mips0")
7888 return parseSetMips0Directive();
7889 if (IdVal == "mips1")
7890 return parseSetFeature(Mips::FeatureMips1);
7891 if (IdVal == "mips2")
7892 return parseSetFeature(Mips::FeatureMips2);
7893 if (IdVal == "mips3")
7894 return parseSetFeature(Mips::FeatureMips3);
7895 if (IdVal == "mips4")
7896 return parseSetFeature(Mips::FeatureMips4);
7897 if (IdVal == "mips5")
7898 return parseSetFeature(Mips::FeatureMips5);
7899 if (IdVal == "mips32")
7900 return parseSetFeature(Mips::FeatureMips32);
7901 if (IdVal == "mips32r2")
7902 return parseSetFeature(Mips::FeatureMips32r2);
7903 if (IdVal == "mips32r3")
7904 return parseSetFeature(Mips::FeatureMips32r3);
7905 if (IdVal == "mips32r5")
7906 return parseSetFeature(Mips::FeatureMips32r5);
7907 if (IdVal == "mips32r6")
7908 return parseSetFeature(Mips::FeatureMips32r6);
7909 if (IdVal == "mips64")
7910 return parseSetFeature(Mips::FeatureMips64);
7911 if (IdVal == "mips64r2")
7912 return parseSetFeature(Mips::FeatureMips64r2);
7913 if (IdVal == "mips64r3")
7914 return parseSetFeature(Mips::FeatureMips64r3);
7915 if (IdVal == "mips64r5")
7916 return parseSetFeature(Mips::FeatureMips64r5);
7917 if (IdVal == "mips64r6") {
7918 if (inMicroMipsMode()) {
7919 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7920 return false;
7921 }
7922 return parseSetFeature(Mips::FeatureMips64r6);
7923 }
7924 if (IdVal == "dsp")
7925 return parseSetFeature(Mips::FeatureDSP);
7926 if (IdVal == "dspr2")
7927 return parseSetFeature(Mips::FeatureDSPR2);
7928 if (IdVal == "nodsp")
7929 return parseSetNoDspDirective();
7930 if (IdVal == "mips3d")
7931 return parseSetFeature(Mips::FeatureMips3D);
7932 if (IdVal == "nomips3d")
7933 return parseSetNoMips3DDirective();
7934 if (IdVal == "msa")
7935 return parseSetMsaDirective();
7936 if (IdVal == "nomsa")
7937 return parseSetNoMsaDirective();
7938 if (IdVal == "mt")
7939 return parseSetMtDirective();
7940 if (IdVal == "nomt")
7941 return parseSetNoMtDirective();
7942 if (IdVal == "softfloat")
7943 return parseSetSoftFloatDirective();
7944 if (IdVal == "hardfloat")
7945 return parseSetHardFloatDirective();
7946 if (IdVal == "crc")
7947 return parseSetFeature(Mips::FeatureCRC);
7948 if (IdVal == "nocrc")
7949 return parseSetNoCRCDirective();
7950 if (IdVal == "virt")
7951 return parseSetFeature(Mips::FeatureVirt);
7952 if (IdVal == "novirt")
7953 return parseSetNoVirtDirective();
7954 if (IdVal == "ginv")
7955 return parseSetFeature(Mips::FeatureGINV);
7956 if (IdVal == "noginv")
7957 return parseSetNoGINVDirective();
7958
7959 // It is just an identifier, look for an assignment.
7960 return parseSetAssignment();
7961}
7962
7963/// parseDirectiveGpWord
7964/// ::= .gpword local_sym
7965bool MipsAsmParser::parseDirectiveGpWord() {
7966 const MCExpr *Value;
7967 if (getParser().parseExpression(Value))
7968 return true;
7969 getTargetStreamer().emitGPRel32Value(Value);
7970 return parseEOL();
7971}
7972
7973/// parseDirectiveGpDWord
7974/// ::= .gpdword local_sym
7975bool MipsAsmParser::parseDirectiveGpDWord() {
7976 const MCExpr *Value;
7977 if (getParser().parseExpression(Value))
7978 return true;
7979 getTargetStreamer().emitGPRel64Value(Value);
7980 return parseEOL();
7981}
7982
7983/// parseDirectiveDtpRelWord
7984/// ::= .dtprelword tls_sym
7985bool MipsAsmParser::parseDirectiveDtpRelWord() {
7986 const MCExpr *Value;
7987 if (getParser().parseExpression(Value))
7988 return true;
7989 getTargetStreamer().emitDTPRel32Value(Value);
7990 return parseEOL();
7991}
7992
7993/// parseDirectiveDtpRelDWord
7994/// ::= .dtpreldword tls_sym
7995bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7996 const MCExpr *Value;
7997 if (getParser().parseExpression(Value))
7998 return true;
7999 getTargetStreamer().emitDTPRel64Value(Value);
8000 return parseEOL();
8001}
8002
8003/// parseDirectiveTpRelWord
8004/// ::= .tprelword tls_sym
8005bool MipsAsmParser::parseDirectiveTpRelWord() {
8006 const MCExpr *Value;
8007 if (getParser().parseExpression(Value))
8008 return true;
8009 getTargetStreamer().emitTPRel32Value(Value);
8010 return parseEOL();
8011}
8012
8013/// parseDirectiveTpRelDWord
8014/// ::= .tpreldword tls_sym
8015bool MipsAsmParser::parseDirectiveTpRelDWord() {
8016 const MCExpr *Value;
8017 if (getParser().parseExpression(Value))
8018 return true;
8019 getTargetStreamer().emitTPRel64Value(Value);
8020 return parseEOL();
8021}
8022
8023bool MipsAsmParser::parseDirectiveOption() {
8024 MCAsmParser &Parser = getParser();
8025 // Get the option token.
8026 AsmToken Tok = Parser.getTok();
8027 // At the moment only identifiers are supported.
8028 if (Tok.isNot(AsmToken::Identifier)) {
8029 return Error(Parser.getTok().getLoc(),
8030 "unexpected token, expected identifier");
8031 }
8032
8033 StringRef Option = Tok.getIdentifier();
8034
8035 if (Option == "pic0") {
8036 // MipsAsmParser needs to know if the current PIC mode changes.
8037 IsPicEnabled = false;
8038
8039 getTargetStreamer().emitDirectiveOptionPic0();
8040 Parser.Lex();
8041 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8042 return Error(Parser.getTok().getLoc(),
8043 "unexpected token, expected end of statement");
8044 }
8045 return false;
8046 }
8047
8048 if (Option == "pic2") {
8049 // MipsAsmParser needs to know if the current PIC mode changes.
8050 IsPicEnabled = true;
8051
8052 getTargetStreamer().emitDirectiveOptionPic2();
8053 Parser.Lex();
8054 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8055 return Error(Parser.getTok().getLoc(),
8056 "unexpected token, expected end of statement");
8057 }
8058 return false;
8059 }
8060
8061 // Unknown option.
8062 Warning(Parser.getTok().getLoc(),
8063 "unknown option, expected 'pic0' or 'pic2'");
8064 Parser.eatToEndOfStatement();
8065 return false;
8066}
8067
8068/// parseInsnDirective
8069/// ::= .insn
8070bool MipsAsmParser::parseInsnDirective() {
8071 // If this is not the end of the statement, report an error.
8072 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8073 reportParseError("unexpected token, expected end of statement");
8074 return false;
8075 }
8076
8077 // The actual label marking happens in
8078 // MipsELFStreamer::createPendingLabelRelocs().
8079 getTargetStreamer().emitDirectiveInsn();
8080
8081 getParser().Lex(); // Eat EndOfStatement token.
8082 return false;
8083}
8084
8085/// parseRSectionDirective
8086/// ::= .rdata
8087bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8088 // If this is not the end of the statement, report an error.
8089 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8090 reportParseError("unexpected token, expected end of statement");
8091 return false;
8092 }
8093
8094 MCSection *ELFSection = getContext().getELFSection(
8096 getParser().getStreamer().switchSection(ELFSection);
8097
8098 getParser().Lex(); // Eat EndOfStatement token.
8099 return false;
8100}
8101
8102/// parseSSectionDirective
8103/// ::= .sbss
8104/// ::= .sdata
8105bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8106 // If this is not the end of the statement, report an error.
8107 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8108 reportParseError("unexpected token, expected end of statement");
8109 return false;
8110 }
8111
8112 MCSection *ELFSection = getContext().getELFSection(
8114 getParser().getStreamer().switchSection(ELFSection);
8115
8116 getParser().Lex(); // Eat EndOfStatement token.
8117 return false;
8118}
8119
8120/// parseDirectiveModule
8121/// ::= .module oddspreg
8122/// ::= .module nooddspreg
8123/// ::= .module fp=value
8124/// ::= .module softfloat
8125/// ::= .module hardfloat
8126/// ::= .module mt
8127/// ::= .module crc
8128/// ::= .module nocrc
8129/// ::= .module virt
8130/// ::= .module novirt
8131/// ::= .module ginv
8132/// ::= .module noginv
8133bool MipsAsmParser::parseDirectiveModule() {
8134 MCAsmParser &Parser = getParser();
8135 AsmLexer &Lexer = getLexer();
8136 SMLoc L = Lexer.getLoc();
8137
8138 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8139 // TODO : get a better message.
8140 reportParseError(".module directive must appear before any code");
8141 return false;
8142 }
8143
8144 StringRef Option;
8145 if (Parser.parseIdentifier(Option)) {
8146 reportParseError("expected .module option identifier");
8147 return false;
8148 }
8149
8150 if (Option == "oddspreg") {
8151 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8152
8153 // Synchronize the abiflags information with the FeatureBits information we
8154 // changed above.
8155 getTargetStreamer().updateABIInfo(*this);
8156
8157 // If printing assembly, use the recently updated abiflags information.
8158 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8159 // emitted at the end).
8160 getTargetStreamer().emitDirectiveModuleOddSPReg();
8161
8162 // If this is not the end of the statement, report an error.
8163 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8164 reportParseError("unexpected token, expected end of statement");
8165 return false;
8166 }
8167
8168 return false; // parseDirectiveModule has finished successfully.
8169 } else if (Option == "nooddspreg") {
8170 if (!isABI_O32()) {
8171 return Error(L, "'.module nooddspreg' requires the O32 ABI");
8172 }
8173
8174 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8175
8176 // Synchronize the abiflags information with the FeatureBits information we
8177 // changed above.
8178 getTargetStreamer().updateABIInfo(*this);
8179
8180 // If printing assembly, use the recently updated abiflags information.
8181 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8182 // emitted at the end).
8183 getTargetStreamer().emitDirectiveModuleOddSPReg();
8184
8185 // If this is not the end of the statement, report an error.
8186 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8187 reportParseError("unexpected token, expected end of statement");
8188 return false;
8189 }
8190
8191 return false; // parseDirectiveModule has finished successfully.
8192 } else if (Option == "fp") {
8193 return parseDirectiveModuleFP();
8194 } else if (Option == "softfloat") {
8195 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8196
8197 // Synchronize the ABI Flags information with the FeatureBits information we
8198 // updated above.
8199 getTargetStreamer().updateABIInfo(*this);
8200
8201 // If printing assembly, use the recently updated ABI Flags information.
8202 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8203 // emitted later).
8204 getTargetStreamer().emitDirectiveModuleSoftFloat();
8205
8206 // If this is not the end of the statement, report an error.
8207 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8208 reportParseError("unexpected token, expected end of statement");
8209 return false;
8210 }
8211
8212 return false; // parseDirectiveModule has finished successfully.
8213 } else if (Option == "hardfloat") {
8214 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8215
8216 // Synchronize the ABI Flags information with the FeatureBits information we
8217 // updated above.
8218 getTargetStreamer().updateABIInfo(*this);
8219
8220 // If printing assembly, use the recently updated ABI Flags information.
8221 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8222 // emitted later).
8223 getTargetStreamer().emitDirectiveModuleHardFloat();
8224
8225 // If this is not the end of the statement, report an error.
8226 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8227 reportParseError("unexpected token, expected end of statement");
8228 return false;
8229 }
8230
8231 return false; // parseDirectiveModule has finished successfully.
8232 } else if (Option == "mt") {
8233 setModuleFeatureBits(Mips::FeatureMT, "mt");
8234
8235 // Synchronize the ABI Flags information with the FeatureBits information we
8236 // updated above.
8237 getTargetStreamer().updateABIInfo(*this);
8238
8239 // If printing assembly, use the recently updated ABI Flags information.
8240 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8241 // emitted later).
8242 getTargetStreamer().emitDirectiveModuleMT();
8243
8244 // If this is not the end of the statement, report an error.
8245 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8246 reportParseError("unexpected token, expected end of statement");
8247 return false;
8248 }
8249
8250 return false; // parseDirectiveModule has finished successfully.
8251 } else if (Option == "crc") {
8252 setModuleFeatureBits(Mips::FeatureCRC, "crc");
8253
8254 // Synchronize the ABI Flags information with the FeatureBits information we
8255 // updated above.
8256 getTargetStreamer().updateABIInfo(*this);
8257
8258 // If printing assembly, use the recently updated ABI Flags information.
8259 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8260 // emitted later).
8261 getTargetStreamer().emitDirectiveModuleCRC();
8262
8263 // If this is not the end of the statement, report an error.
8264 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8265 reportParseError("unexpected token, expected end of statement");
8266 return false;
8267 }
8268
8269 return false; // parseDirectiveModule has finished successfully.
8270 } else if (Option == "nocrc") {
8271 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8272
8273 // Synchronize the ABI Flags information with the FeatureBits information we
8274 // updated above.
8275 getTargetStreamer().updateABIInfo(*this);
8276
8277 // If printing assembly, use the recently updated ABI Flags information.
8278 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8279 // emitted later).
8280 getTargetStreamer().emitDirectiveModuleNoCRC();
8281
8282 // If this is not the end of the statement, report an error.
8283 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8284 reportParseError("unexpected token, expected end of statement");
8285 return false;
8286 }
8287
8288 return false; // parseDirectiveModule has finished successfully.
8289 } else if (Option == "virt") {
8290 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8291
8292 // Synchronize the ABI Flags information with the FeatureBits information we
8293 // updated above.
8294 getTargetStreamer().updateABIInfo(*this);
8295
8296 // If printing assembly, use the recently updated ABI Flags information.
8297 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8298 // emitted later).
8299 getTargetStreamer().emitDirectiveModuleVirt();
8300
8301 // If this is not the end of the statement, report an error.
8302 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8303 reportParseError("unexpected token, expected end of statement");
8304 return false;
8305 }
8306
8307 return false; // parseDirectiveModule has finished successfully.
8308 } else if (Option == "novirt") {
8309 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8310
8311 // Synchronize the ABI Flags information with the FeatureBits information we
8312 // updated above.
8313 getTargetStreamer().updateABIInfo(*this);
8314
8315 // If printing assembly, use the recently updated ABI Flags information.
8316 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8317 // emitted later).
8318 getTargetStreamer().emitDirectiveModuleNoVirt();
8319
8320 // If this is not the end of the statement, report an error.
8321 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8322 reportParseError("unexpected token, expected end of statement");
8323 return false;
8324 }
8325
8326 return false; // parseDirectiveModule has finished successfully.
8327 } else if (Option == "ginv") {
8328 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8329
8330 // Synchronize the ABI Flags information with the FeatureBits information we
8331 // updated above.
8332 getTargetStreamer().updateABIInfo(*this);
8333
8334 // If printing assembly, use the recently updated ABI Flags information.
8335 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8336 // emitted later).
8337 getTargetStreamer().emitDirectiveModuleGINV();
8338
8339 // If this is not the end of the statement, report an error.
8340 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8341 reportParseError("unexpected token, expected end of statement");
8342 return false;
8343 }
8344
8345 return false; // parseDirectiveModule has finished successfully.
8346 } else if (Option == "noginv") {
8347 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8348
8349 // Synchronize the ABI Flags information with the FeatureBits information we
8350 // updated above.
8351 getTargetStreamer().updateABIInfo(*this);
8352
8353 // If printing assembly, use the recently updated ABI Flags information.
8354 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8355 // emitted later).
8356 getTargetStreamer().emitDirectiveModuleNoGINV();
8357
8358 // If this is not the end of the statement, report an error.
8359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8360 reportParseError("unexpected token, expected end of statement");
8361 return false;
8362 }
8363
8364 return false; // parseDirectiveModule has finished successfully.
8365 } else {
8366 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8367 }
8368}
8369
8370/// parseDirectiveModuleFP
8371/// ::= =32
8372/// ::= =xx
8373/// ::= =64
8374bool MipsAsmParser::parseDirectiveModuleFP() {
8375 MCAsmParser &Parser = getParser();
8376 AsmLexer &Lexer = getLexer();
8377
8378 if (Lexer.isNot(AsmToken::Equal)) {
8379 reportParseError("unexpected token, expected equals sign '='");
8380 return false;
8381 }
8382 Parser.Lex(); // Eat '=' token.
8383
8385 if (!parseFpABIValue(FpABI, ".module"))
8386 return false;
8387
8388 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8389 reportParseError("unexpected token, expected end of statement");
8390 return false;
8391 }
8392
8393 // Synchronize the abiflags information with the FeatureBits information we
8394 // changed above.
8395 getTargetStreamer().updateABIInfo(*this);
8396
8397 // If printing assembly, use the recently updated abiflags information.
8398 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8399 // emitted at the end).
8400 getTargetStreamer().emitDirectiveModuleFP();
8401
8402 Parser.Lex(); // Consume the EndOfStatement.
8403 return false;
8404}
8405
8406bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8407 StringRef Directive) {
8408 MCAsmParser &Parser = getParser();
8409 AsmLexer &Lexer = getLexer();
8410 bool ModuleLevelOptions = Directive == ".module";
8411
8412 if (Lexer.is(AsmToken::Identifier)) {
8413 StringRef Value = Parser.getTok().getString();
8414 Parser.Lex();
8415
8416 if (Value != "xx") {
8417 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8418 return false;
8419 }
8420
8421 if (!isABI_O32()) {
8422 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8423 return false;
8424 }
8425
8426 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8427 if (ModuleLevelOptions) {
8428 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8429 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8430 } else {
8431 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8432 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8433 }
8434 return true;
8435 }
8436
8437 if (Lexer.is(AsmToken::Integer)) {
8438 unsigned Value = Parser.getTok().getIntVal();
8439 Parser.Lex();
8440
8441 if (Value != 32 && Value != 64) {
8442 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8443 return false;
8444 }
8445
8446 if (Value == 32) {
8447 if (!isABI_O32()) {
8448 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8449 return false;
8450 }
8451
8452 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8453 if (ModuleLevelOptions) {
8454 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8455 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8456 } else {
8457 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8458 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8459 }
8460 } else {
8461 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8462 if (ModuleLevelOptions) {
8463 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8464 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8465 } else {
8466 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8467 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8468 }
8469 }
8470
8471 return true;
8472 }
8473
8474 return false;
8475}
8476
8477bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8478 // This returns false if this function recognizes the directive
8479 // regardless of whether it is successfully handles or reports an
8480 // error. Otherwise it returns true to give the generic parser a
8481 // chance at recognizing it.
8482
8483 MCAsmParser &Parser = getParser();
8484 StringRef IDVal = DirectiveID.getString();
8485
8486 if (IDVal == ".cpadd") {
8487 parseDirectiveCpAdd(DirectiveID.getLoc());
8488 return false;
8489 }
8490 if (IDVal == ".cpload") {
8491 parseDirectiveCpLoad(DirectiveID.getLoc());
8492 return false;
8493 }
8494 if (IDVal == ".cprestore") {
8495 parseDirectiveCpRestore(DirectiveID.getLoc());
8496 return false;
8497 }
8498 if (IDVal == ".cplocal") {
8499 parseDirectiveCpLocal(DirectiveID.getLoc());
8500 return false;
8501 }
8502 if (IDVal == ".ent") {
8503 StringRef SymbolName;
8504
8505 if (Parser.parseIdentifier(SymbolName)) {
8506 reportParseError("expected identifier after .ent");
8507 return false;
8508 }
8509
8510 // There's an undocumented extension that allows an integer to
8511 // follow the name of the procedure which AFAICS is ignored by GAS.
8512 // Example: .ent foo,2
8513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8514 if (getLexer().isNot(AsmToken::Comma)) {
8515 // Even though we accept this undocumented extension for compatibility
8516 // reasons, the additional integer argument does not actually change
8517 // the behaviour of the '.ent' directive, so we would like to discourage
8518 // its use. We do this by not referring to the extended version in
8519 // error messages which are not directly related to its use.
8520 reportParseError("unexpected token, expected end of statement");
8521 return false;
8522 }
8523 Parser.Lex(); // Eat the comma.
8524 const MCExpr *DummyNumber;
8525 int64_t DummyNumberVal;
8526 // If the user was explicitly trying to use the extended version,
8527 // we still give helpful extension-related error messages.
8528 if (Parser.parseExpression(DummyNumber)) {
8529 reportParseError("expected number after comma");
8530 return false;
8531 }
8532 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8533 reportParseError("expected an absolute expression after comma");
8534 return false;
8535 }
8536 }
8537
8538 // If this is not the end of the statement, report an error.
8539 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8540 reportParseError("unexpected token, expected end of statement");
8541 return false;
8542 }
8543
8544 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8545
8546 getTargetStreamer().emitDirectiveEnt(*Sym);
8547 CurrentFn = Sym;
8548 IsCpRestoreSet = false;
8549 return false;
8550 }
8551
8552 if (IDVal == ".end") {
8553 StringRef SymbolName;
8554
8555 if (Parser.parseIdentifier(SymbolName)) {
8556 reportParseError("expected identifier after .end");
8557 return false;
8558 }
8559
8560 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8561 reportParseError("unexpected token, expected end of statement");
8562 return false;
8563 }
8564
8565 if (CurrentFn == nullptr) {
8566 reportParseError(".end used without .ent");
8567 return false;
8568 }
8569
8570 if ((SymbolName != CurrentFn->getName())) {
8571 reportParseError(".end symbol does not match .ent symbol");
8572 return false;
8573 }
8574
8575 getTargetStreamer().emitDirectiveEnd(SymbolName);
8576 CurrentFn = nullptr;
8577 IsCpRestoreSet = false;
8578 return false;
8579 }
8580
8581 if (IDVal == ".frame") {
8582 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8584 ParseStatus Res = parseAnyRegister(TmpReg);
8585 if (Res.isNoMatch() || Res.isFailure()) {
8586 reportParseError("expected stack register");
8587 return false;
8588 }
8589
8590 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8591 if (!StackRegOpnd.isGPRAsmReg()) {
8592 reportParseError(StackRegOpnd.getStartLoc(),
8593 "expected general purpose register");
8594 return false;
8595 }
8596 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8597
8598 if (Parser.getTok().is(AsmToken::Comma))
8599 Parser.Lex();
8600 else {
8601 reportParseError("unexpected token, expected comma");
8602 return false;
8603 }
8604
8605 // Parse the frame size.
8606 const MCExpr *FrameSize;
8607 int64_t FrameSizeVal;
8608
8609 if (Parser.parseExpression(FrameSize)) {
8610 reportParseError("expected frame size value");
8611 return false;
8612 }
8613
8614 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8615 reportParseError("frame size not an absolute expression");
8616 return false;
8617 }
8618
8619 if (Parser.getTok().is(AsmToken::Comma))
8620 Parser.Lex();
8621 else {
8622 reportParseError("unexpected token, expected comma");
8623 return false;
8624 }
8625
8626 // Parse the return register.
8627 TmpReg.clear();
8628 Res = parseAnyRegister(TmpReg);
8629 if (Res.isNoMatch() || Res.isFailure()) {
8630 reportParseError("expected return register");
8631 return false;
8632 }
8633
8634 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8635 if (!ReturnRegOpnd.isGPRAsmReg()) {
8636 reportParseError(ReturnRegOpnd.getStartLoc(),
8637 "expected general purpose register");
8638 return false;
8639 }
8640
8641 // If this is not the end of the statement, report an error.
8642 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8643 reportParseError("unexpected token, expected end of statement");
8644 return false;
8645 }
8646
8647 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8648 ReturnRegOpnd.getGPR32Reg());
8649 IsCpRestoreSet = false;
8650 return false;
8651 }
8652
8653 if (IDVal == ".set") {
8654 parseDirectiveSet();
8655 return false;
8656 }
8657
8658 if (IDVal == ".mask" || IDVal == ".fmask") {
8659 // .mask bitmask, frame_offset
8660 // bitmask: One bit for each register used.
8661 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8662 // first register is expected to be saved.
8663 // Examples:
8664 // .mask 0x80000000, -4
8665 // .fmask 0x80000000, -4
8666 //
8667
8668 // Parse the bitmask
8669 const MCExpr *BitMask;
8670 int64_t BitMaskVal;
8671
8672 if (Parser.parseExpression(BitMask)) {
8673 reportParseError("expected bitmask value");
8674 return false;
8675 }
8676
8677 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8678 reportParseError("bitmask not an absolute expression");
8679 return false;
8680 }
8681
8682 if (Parser.getTok().is(AsmToken::Comma))
8683 Parser.Lex();
8684 else {
8685 reportParseError("unexpected token, expected comma");
8686 return false;
8687 }
8688
8689 // Parse the frame_offset
8690 const MCExpr *FrameOffset;
8691 int64_t FrameOffsetVal;
8692
8693 if (Parser.parseExpression(FrameOffset)) {
8694 reportParseError("expected frame offset value");
8695 return false;
8696 }
8697
8698 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8699 reportParseError("frame offset not an absolute expression");
8700 return false;
8701 }
8702
8703 // If this is not the end of the statement, report an error.
8704 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8705 reportParseError("unexpected token, expected end of statement");
8706 return false;
8707 }
8708
8709 if (IDVal == ".mask")
8710 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8711 else
8712 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8713 return false;
8714 }
8715
8716 if (IDVal == ".nan")
8717 return parseDirectiveNaN();
8718
8719 if (IDVal == ".gpword") {
8720 parseDirectiveGpWord();
8721 return false;
8722 }
8723
8724 if (IDVal == ".gpdword") {
8725 parseDirectiveGpDWord();
8726 return false;
8727 }
8728
8729 if (IDVal == ".dtprelword") {
8730 parseDirectiveDtpRelWord();
8731 return false;
8732 }
8733
8734 if (IDVal == ".dtpreldword") {
8735 parseDirectiveDtpRelDWord();
8736 return false;
8737 }
8738
8739 if (IDVal == ".tprelword") {
8740 parseDirectiveTpRelWord();
8741 return false;
8742 }
8743
8744 if (IDVal == ".tpreldword") {
8745 parseDirectiveTpRelDWord();
8746 return false;
8747 }
8748
8749 if (IDVal == ".option") {
8750 parseDirectiveOption();
8751 return false;
8752 }
8753
8754 if (IDVal == ".abicalls") {
8755 getTargetStreamer().emitDirectiveAbiCalls();
8756 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8757 Error(Parser.getTok().getLoc(),
8758 "unexpected token, expected end of statement");
8759 }
8760 return false;
8761 }
8762
8763 if (IDVal == ".cpsetup") {
8764 parseDirectiveCPSetup();
8765 return false;
8766 }
8767 if (IDVal == ".cpreturn") {
8768 parseDirectiveCPReturn();
8769 return false;
8770 }
8771 if (IDVal == ".module") {
8772 parseDirectiveModule();
8773 return false;
8774 }
8775 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8776 parseInternalDirectiveReallowModule();
8777 return false;
8778 }
8779 if (IDVal == ".insn") {
8780 parseInsnDirective();
8781 return false;
8782 }
8783 if (IDVal == ".rdata") {
8784 parseRSectionDirective(".rodata");
8785 return false;
8786 }
8787 if (IDVal == ".sbss") {
8788 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8789 return false;
8790 }
8791 if (IDVal == ".sdata") {
8792 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8793 return false;
8794 }
8795
8796 return true;
8797}
8798
8799bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8800 // If this is not the end of the statement, report an error.
8801 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8802 reportParseError("unexpected token, expected end of statement");
8803 return false;
8804 }
8805
8806 getTargetStreamer().reallowModuleDirective();
8807
8808 getParser().Lex(); // Eat EndOfStatement token.
8809 return false;
8810}
8811
8812extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
8819
8820#define GET_REGISTER_MATCHER
8821#define GET_MATCHER_IMPLEMENTATION
8822#define GET_MNEMONIC_SPELL_CHECKER
8823#include "MipsGenAsmMatcher.inc"
8824
8825bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8826 // Find the appropriate table for this asm variant.
8827 const MatchEntry *Start, *End;
8828 switch (VariantID) {
8829 default: llvm_unreachable("invalid variant!");
8830 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8831 }
8832 // Search the table.
8833 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8834 return MnemonicRange.first != MnemonicRange.second;
8835}
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)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
cl::opt< bool > NoZeroDivCheck
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:2211
#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:1415
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:51
LLVM_ABI StringRef getABIName()
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:325
Op::Description Desc
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:151
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:156
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition Alignment.h:186
@ 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()
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,...