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