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 MCInst TmpInst;
5036
5037 if (hasMips64r2()) {
5038 unsigned FinalOpcode = Mips::NOP;
5039 if (ImmValue == 0)
5040 FinalOpcode = Mips::DROTR;
5041 else if (ImmValue % 32 == 0)
5042 FinalOpcode = Mips::DROTR32;
5043 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5044 if (Inst.getOpcode() == Mips::DROLImm)
5045 FinalOpcode = Mips::DROTR32;
5046 else
5047 FinalOpcode = Mips::DROTR;
5048 } else if (ImmValue >= 33) {
5049 if (Inst.getOpcode() == Mips::DROLImm)
5050 FinalOpcode = Mips::DROTR;
5051 else
5052 FinalOpcode = Mips::DROTR32;
5053 }
5054
5055 uint64_t ShiftValue = ImmValue % 32;
5056 if (Inst.getOpcode() == Mips::DROLImm)
5057 ShiftValue = (32 - ImmValue % 32) % 32;
5058
5059 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5060
5061 return false;
5062 }
5063
5064 if (hasMips64()) {
5065 if (ImmValue == 0) {
5066 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5067 return false;
5068 }
5069
5070 switch (Inst.getOpcode()) {
5071 default:
5072 llvm_unreachable("unexpected instruction opcode");
5073 case Mips::DROLImm:
5074 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5075 FirstShift = Mips::DSLL;
5076 SecondShift = Mips::DSRL32;
5077 }
5078 if (ImmValue == 32) {
5079 FirstShift = Mips::DSLL32;
5080 SecondShift = Mips::DSRL32;
5081 }
5082 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5083 FirstShift = Mips::DSLL32;
5084 SecondShift = Mips::DSRL;
5085 }
5086 break;
5087 case Mips::DRORImm:
5088 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5089 FirstShift = Mips::DSRL;
5090 SecondShift = Mips::DSLL32;
5091 }
5092 if (ImmValue == 32) {
5093 FirstShift = Mips::DSRL32;
5094 SecondShift = Mips::DSLL32;
5095 }
5096 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5097 FirstShift = Mips::DSRL32;
5098 SecondShift = Mips::DSLL;
5099 }
5100 break;
5101 }
5102
5103 ATReg = getATReg(Inst.getLoc());
5104 if (!ATReg)
5105 return true;
5106
5107 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5108 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5109 Inst.getLoc(), STI);
5110 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5111
5112 return false;
5113 }
5114
5115 return true;
5116}
5117
5118bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5119 const MCSubtargetInfo *STI) {
5120 MipsTargetStreamer &TOut = getTargetStreamer();
5121 MCRegister FirstRegOp = Inst.getOperand(0).getReg();
5122 MCRegister SecondRegOp = Inst.getOperand(1).getReg();
5123
5124 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5125 if (FirstRegOp != SecondRegOp)
5126 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::R0, IDLoc, STI);
5127 else
5128 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5129 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::R0, SecondRegOp, IDLoc, STI);
5130
5131 return false;
5132}
5133
5134bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5135 const MCSubtargetInfo *STI) {
5136 MipsTargetStreamer &TOut = getTargetStreamer();
5137 MCRegister ATReg;
5138 MCRegister DstReg = Inst.getOperand(0).getReg();
5139 MCRegister SrcReg = Inst.getOperand(1).getReg();
5140 int32_t ImmValue = Inst.getOperand(2).getImm();
5141
5142 ATReg = getATReg(IDLoc);
5143 if (!ATReg)
5144 return true;
5145
5146 loadImmediate(ImmValue, ATReg, MCRegister(), true, false, IDLoc, Out, STI);
5147
5148 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5149 SrcReg, ATReg, IDLoc, STI);
5150
5151 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5152
5153 return false;
5154}
5155
5156bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5157 const MCSubtargetInfo *STI) {
5158 MipsTargetStreamer &TOut = getTargetStreamer();
5159 MCRegister ATReg;
5160 MCRegister DstReg = Inst.getOperand(0).getReg();
5161 MCRegister SrcReg = Inst.getOperand(1).getReg();
5162 MCRegister TmpReg = Inst.getOperand(2).getReg();
5163
5164 ATReg = getATReg(Inst.getLoc());
5165 if (!ATReg)
5166 return true;
5167
5168 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5169 SrcReg, TmpReg, IDLoc, STI);
5170
5171 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5172
5173 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5174 DstReg, DstReg, 0x1F, IDLoc, STI);
5175
5176 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5177
5178 if (useTraps()) {
5179 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5180 } else {
5181 MCContext &Context = TOut.getContext();
5182 MCSymbol * BrTarget = Context.createTempSymbol();
5183 MCOperand LabelOp =
5185
5186 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5187 if (AssemblerOptions.back()->isReorder())
5188 TOut.emitNop(IDLoc, STI);
5189 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5190
5191 TOut.getStreamer().emitLabel(BrTarget);
5192 }
5193 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5194
5195 return false;
5196}
5197
5198bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5199 const MCSubtargetInfo *STI) {
5200 MipsTargetStreamer &TOut = getTargetStreamer();
5201 MCRegister ATReg;
5202 MCRegister DstReg = Inst.getOperand(0).getReg();
5203 MCRegister SrcReg = Inst.getOperand(1).getReg();
5204 MCRegister TmpReg = Inst.getOperand(2).getReg();
5205
5206 ATReg = getATReg(IDLoc);
5207 if (!ATReg)
5208 return true;
5209
5210 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5211 SrcReg, TmpReg, IDLoc, STI);
5212
5213 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5214 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5215 if (useTraps()) {
5216 TOut.emitRRI(Mips::TNE, ATReg, Mips::R0, 6, IDLoc, STI);
5217 } else {
5218 MCContext &Context = TOut.getContext();
5219 MCSymbol * BrTarget = Context.createTempSymbol();
5220 MCOperand LabelOp =
5222
5223 TOut.emitRRX(Mips::BEQ, ATReg, Mips::R0, LabelOp, IDLoc, STI);
5224 if (AssemblerOptions.back()->isReorder())
5225 TOut.emitNop(IDLoc, STI);
5226 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5227
5228 TOut.getStreamer().emitLabel(BrTarget);
5229 }
5230
5231 return false;
5232}
5233
5234bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5235 const MCSubtargetInfo *STI) {
5236 MipsTargetStreamer &TOut = getTargetStreamer();
5237 MCRegister DstReg = Inst.getOperand(0).getReg();
5238 MCRegister SrcReg = Inst.getOperand(1).getReg();
5239 MCRegister TmpReg = Inst.getOperand(2).getReg();
5240
5241 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5242 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5243
5244 return false;
5245}
5246
5247// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5248// lw $<reg+1>>, offset+4($reg2)'
5249// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5250// sw $<reg+1>>, offset+4($reg2)'
5251// for O32.
5252bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5253 MCStreamer &Out,
5254 const MCSubtargetInfo *STI,
5255 bool IsLoad) {
5256 if (!isABI_O32())
5257 return true;
5258
5259 warnIfNoMacro(IDLoc);
5260
5261 MipsTargetStreamer &TOut = getTargetStreamer();
5262 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5263 MCRegister FirstReg = Inst.getOperand(0).getReg();
5264 MCRegister SecondReg = nextReg(FirstReg);
5265 MCRegister BaseReg = Inst.getOperand(1).getReg();
5266 if (!SecondReg)
5267 return true;
5268
5269 warnIfRegIndexIsAT(FirstReg, IDLoc);
5270
5271 assert(Inst.getOperand(2).isImm() &&
5272 "Offset for load macro is not immediate!");
5273
5274 MCOperand &FirstOffset = Inst.getOperand(2);
5275 signed NextOffset = FirstOffset.getImm() + 4;
5276 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5277
5278 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5279 return true;
5280
5281 // For loads, clobber the base register with the second load instead of the
5282 // first if the BaseReg == FirstReg.
5283 if (FirstReg != BaseReg || !IsLoad) {
5284 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5285 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5286 } else {
5287 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5288 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5289 }
5290
5291 return false;
5292}
5293
5294
5295// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5296// swc1 $<reg>, offset+4($reg2)'
5297// or if little endian to 'swc1 $<reg>, offset($reg2);
5298// swc1 $<reg+1>, offset+4($reg2)'
5299// for Mips1.
5300bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5301 MCStreamer &Out,
5302 const MCSubtargetInfo *STI) {
5303 if (!isABI_O32())
5304 return true;
5305
5306 warnIfNoMacro(IDLoc);
5307
5308 MipsTargetStreamer &TOut = getTargetStreamer();
5309 unsigned Opcode = Mips::SWC1;
5310 MCRegister FirstReg = Inst.getOperand(0).getReg();
5311 MCRegister SecondReg = nextReg(FirstReg);
5312 MCRegister BaseReg = Inst.getOperand(1).getReg();
5313 if (!SecondReg)
5314 return true;
5315
5316 warnIfRegIndexIsAT(FirstReg, IDLoc);
5317
5318 assert(Inst.getOperand(2).isImm() &&
5319 "Offset for macro is not immediate!");
5320
5321 MCOperand &FirstOffset = Inst.getOperand(2);
5322 signed NextOffset = FirstOffset.getImm() + 4;
5323 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5324
5325 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5326 return true;
5327
5328 if (!IsLittleEndian)
5329 std::swap(FirstReg, SecondReg);
5330
5331 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5332 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5333
5334 return false;
5335}
5336
5337bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5338 const MCSubtargetInfo *STI) {
5339 MipsTargetStreamer &TOut = getTargetStreamer();
5340
5341 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5342 assert(Inst.getOperand(0).isReg() &&
5343 Inst.getOperand(1).isReg() &&
5344 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5345
5346 MCRegister DstReg = Inst.getOperand(0).getReg();
5347 MCRegister SrcReg = Inst.getOperand(1).getReg();
5348 MCRegister OpReg = Inst.getOperand(2).getReg();
5349
5350 warnIfNoMacro(IDLoc);
5351
5352 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5353 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5354 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5355 return false;
5356 }
5357
5358 MCRegister Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5359 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5360 return false;
5361}
5362
5363bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5364 const MCSubtargetInfo *STI) {
5365 MipsTargetStreamer &TOut = getTargetStreamer();
5366
5367 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5368 assert(Inst.getOperand(0).isReg() &&
5369 Inst.getOperand(1).isReg() &&
5370 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5371
5372 MCRegister DstReg = Inst.getOperand(0).getReg();
5373 MCRegister SrcReg = Inst.getOperand(1).getReg();
5374 int64_t Imm = Inst.getOperand(2).getImm();
5375
5376 warnIfNoMacro(IDLoc);
5377
5378 if (Imm == 0) {
5379 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5380 return false;
5381 }
5382
5383 if (SrcReg == Mips::R0) {
5384 Warning(IDLoc, "comparison is always false");
5385 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5386 DstReg, SrcReg, SrcReg, IDLoc, STI);
5387 return false;
5388 }
5389
5390 unsigned Opc;
5391 if (Imm > -0x8000 && Imm < 0) {
5392 Imm = -Imm;
5393 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5394 } else {
5395 Opc = Mips::XORi;
5396 }
5397
5398 if (!isUInt<16>(Imm)) {
5399 MCRegister ATReg = getATReg(IDLoc);
5400 if (!ATReg)
5401 return true;
5402
5403 if (loadImmediate(Imm, ATReg, MCRegister(), true, isGP64bit(), IDLoc, Out,
5404 STI))
5405 return true;
5406
5407 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5408 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5409 return false;
5410 }
5411
5412 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5413 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5414 return false;
5415}
5416
5417bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5418 const MCSubtargetInfo *STI) {
5419
5420 MipsTargetStreamer &TOut = getTargetStreamer();
5421
5422 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5423 assert(Inst.getOperand(0).isReg() &&
5424 Inst.getOperand(1).isReg() &&
5425 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5426
5427 MCRegister DstReg = Inst.getOperand(0).getReg();
5428 MCRegister SrcReg = Inst.getOperand(1).getReg();
5429 MCRegister OpReg = Inst.getOperand(2).getReg();
5430
5431 warnIfNoMacro(IDLoc);
5432
5433 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5434 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5435 TOut.emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5436 return false;
5437 }
5438
5439 MCRegister Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5440 TOut.emitRRR(Mips::SLTu, DstReg, Mips::R0, Reg, IDLoc, STI);
5441 return false;
5442}
5443
5444bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5445 const MCSubtargetInfo *STI) {
5446 MipsTargetStreamer &TOut = getTargetStreamer();
5447
5448 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5449 assert(Inst.getOperand(0).isReg() &&
5450 Inst.getOperand(1).isReg() &&
5451 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5452
5453 MCRegister DstReg = Inst.getOperand(0).getReg();
5454 MCRegister SrcReg = Inst.getOperand(1).getReg();
5455 int64_t ImmValue = Inst.getOperand(2).getImm();
5456
5457 warnIfNoMacro(IDLoc);
5458
5459 if (ImmValue == 0) {
5460 TOut.emitRRR(Mips::SLTu, DstReg, Mips::R0, SrcReg, IDLoc, STI);
5461 return false;
5462 }
5463
5464 if (SrcReg == Mips::R0) {
5465 Warning(IDLoc, "comparison is always true");
5466 if (loadImmediate(1, DstReg, MCRegister(), true, false, IDLoc, Out, STI))
5467 return true;
5468 return false;
5469 }
5470
5471 unsigned Opc;
5472 if (ImmValue > -0x8000 && ImmValue < 0) {
5473 ImmValue = -ImmValue;
5474 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5475 } else {
5476 Opc = Mips::XORi;
5477 }
5478
5479 if (isUInt<16>(ImmValue)) {
5480 TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5481 TOut.emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5482 return false;
5483 }
5484
5485 MCRegister ATReg = getATReg(IDLoc);
5486 if (!ATReg)
5487 return true;
5488
5489 if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue), false,
5490 IDLoc, Out, STI))
5491 return true;
5492
5493 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5494 TOut.emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5495 return false;
5496}
5497
5498// Map the DSP accumulator and control register to the corresponding gpr
5499// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5500// do not map the DSP registers contigously to gpr registers.
5501static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5502 switch (Inst.getOpcode()) {
5503 case Mips::MFTLO:
5504 case Mips::MTTLO:
5505 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5506 case Mips::AC0:
5507 return Mips::R0;
5508 case Mips::AC1:
5509 return Mips::R4;
5510 case Mips::AC2:
5511 return Mips::R8;
5512 case Mips::AC3:
5513 return Mips::R12;
5514 default:
5515 llvm_unreachable("Unknown register for 'mttr' alias!");
5516 }
5517 case Mips::MFTHI:
5518 case Mips::MTTHI:
5519 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5520 case Mips::AC0:
5521 return Mips::R1;
5522 case Mips::AC1:
5523 return Mips::R5;
5524 case Mips::AC2:
5525 return Mips::R9;
5526 case Mips::AC3:
5527 return Mips::R13;
5528 default:
5529 llvm_unreachable("Unknown register for 'mttr' alias!");
5530 }
5531 case Mips::MFTACX:
5532 case Mips::MTTACX:
5533 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5534 case Mips::AC0:
5535 return Mips::R2;
5536 case Mips::AC1:
5537 return Mips::R6;
5538 case Mips::AC2:
5539 return Mips::R10;
5540 case Mips::AC3:
5541 return Mips::R14;
5542 default:
5543 llvm_unreachable("Unknown register for 'mttr' alias!");
5544 }
5545 case Mips::MFTDSP:
5546 case Mips::MTTDSP:
5547 return Mips::R16;
5548 default:
5549 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5550 }
5551}
5552
5553// Map the floating point register operand to the corresponding register
5554// operand.
5555static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5556 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg().id()) {
5557 case Mips::F0:
5558 return Mips::R0;
5559 case Mips::F1:
5560 return Mips::R1;
5561 case Mips::F2:
5562 return Mips::R2;
5563 case Mips::F3:
5564 return Mips::R3;
5565 case Mips::F4:
5566 return Mips::R4;
5567 case Mips::F5:
5568 return Mips::R5;
5569 case Mips::F6:
5570 return Mips::R6;
5571 case Mips::F7:
5572 return Mips::R7;
5573 case Mips::F8:
5574 return Mips::R8;
5575 case Mips::F9:
5576 return Mips::R9;
5577 case Mips::F10:
5578 return Mips::R10;
5579 case Mips::F11:
5580 return Mips::R11;
5581 case Mips::F12:
5582 return Mips::R12;
5583 case Mips::F13:
5584 return Mips::R13;
5585 case Mips::F14:
5586 return Mips::R14;
5587 case Mips::F15:
5588 return Mips::R15;
5589 case Mips::F16:
5590 return Mips::R16;
5591 case Mips::F17:
5592 return Mips::R17;
5593 case Mips::F18:
5594 return Mips::R18;
5595 case Mips::F19:
5596 return Mips::R19;
5597 case Mips::F20:
5598 return Mips::R20;
5599 case Mips::F21:
5600 return Mips::R21;
5601 case Mips::F22:
5602 return Mips::R22;
5603 case Mips::F23:
5604 return Mips::R23;
5605 case Mips::F24:
5606 return Mips::R24;
5607 case Mips::F25:
5608 return Mips::R25;
5609 case Mips::F26:
5610 return Mips::R26;
5611 case Mips::F27:
5612 return Mips::R27;
5613 case Mips::F28:
5614 return Mips::GP;
5615 case Mips::F29:
5616 return Mips::SP;
5617 case Mips::F30:
5618 return Mips::FP;
5619 case Mips::F31:
5620 return Mips::RA;
5621 default:
5622 llvm_unreachable("Unknown register for mttc1 alias!");
5623 }
5624}
5625
5626// Map the coprocessor operand the corresponding gpr register operand.
5627static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5628 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg().id()) {
5629 case Mips::COP00:
5630 return Mips::R0;
5631 case Mips::COP01:
5632 return Mips::R1;
5633 case Mips::COP02:
5634 return Mips::R2;
5635 case Mips::COP03:
5636 return Mips::R3;
5637 case Mips::COP04:
5638 return Mips::R4;
5639 case Mips::COP05:
5640 return Mips::R5;
5641 case Mips::COP06:
5642 return Mips::R6;
5643 case Mips::COP07:
5644 return Mips::R7;
5645 case Mips::COP08:
5646 return Mips::R8;
5647 case Mips::COP09:
5648 return Mips::R9;
5649 case Mips::COP010:
5650 return Mips::R10;
5651 case Mips::COP011:
5652 return Mips::R11;
5653 case Mips::COP012:
5654 return Mips::R12;
5655 case Mips::COP013:
5656 return Mips::R13;
5657 case Mips::COP014:
5658 return Mips::R14;
5659 case Mips::COP015:
5660 return Mips::R15;
5661 case Mips::COP016:
5662 return Mips::R16;
5663 case Mips::COP017:
5664 return Mips::R17;
5665 case Mips::COP018:
5666 return Mips::R18;
5667 case Mips::COP019:
5668 return Mips::R19;
5669 case Mips::COP020:
5670 return Mips::R20;
5671 case Mips::COP021:
5672 return Mips::R21;
5673 case Mips::COP022:
5674 return Mips::R22;
5675 case Mips::COP023:
5676 return Mips::R23;
5677 case Mips::COP024:
5678 return Mips::R24;
5679 case Mips::COP025:
5680 return Mips::R25;
5681 case Mips::COP026:
5682 return Mips::R26;
5683 case Mips::COP027:
5684 return Mips::R27;
5685 case Mips::COP028:
5686 return Mips::GP;
5687 case Mips::COP029:
5688 return Mips::SP;
5689 case Mips::COP030:
5690 return Mips::FP;
5691 case Mips::COP031:
5692 return Mips::RA;
5693 default:
5694 llvm_unreachable("Unknown register for mttc0 alias!");
5695 }
5696}
5697
5698/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5699/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5700bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5701 const MCSubtargetInfo *STI) {
5702 MipsTargetStreamer &TOut = getTargetStreamer();
5703 MCRegister rd;
5704 unsigned u = 1;
5705 unsigned sel = 0;
5706 unsigned h = 0;
5707 bool IsMFTR = false;
5708 switch (Inst.getOpcode()) {
5709 case Mips::MFTC0:
5710 IsMFTR = true;
5711 [[fallthrough]];
5712 case Mips::MTTC0:
5713 u = 0;
5714 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5715 sel = Inst.getOperand(2).getImm();
5716 break;
5717 case Mips::MFTGPR:
5718 IsMFTR = true;
5719 [[fallthrough]];
5720 case Mips::MTTGPR:
5721 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5722 break;
5723 case Mips::MFTLO:
5724 case Mips::MFTHI:
5725 case Mips::MFTACX:
5726 case Mips::MFTDSP:
5727 IsMFTR = true;
5728 [[fallthrough]];
5729 case Mips::MTTLO:
5730 case Mips::MTTHI:
5731 case Mips::MTTACX:
5732 case Mips::MTTDSP:
5733 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5734 sel = 1;
5735 break;
5736 case Mips::MFTHC1:
5737 h = 1;
5738 [[fallthrough]];
5739 case Mips::MFTC1:
5740 IsMFTR = true;
5741 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5742 sel = 2;
5743 break;
5744 case Mips::MTTHC1:
5745 h = 1;
5746 [[fallthrough]];
5747 case Mips::MTTC1:
5748 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5749 sel = 2;
5750 break;
5751 case Mips::CFTC1:
5752 IsMFTR = true;
5753 [[fallthrough]];
5754 case Mips::CTTC1:
5755 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5756 sel = 3;
5757 break;
5758 }
5759 MCRegister Op0 = IsMFTR ? Inst.getOperand(0).getReg() : MCRegister(rd);
5760 MCRegister Op1 =
5761 IsMFTR ? MCRegister(rd)
5762 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5763 : Inst.getOperand(0).getReg());
5764
5765 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5766 STI);
5767 return false;
5768}
5769
5770bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5771 const MCSubtargetInfo *STI) {
5772 assert(Inst.getNumOperands() == 3 && "expected three operands");
5773 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5774 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5775
5776 warnIfNoMacro(IDLoc);
5777
5778 MipsTargetStreamer &TOut = getTargetStreamer();
5779 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5780 MCRegister RtReg = Inst.getOperand(0).getReg();
5781 MCRegister BaseReg = Inst.getOperand(1).getReg();
5782 const MCOperand &BaseOp = Inst.getOperand(2);
5783
5784 if (BaseOp.isImm()) {
5785 int64_t ImmValue = BaseOp.getImm();
5786 if (ImmValue == 0) {
5787 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5788 return false;
5789 }
5790 }
5791
5792 MCRegister ATReg = getATReg(IDLoc);
5793 if (!ATReg)
5794 return true;
5795
5796 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5797 return true;
5798
5799 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5800 return false;
5801}
5802
5803unsigned
5804MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5805 const OperandVector &Operands) {
5806 switch (Inst.getOpcode()) {
5807 default:
5808 return Match_Success;
5809 case Mips::DATI:
5810 case Mips::DAHI:
5811 if (static_cast<MipsOperand &>(*Operands[1])
5812 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5813 return Match_Success;
5814 return Match_RequiresSameSrcAndDst;
5815 }
5816}
5817
5818unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5819 switch (Inst.getOpcode()) {
5820 // As described by the MIPSR6 spec, daui must not use the zero operand for
5821 // its source operand.
5822 case Mips::DAUI:
5823 if (Inst.getOperand(1).getReg() == Mips::R0 ||
5824 Inst.getOperand(1).getReg() == Mips::R0_64)
5825 return Match_RequiresNoZeroRegister;
5826 return Match_Success;
5827 // As described by the Mips32r2 spec, the registers Rd and Rs for
5828 // jalr.hb must be different.
5829 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5830 // and registers Rd and Base for microMIPS lwp instruction
5831 case Mips::JALR_HB:
5832 case Mips::JALR_HB64:
5833 case Mips::JALRC_HB_MMR6:
5834 case Mips::JALRC_MMR6:
5835 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5836 return Match_RequiresDifferentSrcAndDst;
5837 return Match_Success;
5838 case Mips::LWP_MM:
5839 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5840 return Match_RequiresDifferentSrcAndDst;
5841 return Match_Success;
5842 case Mips::SYNC:
5843 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5844 return Match_NonZeroOperandForSync;
5845 return Match_Success;
5846 case Mips::MFC0:
5847 case Mips::MTC0:
5848 case Mips::MTC2:
5849 case Mips::MFC2:
5850 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5851 return Match_NonZeroOperandForMTCX;
5852 return Match_Success;
5853 // As described the MIPSR6 spec, the compact branches that compare registers
5854 // must:
5855 // a) Not use the zero register.
5856 // b) Not use the same register twice.
5857 // c) rs < rt for bnec, beqc.
5858 // NB: For this case, the encoding will swap the operands as their
5859 // ordering doesn't matter. GAS performs this transformation too.
5860 // Hence, that constraint does not have to be enforced.
5861 //
5862 // The compact branches that branch iff the signed addition of two registers
5863 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5864 // operand swapping. They do not have restriction of using the zero register.
5865 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5866 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5867 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5868 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5869 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5870 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5871 case Mips::BLEZC64:
5872 case Mips::BGEZC64:
5873 case Mips::BGTZC64:
5874 case Mips::BLTZC64:
5875 case Mips::BEQZC64:
5876 case Mips::BNEZC64:
5877 if (Inst.getOperand(0).getReg() == Mips::R0 ||
5878 Inst.getOperand(0).getReg() == Mips::R0_64)
5879 return Match_RequiresNoZeroRegister;
5880 return Match_Success;
5881 case Mips::BGEC: case Mips::BGEC_MMR6:
5882 case Mips::BLTC: case Mips::BLTC_MMR6:
5883 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5884 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5885 case Mips::BEQC: case Mips::BEQC_MMR6:
5886 case Mips::BNEC: case Mips::BNEC_MMR6:
5887 case Mips::BGEC64:
5888 case Mips::BLTC64:
5889 case Mips::BGEUC64:
5890 case Mips::BLTUC64:
5891 case Mips::BEQC64:
5892 case Mips::BNEC64:
5893 if (Inst.getOperand(0).getReg() == Mips::R0 ||
5894 Inst.getOperand(0).getReg() == Mips::R0_64)
5895 return Match_RequiresNoZeroRegister;
5896 if (Inst.getOperand(1).getReg() == Mips::R0 ||
5897 Inst.getOperand(1).getReg() == Mips::R0_64)
5898 return Match_RequiresNoZeroRegister;
5899 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5900 return Match_RequiresDifferentOperands;
5901 return Match_Success;
5902 case Mips::DINS: {
5903 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5904 "Operands must be immediates for dins!");
5905 const signed Pos = Inst.getOperand(2).getImm();
5906 const signed Size = Inst.getOperand(3).getImm();
5907 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5908 return Match_RequiresPosSizeRange0_32;
5909 return Match_Success;
5910 }
5911 case Mips::DINSM:
5912 case Mips::DINSU: {
5913 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5914 "Operands must be immediates for dinsm/dinsu!");
5915 const signed Pos = Inst.getOperand(2).getImm();
5916 const signed Size = Inst.getOperand(3).getImm();
5917 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5918 return Match_RequiresPosSizeRange33_64;
5919 return Match_Success;
5920 }
5921 case Mips::DEXT: {
5922 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5923 "Operands must be immediates for DEXTM!");
5924 const signed Pos = Inst.getOperand(2).getImm();
5925 const signed Size = Inst.getOperand(3).getImm();
5926 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5927 return Match_RequiresPosSizeUImm6;
5928 return Match_Success;
5929 }
5930 case Mips::DEXTM:
5931 case Mips::DEXTU: {
5932 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5933 "Operands must be immediates for dextm/dextu!");
5934 const signed Pos = Inst.getOperand(2).getImm();
5935 const signed Size = Inst.getOperand(3).getImm();
5936 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5937 return Match_RequiresPosSizeRange33_64;
5938 return Match_Success;
5939 }
5940 case Mips::CRC32B: case Mips::CRC32CB:
5941 case Mips::CRC32H: case Mips::CRC32CH:
5942 case Mips::CRC32W: case Mips::CRC32CW:
5943 case Mips::CRC32D: case Mips::CRC32CD:
5944 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5945 return Match_RequiresSameSrcAndDst;
5946 return Match_Success;
5947 }
5948
5949 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5950 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5951 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5952 return Match_NoFCCRegisterForCurrentISA;
5953
5954 return Match_Success;
5955
5956}
5957
5960 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5961 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5962 if (ErrorLoc == SMLoc())
5963 return Loc;
5964 return ErrorLoc;
5965 }
5966 return Loc;
5967}
5968
5969bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5971 MCStreamer &Out,
5972 uint64_t &ErrorInfo,
5973 bool MatchingInlineAsm) {
5974 MCInst Inst;
5975 unsigned MatchResult =
5976 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5977
5978 switch (MatchResult) {
5979 case Match_Success:
5980 if (processInstruction(Inst, IDLoc, Out, STI))
5981 return true;
5982 return false;
5983 case Match_MissingFeature:
5984 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5985 return true;
5986 case Match_InvalidTiedOperand:
5987 Error(IDLoc, "operand must match destination register");
5988 return true;
5989 case Match_InvalidOperand: {
5990 SMLoc ErrorLoc = IDLoc;
5991 if (ErrorInfo != ~0ULL) {
5992 if (ErrorInfo >= Operands.size())
5993 return Error(IDLoc, "too few operands for instruction");
5994
5995 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5996 if (Operands[ErrorInfo]->isMem())
5997 ErrorLoc = static_cast<MipsOperand &>(*Operands[ErrorInfo])
5998 .getMemBase()
5999 ->getStartLoc();
6000 if (ErrorLoc == SMLoc())
6001 ErrorLoc = IDLoc;
6002 }
6003
6004 return Error(ErrorLoc, "invalid operand for instruction");
6005 }
6006 case Match_NonZeroOperandForSync:
6007 return Error(IDLoc,
6008 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6009 case Match_NonZeroOperandForMTCX:
6010 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
6011 case Match_MnemonicFail:
6012 return Error(IDLoc, "invalid instruction");
6013 case Match_RequiresDifferentSrcAndDst:
6014 return Error(IDLoc, "source and destination must be different");
6015 case Match_RequiresDifferentOperands:
6016 return Error(IDLoc, "registers must be different");
6017 case Match_RequiresNoZeroRegister:
6018 return Error(IDLoc, "invalid operand ($zero) for instruction");
6019 case Match_RequiresSameSrcAndDst:
6020 return Error(IDLoc, "source and destination must match");
6021 case Match_NoFCCRegisterForCurrentISA:
6022 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6023 "non-zero fcc register doesn't exist in current ISA level");
6024 case Match_Immz:
6025 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
6026 case Match_UImm1_0:
6027 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6028 "expected 1-bit unsigned immediate");
6029 case Match_UImm2_0:
6030 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6031 "expected 2-bit unsigned immediate");
6032 case Match_UImm2_1:
6033 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6034 "expected immediate in range 1 .. 4");
6035 case Match_UImm3_0:
6036 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6037 "expected 3-bit unsigned immediate");
6038 case Match_UImm4_0:
6039 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6040 "expected 4-bit unsigned immediate");
6041 case Match_SImm4_0:
6042 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6043 "expected 4-bit signed immediate");
6044 case Match_UImm5_0:
6045 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6046 "expected 5-bit unsigned immediate");
6047 case Match_SImm5_0:
6048 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6049 "expected 5-bit signed immediate");
6050 case Match_UImm5_1:
6051 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6052 "expected immediate in range 1 .. 32");
6053 case Match_UImm5_32:
6054 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6055 "expected immediate in range 32 .. 63");
6056 case Match_UImm5_33:
6057 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6058 "expected immediate in range 33 .. 64");
6059 case Match_UImm5_0_Report_UImm6:
6060 // This is used on UImm5 operands that have a corresponding UImm5_32
6061 // operand to avoid confusing the user.
6062 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6063 "expected 6-bit unsigned immediate");
6064 case Match_ConstantMemOffset:
6065 if (ErrorInfo < Operands.size() &&
6066 !static_cast<MipsOperand &>(*Operands[ErrorInfo]).isConstantImm())
6067 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6068 "expected immediate operand kind");
6069 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6070 "immediate operand value out of range");
6071 case Match_UImm5_Lsl2:
6072 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6073 "expected both 7-bit unsigned immediate and multiple of 4");
6074 case Match_UImmRange2_64:
6075 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6076 "expected immediate in range 2 .. 64");
6077 case Match_UImm6_0:
6078 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6079 "expected 6-bit unsigned immediate");
6080 case Match_UImm6_Lsl2:
6081 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6082 "expected both 8-bit unsigned immediate and multiple of 4");
6083 case Match_SImm6_0:
6084 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6085 "expected 6-bit signed immediate");
6086 case Match_UImm7_0:
6087 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6088 "expected 7-bit unsigned immediate");
6089 case Match_UImm7_N1:
6090 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6091 "expected immediate in range -1 .. 126");
6092 case Match_SImm7_Lsl2:
6093 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6094 "expected both 9-bit signed immediate and multiple of 4");
6095 case Match_UImm8_0:
6096 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6097 "expected 8-bit unsigned immediate");
6098 case Match_UImm10_0:
6099 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6100 "expected 10-bit unsigned immediate");
6101 case Match_SImm10_0:
6102 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6103 "expected 10-bit signed immediate");
6104 case Match_SImm11_0:
6105 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6106 "expected 11-bit signed immediate");
6107 case Match_UImm16:
6108 case Match_UImm16_Relaxed:
6109 case Match_UImm16_AltRelaxed:
6110 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6111 "expected 16-bit unsigned immediate");
6112 case Match_SImm16:
6113 case Match_SImm16_Relaxed:
6114 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6115 "expected 16-bit signed immediate");
6116 case Match_SImm18_Lsl3:
6117 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6118 "expected both 18-bit signed immediate and multiple of 8");
6119 case Match_SImm19_Lsl2:
6120 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6121 "expected both 19-bit signed immediate and multiple of 4");
6122 case Match_UImm20_0:
6123 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6124 "expected 20-bit unsigned immediate");
6125 case Match_UImm26_0:
6126 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6127 "expected 26-bit unsigned immediate");
6128 case Match_SImm32:
6129 case Match_SImm32_Relaxed:
6130 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6131 "expected 32-bit signed immediate");
6132 case Match_UImm32_Coerced:
6133 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6134 "expected 32-bit immediate");
6135 case Match_MemSImm9:
6136 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6137 "expected memory with 9-bit signed offset");
6138 case Match_MemSImm10:
6139 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6140 "expected memory with 10-bit signed offset");
6141 case Match_MemSImm10Lsl1:
6142 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6143 "expected memory with 11-bit signed offset and multiple of 2");
6144 case Match_MemSImm10Lsl2:
6145 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6146 "expected memory with 12-bit signed offset and multiple of 4");
6147 case Match_MemSImm10Lsl3:
6148 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6149 "expected memory with 13-bit signed offset and multiple of 8");
6150 case Match_MemSImm11:
6151 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6152 "expected memory with 11-bit signed offset");
6153 case Match_MemSImm12:
6154 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6155 "expected memory with 12-bit signed offset");
6156 case Match_MemSImm16:
6157 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6158 "expected memory with 16-bit signed offset");
6159 case Match_MemSImmPtr:
6160 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6161 "expected memory with 32-bit signed offset");
6162 case Match_RequiresPosSizeRange0_32: {
6163 SMLoc ErrorStart = Operands[3]->getStartLoc();
6164 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6165 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6166 SMRange(ErrorStart, ErrorEnd));
6167 }
6168 case Match_RequiresPosSizeUImm6: {
6169 SMLoc ErrorStart = Operands[3]->getStartLoc();
6170 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6171 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6172 SMRange(ErrorStart, ErrorEnd));
6173 }
6174 case Match_RequiresPosSizeRange33_64: {
6175 SMLoc ErrorStart = Operands[3]->getStartLoc();
6176 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6177 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6178 SMRange(ErrorStart, ErrorEnd));
6179 }
6180 }
6181
6182 llvm_unreachable("Implement any new match types added!");
6183}
6184
6185void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6186 if (RegIndex && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6187 Warning(Loc, "used $at (currently $" + Twine(RegIndex.id()) +
6188 ") without \".set noat\"");
6189}
6190
6191void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6192 if (!AssemblerOptions.back()->isMacro())
6193 Warning(Loc, "macro instruction expanded into multiple instructions");
6194}
6195
6196void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6197 const OperandVector &Operands) {
6198 assert(
6199 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
6200 "Unexpected instruction!");
6201 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6202 MCRegister NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6203 Inst.addOperand(MCOperand::createReg(NextReg));
6204 static_cast<MipsOperand &>(*Operands[4]).addPtrRegOperands(Inst, 1);
6205 static_cast<MipsOperand &>(*Operands[2]).addImmOperands(Inst, 1);
6206}
6207
6208void
6209MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6210 SMRange Range, bool ShowColors) {
6211 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6212 Range, SMFixIt(Range, FixMsg),
6213 ShowColors);
6214}
6215
6216int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6217 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
6218 bool IsDeprecated;
6219 int Index = MIPS_MC::getCPURegisterIndex(Name, MRI, ABI.getRegAltNameIndex(),
6220 &IsDeprecated);
6221 if (IsDeprecated) {
6222 MCRegister Reg = MRI.getRegClass(Mips::GPR32RegClassID).getRegister(Index);
6223 AsmToken RegTok = getLexer().peekTok();
6224 StringRef FixedName =
6225 MipsInstPrinter::getRegisterName(Reg, ABI.getRegAltNameIndex());
6226 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6227 "Did you mean $" + FixedName + "?",
6228 RegTok.getLocRange());
6229 }
6230 return Index;
6231}
6232
6233int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6234 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
6235 MCRegister Reg = MIPS_MC::matchRegisterName(Name, MRI, Mips::HWRegsRegClassID,
6236 Mips::RegAliasName);
6237 return Reg ? MRI.getEncodingValue(Reg) : -1;
6238}
6239
6240int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6241 if (Name[0] == 'f') {
6242 StringRef NumString = Name.substr(1);
6243 unsigned IntVal;
6244 if (NumString.getAsInteger(10, IntVal))
6245 return -1; // This is not an integer.
6246 if (IntVal > 31) // Maximum index for fpu register.
6247 return -1;
6248 return IntVal;
6249 }
6250 return -1;
6251}
6252
6253int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6254 if (Name.starts_with("fcc")) {
6255 StringRef NumString = Name.substr(3);
6256 unsigned IntVal;
6257 if (NumString.getAsInteger(10, IntVal))
6258 return -1; // This is not an integer.
6259 if (IntVal > 7) // There are only 8 fcc registers.
6260 return -1;
6261 return IntVal;
6262 }
6263 return -1;
6264}
6265
6266int MipsAsmParser::matchACRegisterName(StringRef Name) {
6267 if (Name.starts_with("ac")) {
6268 StringRef NumString = Name.substr(2);
6269 unsigned IntVal;
6270 if (NumString.getAsInteger(10, IntVal))
6271 return -1; // This is not an integer.
6272 if (IntVal > 3) // There are only 3 acc registers.
6273 return -1;
6274 return IntVal;
6275 }
6276 return -1;
6277}
6278
6279int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6280 unsigned IntVal;
6281
6282 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6283 return -1;
6284
6285 if (IntVal > 31)
6286 return -1;
6287
6288 return IntVal;
6289}
6290
6291int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6292 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
6293 MCRegister Reg = MIPS_MC::matchRegisterName(
6294 Name, MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6295 return Reg ? MRI.getEncodingValue(Reg) : -1;
6296}
6297
6298bool MipsAsmParser::canUseATReg() {
6299 return AssemblerOptions.back()->getATRegIndex() != 0;
6300}
6301
6302MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6303 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6304 if (ATIndex == 0) {
6305 reportParseError(Loc,
6306 "pseudo-instruction requires $at, which is not available");
6307 return 0;
6308 }
6309 MCRegister AT = getReg(
6310 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6311 return AT;
6312}
6313
6314MCRegister MipsAsmParser::getReg(int RC, int RegNo) {
6315 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6316}
6317
6318// Recognize relocation specifiers so the common parser can handle arithmetic
6319// around them, such as %lo(8) + symbol.
6320bool MipsAsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
6321 if (getLexer().isNot(AsmToken::Percent))
6322 return getParser().parsePrimaryExpr(Res, EndLoc);
6323 Res = parseRelocExpr();
6324 EndLoc = getLexer().getLoc();
6325 return !Res;
6326}
6327
6328// Parse an expression with optional, possibly nested relocation specifiers.
6329// The opening parentheses are required, unlike the GAS form "%lo foo".
6330const MCExpr *MipsAsmParser::parseRelocExpr() {
6331 auto getOp = [](StringRef Op) {
6332 return StringSwitch<Mips::Specifier>(Op)
6333 .Case("call16", Mips::S_GOT_CALL)
6334 .Case("call_hi", Mips::S_CALL_HI16)
6335 .Case("call_lo", Mips::S_CALL_LO16)
6336 .Case("dtprel_hi", Mips::S_DTPREL_HI)
6337 .Case("dtprel_lo", Mips::S_DTPREL_LO)
6338 .Case("got", Mips::S_GOT)
6339 .Case("got_disp", Mips::S_GOT_DISP)
6340 .Case("got_hi", Mips::S_GOT_HI16)
6341 .Case("got_lo", Mips::S_GOT_LO16)
6342 .Case("got_ofst", Mips::S_GOT_OFST)
6343 .Case("got_page", Mips::S_GOT_PAGE)
6344 .Case("gottprel", Mips::S_GOTTPREL)
6345 .Case("gp_rel", Mips::S_GPREL)
6346 .Case("hi", Mips::S_HI)
6347 .Case("higher", Mips::S_HIGHER)
6348 .Case("highest", Mips::S_HIGHEST)
6349 .Case("lo", Mips::S_LO)
6350 .Case("neg", Mips::S_NEG)
6351 .Case("pcrel_hi", Mips::S_PCREL_HI16)
6352 .Case("pcrel_lo", Mips::S_PCREL_LO16)
6353 .Case("tlsgd", Mips::S_TLSGD)
6354 .Case("tlsldm", Mips::S_TLSLDM)
6355 .Case("tprel_hi", Mips::S_TPREL_HI)
6356 .Case("tprel_lo", Mips::S_TPREL_LO)
6357 .Default(Mips::S_None);
6358 };
6359
6360 MCAsmParser &Parser = getParser();
6361 StringRef Name;
6362 const MCExpr *Res = nullptr;
6364 while (parseOptionalToken(AsmToken::Percent)) {
6365 if (Parser.parseIdentifier(Name) ||
6366 Parser.parseToken(AsmToken::LParen, "expected '('"))
6367 return nullptr;
6368 auto Op = getOp(Name);
6369 if (Op == Mips::S_None) {
6370 Error(Parser.getTok().getLoc(), "invalid relocation operator");
6371 return nullptr;
6372 }
6373 Ops.push_back(Op);
6374 }
6375 if (Parser.parseExpression(Res))
6376 return nullptr;
6377 while (Ops.size()) {
6378 if (Parser.parseToken(AsmToken::RParen, "expected ')'"))
6379 return nullptr;
6380 Res = MCSpecifierExpr::create(Res, Ops.pop_back_val(), getContext());
6381 }
6382 return Res;
6383}
6384
6385bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6386 MCAsmParser &Parser = getParser();
6387 LLVM_DEBUG(dbgs() << "parseOperand\n");
6388
6389 // Check if the current operand has a custom associated parser, if so, try to
6390 // custom parse the operand, or fallback to the general approach.
6391 // Setting the third parameter to true tells the parser to keep parsing even
6392 // if the operands are not supported with the current feature set. In this
6393 // case, the instruction matcher will output a "instruction requires a CPU
6394 // feature not currently enabled" error. If this were false, the parser would
6395 // stop here and output a less useful "invalid operand" error.
6396 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic, true);
6397 if (Res.isSuccess())
6398 return false;
6399 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6400 // there was a match, but an error occurred, in which case, just return that
6401 // the operand parsing failed.
6402 if (Res.isFailure())
6403 return true;
6404
6405 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6406
6407 switch (getLexer().getKind()) {
6408 case AsmToken::Dollar: {
6409 // Parse the register.
6410 SMLoc S = Parser.getTok().getLoc();
6411
6412 // Almost all registers have been parsed by custom parsers. There is only
6413 // one exception to this. $zero (and it's alias $0) will reach this point
6414 // for div, divu, and similar instructions because it is not an operand
6415 // to the instruction definition but an explicit register. Special case
6416 // this situation for now.
6417 if (!parseAnyRegister(Operands).isNoMatch())
6418 return false;
6419
6420 // Maybe it is a symbol reference.
6421 StringRef Identifier;
6422 if (Parser.parseIdentifier(Identifier))
6423 return true;
6424
6425 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6426 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
6427 // Otherwise create a symbol reference.
6428 const MCExpr *SymRef = MCSymbolRefExpr::create(Sym, getContext());
6429
6430 Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this));
6431 return false;
6432 }
6433 default: {
6434 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6435 const MCExpr *Expr = parseRelocExpr();
6436 if (!Expr)
6437 return true;
6438 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6439 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6440 return false;
6441 }
6442 } // switch(getLexer().getKind())
6443 return true;
6444}
6445
6446bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
6447 SMLoc &EndLoc) {
6448 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6449}
6450
6451ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6452 SMLoc &EndLoc) {
6454 ParseStatus Res = parseAnyRegister(Operands);
6455 if (Res.isSuccess()) {
6456 assert(Operands.size() == 1);
6457 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6458 StartLoc = Operand.getStartLoc();
6459 EndLoc = Operand.getEndLoc();
6460
6461 // AFAIK, we only support numeric registers and named GPR's in CFI
6462 // directives.
6463 // Don't worry about eating tokens before failing. Using an unrecognised
6464 // register is a parse error.
6465 if (Operand.isGPRAsmReg()) {
6466 // Resolve to GPR32 or GPR64 appropriately.
6467 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6468 }
6469
6470 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6471 }
6472
6473 assert(Operands.size() == 0);
6474 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6475}
6476
6477const MCExpr *MipsAsmParser::parseMemOffset() {
6478 // An omitted expression, as in ($sp), denotes zero.
6479 if (getLexer().is(AsmToken::LParen) &&
6480 getLexer().peekTok().is(AsmToken::Dollar))
6482
6483 const MCExpr *Offset;
6484 if (getParser().parseExpression(Offset))
6485 return nullptr;
6486 int64_t Value;
6487 if (Offset->evaluateAsAbsolute(Value))
6489 return Offset;
6490}
6491
6492ParseStatus MipsAsmParser::parseMemOffsetOperand(OperandVector &Operands) {
6493 SMLoc S = getLexer().getLoc();
6494 const MCExpr *Offset = parseMemOffset();
6495 if (!Offset)
6496 return ParseStatus::Failure;
6497
6498 SMLoc E = getLexer().getLoc();
6499 Operands.push_back(MipsOperand::CreateImm(Offset, S, E, *this));
6500
6501 if (getLexer().is(AsmToken::LParen)) {
6502 StringRef Mnemonic = static_cast<MipsOperand &>(*Operands[0]).getToken();
6503 return parseParenSuffix(Mnemonic, Operands) ? ParseStatus::Failure
6505 }
6506
6507 // A memory address without an explicit base uses $zero.
6508 // FIXME: GAS can expand arbitrary symbolic addresses. Ideally, a pseudo
6509 // instruction should handle these instead of supplying a default $zero base.
6510 Operands.push_back(MipsOperand::CreateToken("(", E, *this));
6511 Operands.push_back(MipsOperand::createGPRReg(
6512 0, "0", getContext().getRegisterInfo(), E, E, *this));
6513 Operands.push_back(MipsOperand::CreateToken(")", E, *this));
6514 return ParseStatus::Success;
6515}
6516
6517ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6518 MCAsmParser &Parser = getParser();
6519 SMLoc S = Parser.getTok().getLoc();
6520 const MCExpr *Address = parseMemOffset();
6521 if (!Address)
6522 return ParseStatus::Failure;
6523
6524 SMLoc E = Parser.getTok().getLoc();
6525 if (getLexer().isNot(AsmToken::LParen)) {
6526 Operands.push_back(MipsOperand::CreateImm(Address, S, E, *this));
6527 return ParseStatus::Success;
6528 }
6529
6530 Parser.Lex(); // Eat '('.
6531 ParseStatus Result = parseAnyRegister(Operands);
6532 if (!Result.isSuccess())
6533 return Result;
6534 if (Parser.parseRParen())
6535 return ParseStatus::Failure;
6536
6537 std::unique_ptr<MipsOperand> Base(
6538 static_cast<MipsOperand *>(Operands.back().release()));
6539 Operands.pop_back();
6540 E = Base->getEndLoc();
6541 Operands.push_back(
6542 MipsOperand::CreateMem(std::move(Base), Address, S, E, *this));
6543 return ParseStatus::Success;
6544}
6545
6546bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6547 MCAsmParser &Parser = getParser();
6548 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6549 if (!Sym)
6550 return false;
6551
6552 SMLoc S = Parser.getTok().getLoc();
6553 if (Sym->isVariable()) {
6554 const MCExpr *Expr = Sym->getVariableValue();
6555 if (Expr->getKind() == MCExpr::SymbolRef) {
6556 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6557 StringRef DefSymbol = Ref->getSymbol().getName();
6558 if (DefSymbol.starts_with("$")) {
6559 ParseStatus Res =
6560 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6561 if (Res.isSuccess()) {
6562 Parser.Lex();
6563 return true;
6564 }
6565 if (Res.isFailure())
6566 llvm_unreachable("Should never fail");
6567 }
6568 }
6569 } else if (Sym->isUndefined()) {
6570 // If symbol is unset, it might be created in the `parseSetAssignment`
6571 // routine as an alias for a numeric register name.
6572 // Lookup in the aliases list.
6573 auto Entry = RegisterSets.find(Sym->getName());
6574 if (Entry != RegisterSets.end()) {
6575 ParseStatus Res =
6576 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6577 if (Res.isSuccess()) {
6578 Parser.Lex();
6579 return true;
6580 }
6581 }
6582 }
6583
6584 return false;
6585}
6586
6587ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6588 OperandVector &Operands, StringRef Identifier, SMLoc S) {
6589 int Index = matchCPURegisterName(Identifier);
6590 if (Index != -1) {
6591 Operands.push_back(MipsOperand::createGPRReg(
6592 Index, Identifier, getContext().getRegisterInfo(), S,
6593 getLexer().getLoc(), *this));
6594 return ParseStatus::Success;
6595 }
6596
6597 Index = matchHWRegsRegisterName(Identifier);
6598 if (Index != -1) {
6599 Operands.push_back(MipsOperand::createHWRegsReg(
6600 Index, Identifier, getContext().getRegisterInfo(), S,
6601 getLexer().getLoc(), *this));
6602 return ParseStatus::Success;
6603 }
6604
6605 Index = matchFPURegisterName(Identifier);
6606 if (Index != -1) {
6607 Operands.push_back(MipsOperand::createFGRReg(
6608 Index, Identifier, getContext().getRegisterInfo(), S,
6609 getLexer().getLoc(), *this));
6610 return ParseStatus::Success;
6611 }
6612
6613 Index = matchFCCRegisterName(Identifier);
6614 if (Index != -1) {
6615 Operands.push_back(MipsOperand::createFCCReg(
6616 Index, Identifier, getContext().getRegisterInfo(), S,
6617 getLexer().getLoc(), *this));
6618 return ParseStatus::Success;
6619 }
6620
6621 Index = matchACRegisterName(Identifier);
6622 if (Index != -1) {
6623 Operands.push_back(MipsOperand::createACCReg(
6624 Index, Identifier, getContext().getRegisterInfo(), S,
6625 getLexer().getLoc(), *this));
6626 return ParseStatus::Success;
6627 }
6628
6629 Index = matchMSA128RegisterName(Identifier);
6630 if (Index != -1) {
6631 Operands.push_back(MipsOperand::createMSA128Reg(
6632 Index, Identifier, getContext().getRegisterInfo(), S,
6633 getLexer().getLoc(), *this));
6634 return ParseStatus::Success;
6635 }
6636
6637 Index = matchMSA128CtrlRegisterName(Identifier);
6638 if (Index != -1) {
6639 Operands.push_back(MipsOperand::createMSACtrlReg(
6640 Index, Identifier, getContext().getRegisterInfo(), S,
6641 getLexer().getLoc(), *this));
6642 return ParseStatus::Success;
6643 }
6644
6645 return ParseStatus::NoMatch;
6646}
6647
6648ParseStatus
6649MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6650 const AsmToken &Token, SMLoc S) {
6651 if (Token.is(AsmToken::Identifier)) {
6652 LLVM_DEBUG(dbgs() << ".. identifier\n");
6653 StringRef Identifier = Token.getIdentifier();
6654 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6655 }
6656 if (Token.is(AsmToken::Integer)) {
6657 LLVM_DEBUG(dbgs() << ".. integer\n");
6658 int64_t RegNum = Token.getIntVal();
6659 if (RegNum < 0 || RegNum > 31) {
6660 // Show the error, but treat invalid register
6661 // number as a normal one to continue parsing
6662 // and catch other possible errors.
6663 Error(getLexer().getLoc(), "invalid register number");
6664 }
6665 Operands.push_back(MipsOperand::createNumericReg(
6666 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6667 Token.getLoc(), *this));
6668 return ParseStatus::Success;
6669 }
6670
6671 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6672
6673 return ParseStatus::NoMatch;
6674}
6675
6676ParseStatus
6677MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6678 auto Token = getLexer().peekTok(false);
6679 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6680}
6681
6682ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6683 MCAsmParser &Parser = getParser();
6684 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6685
6686 auto Token = Parser.getTok();
6687
6688 SMLoc S = Token.getLoc();
6689
6690 if (Token.isNot(AsmToken::Dollar)) {
6691 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6692 if (Token.is(AsmToken::Identifier)) {
6693 if (searchSymbolAlias(Operands))
6694 return ParseStatus::Success;
6695 }
6696 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6697 return ParseStatus::NoMatch;
6698 }
6699 LLVM_DEBUG(dbgs() << ".. $\n");
6700
6701 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6702 if (Res.isSuccess()) {
6703 Parser.Lex(); // $
6704 Parser.Lex(); // identifier
6705 }
6706 return Res;
6707}
6708
6709ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6710 MCAsmParser &Parser = getParser();
6711 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6712
6713 SMLoc S = getLexer().getLoc();
6714
6715 // Registers are a valid target and have priority over symbols.
6716 ParseStatus Res = parseAnyRegister(Operands);
6717 if (!Res.isNoMatch())
6718 return Res;
6719
6720 // Integers and expressions are acceptable
6721 const MCExpr *Expr = nullptr;
6722 if (Parser.parseExpression(Expr)) {
6723 // We have no way of knowing if a symbol was consumed so we must ParseFail
6724 return ParseStatus::Failure;
6725 }
6726 Operands.push_back(
6727 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6728 return ParseStatus::Success;
6729}
6730
6731ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) {
6732 MCAsmParser &Parser = getParser();
6733 const MCExpr *IdVal;
6734 // If the first token is '$' we may have register operand. We have to reject
6735 // cases where it is not a register. Complicating the matter is that
6736 // register names are not reserved across all ABIs.
6737 // Peek past the dollar to see if it's a register name for this ABI.
6738 SMLoc S = Parser.getTok().getLoc();
6739 if (Parser.getTok().is(AsmToken::Dollar)) {
6740 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6743 }
6744 if (getParser().parseExpression(IdVal))
6745 return ParseStatus::Failure;
6746 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6747 if (!MCE)
6748 return ParseStatus::NoMatch;
6749 int64_t Val = MCE->getValue();
6750 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6751 Operands.push_back(MipsOperand::CreateImm(
6752 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6753 return ParseStatus::Success;
6754}
6755
6756ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6757 MCAsmParser &Parser = getParser();
6759 MCRegister Reg;
6760 MCRegister PrevReg;
6761 bool RegRange = false;
6763
6764 if (Parser.getTok().isNot(AsmToken::Dollar))
6765 return ParseStatus::Failure;
6766
6767 SMLoc S = Parser.getTok().getLoc();
6768 while (parseAnyRegister(TmpOperands).isSuccess()) {
6769 SMLoc E = getLexer().getLoc();
6770 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*TmpOperands.back());
6771 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6772 if (RegRange) {
6773 // Remove last register operand because registers from register range
6774 // should be inserted first.
6775 if ((isGP64bit() && Reg == Mips::RA_64) ||
6776 (!isGP64bit() && Reg == Mips::RA)) {
6777 Regs.push_back(Reg);
6778 } else {
6779 MCRegister TmpReg = PrevReg + 1;
6780 while (TmpReg <= Reg) {
6781 if ((((TmpReg < Mips::R16) || (TmpReg > Mips::R23)) &&
6782 !isGP64bit()) ||
6783 (((TmpReg < Mips::R16_64) || (TmpReg > Mips::R23_64)) &&
6784 isGP64bit()))
6785 return Error(E, "invalid register operand");
6786
6787 PrevReg = TmpReg;
6788 Regs.push_back(TmpReg);
6789 TmpReg = TmpReg.id() + 1;
6790 }
6791 }
6792
6793 RegRange = false;
6794 } else {
6795 if (!PrevReg.isValid() &&
6796 ((isGP64bit() && (Reg != Mips::R16_64) && (Reg != Mips::RA_64)) ||
6797 (!isGP64bit() && (Reg != Mips::R16) && (Reg != Mips::RA))))
6798 return Error(E, "$16 or $31 expected");
6799 if (!(((Reg == Mips::FP || Reg == Mips::RA ||
6800 (Reg >= Mips::R16 && Reg <= Mips::R23)) &&
6801 !isGP64bit()) ||
6802 ((Reg == Mips::FP_64 || Reg == Mips::RA_64 ||
6803 (Reg >= Mips::R16_64 && Reg <= Mips::R23_64)) &&
6804 isGP64bit())))
6805 return Error(E, "invalid register operand");
6806 if (PrevReg.isValid() && (Reg != PrevReg + 1) &&
6807 ((Reg != Mips::FP && Reg != Mips::RA && !isGP64bit()) ||
6808 (Reg != Mips::FP_64 && Reg != Mips::RA_64 && isGP64bit())))
6809 return Error(E, "consecutive register numbers expected");
6810
6811 Regs.push_back(Reg);
6812 }
6813
6814 if (Parser.getTok().is(AsmToken::Minus))
6815 RegRange = true;
6816
6817 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6818 !Parser.getTok().isNot(AsmToken::Comma))
6819 return Error(E, "',' or '-' expected");
6820
6821 Lex(); // Consume comma or minus
6822 if (Parser.getTok().isNot(AsmToken::Dollar))
6823 break;
6824
6825 PrevReg = Reg;
6826 }
6827
6828 SMLoc E = Parser.getTok().getLoc();
6829 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6830 return parseMemOffsetOperand(Operands);
6831}
6832
6833/// Sometimes (i.e. load/stores) the operand may be followed immediately by
6834/// either this.
6835/// ::= '(', register, ')'
6836/// handle it before we iterate so we don't get tripped up by the lack of
6837/// a comma.
6838bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6839 MCAsmParser &Parser = getParser();
6840 if (getLexer().is(AsmToken::LParen)) {
6841 Operands.push_back(
6842 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6843 Parser.Lex();
6844 if (parseOperand(Operands, Name)) {
6845 SMLoc Loc = getLexer().getLoc();
6846 return Error(Loc, "unexpected token in argument list");
6847 }
6848 if (Parser.getTok().isNot(AsmToken::RParen)) {
6849 SMLoc Loc = getLexer().getLoc();
6850 return Error(Loc, "unexpected token, expected ')'");
6851 }
6852 Operands.push_back(
6853 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6854 Parser.Lex();
6855 }
6856 return false;
6857}
6858
6859/// Sometimes (i.e. in MSA) the operand may be followed immediately by
6860/// either one of these.
6861/// ::= '[', register, ']'
6862/// ::= '[', integer, ']'
6863/// handle it before we iterate so we don't get tripped up by the lack of
6864/// a comma.
6865bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6867 MCAsmParser &Parser = getParser();
6868 if (getLexer().is(AsmToken::LBrac)) {
6869 Operands.push_back(
6870 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6871 Parser.Lex();
6872 if (parseOperand(Operands, Name)) {
6873 SMLoc Loc = getLexer().getLoc();
6874 return Error(Loc, "unexpected token in argument list");
6875 }
6876 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6877 SMLoc Loc = getLexer().getLoc();
6878 return Error(Loc, "unexpected token, expected ']'");
6879 }
6880 Operands.push_back(
6881 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6882 Parser.Lex();
6883 }
6884 return false;
6885}
6886
6887static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6888 unsigned VariantID = 0);
6889
6890bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6891 const MCParsedAsmOperand &Op2) const {
6892 // This target-overriden function exists to maintain current behaviour for
6893 // e.g.
6894 // dahi $3, $3, 0x5678
6895 // as tested in test/MC/Mips/mips64r6/valid.s.
6896 // FIXME: Should this test actually fail with an error? If so, then remove
6897 // this overloaded method.
6898 if (!Op1.isReg() || !Op2.isReg())
6899 return true;
6900 return Op1.getReg() == Op2.getReg();
6901}
6902
6903bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6904 SMLoc NameLoc, OperandVector &Operands) {
6905 MCAsmParser &Parser = getParser();
6906 LLVM_DEBUG(dbgs() << "parseInstruction\n");
6907
6908 // We have reached first instruction, module directive are now forbidden.
6909 getTargetStreamer().forbidModuleDirective();
6910
6911 // Check if we have valid mnemonic
6912 if (!mnemonicIsValid(Name, 0)) {
6913 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6914 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6915 return Error(NameLoc, "unknown instruction" + Suggestion);
6916 }
6917 // First operand in MCInst is instruction mnemonic.
6918 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6919
6920 // Read the remaining operands.
6921 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6922 do {
6923 bool IsFirstOperand = Operands.size() == 1;
6924 // Parse and remember the operand.
6925 if (parseOperand(Operands, Name)) {
6926 SMLoc Loc = getLexer().getLoc();
6927 return Error(Loc, "unexpected token in argument list");
6928 }
6929 // Parse suffixes before we iterate. First operands handle parentheses
6930 // through their custom parser.
6931 if (getLexer().is(AsmToken::LBrac)) {
6932 if (parseBracketSuffix(Name, Operands))
6933 return true;
6934 } else if (!IsFirstOperand && getLexer().is(AsmToken::LParen) &&
6935 parseParenSuffix(Name, Operands))
6936 return true;
6937 } while (parseOptionalToken(AsmToken::Comma));
6938 }
6939 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6940 SMLoc Loc = getLexer().getLoc();
6941 return Error(Loc, "unexpected token in argument list");
6942 }
6943 Parser.Lex(); // Consume the EndOfStatement.
6944 return false;
6945}
6946
6947// FIXME: Given that these have the same name, these should both be
6948// consistent on affecting the Parser.
6949bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
6950 SMLoc Loc = getLexer().getLoc();
6951 return Error(Loc, ErrorMsg);
6952}
6953
6954bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
6955 return Error(Loc, ErrorMsg);
6956}
6957
6958bool MipsAsmParser::parseSetNoAtDirective() {
6959 MCAsmParser &Parser = getParser();
6960 // Line should look like: ".set noat".
6961
6962 // Set the $at register to $0.
6963 AssemblerOptions.back()->setATRegIndex(0);
6964
6965 Parser.Lex(); // Eat "noat".
6966
6967 // If this is not the end of the statement, report an error.
6968 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6969 reportParseError("unexpected token, expected end of statement");
6970 return false;
6971 }
6972
6973 getTargetStreamer().emitDirectiveSetNoAt();
6974 Parser.Lex(); // Consume the EndOfStatement.
6975 return false;
6976}
6977
6978bool MipsAsmParser::parseSetAtDirective() {
6979 // Line can be: ".set at", which sets $at to $1
6980 // or ".set at=$reg", which sets $at to $reg.
6981 MCAsmParser &Parser = getParser();
6982 Parser.Lex(); // Eat "at".
6983
6984 if (getLexer().is(AsmToken::EndOfStatement)) {
6985 // No register was specified, so we set $at to $1.
6986 AssemblerOptions.back()->setATRegIndex(1);
6987
6988 getTargetStreamer().emitDirectiveSetAt();
6989 Parser.Lex(); // Consume the EndOfStatement.
6990 return false;
6991 }
6992
6993 if (getLexer().isNot(AsmToken::Equal)) {
6994 reportParseError("unexpected token, expected equals sign");
6995 return false;
6996 }
6997 Parser.Lex(); // Eat "=".
6998
6999 if (getLexer().isNot(AsmToken::Dollar)) {
7000 if (getLexer().is(AsmToken::EndOfStatement)) {
7001 reportParseError("no register specified");
7002 return false;
7003 } else {
7004 reportParseError("unexpected token, expected dollar sign '$'");
7005 return false;
7006 }
7007 }
7008 Parser.Lex(); // Eat "$".
7009
7010 // Find out what "reg" is.
7011 unsigned AtRegNo;
7012 const AsmToken &Reg = Parser.getTok();
7013 if (Reg.is(AsmToken::Identifier)) {
7014 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7015 } else if (Reg.is(AsmToken::Integer)) {
7016 AtRegNo = Reg.getIntVal();
7017 } else {
7018 reportParseError("unexpected token, expected identifier or integer");
7019 return false;
7020 }
7021
7022 // Check if $reg is a valid register. If it is, set $at to $reg.
7023 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7024 reportParseError("invalid register");
7025 return false;
7026 }
7027 Parser.Lex(); // Eat "reg".
7028
7029 // If this is not the end of the statement, report an error.
7030 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7031 reportParseError("unexpected token, expected end of statement");
7032 return false;
7033 }
7034
7035 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7036
7037 Parser.Lex(); // Consume the EndOfStatement.
7038 return false;
7039}
7040
7041bool MipsAsmParser::parseSetReorderDirective() {
7042 MCAsmParser &Parser = getParser();
7043 Parser.Lex();
7044 // If this is not the end of the statement, report an error.
7045 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7046 reportParseError("unexpected token, expected end of statement");
7047 return false;
7048 }
7049 AssemblerOptions.back()->setReorder();
7050 getTargetStreamer().emitDirectiveSetReorder();
7051 Parser.Lex(); // Consume the EndOfStatement.
7052 return false;
7053}
7054
7055bool MipsAsmParser::parseSetNoReorderDirective() {
7056 MCAsmParser &Parser = getParser();
7057 Parser.Lex();
7058 // If this is not the end of the statement, report an error.
7059 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7060 reportParseError("unexpected token, expected end of statement");
7061 return false;
7062 }
7063 AssemblerOptions.back()->setNoReorder();
7064 getTargetStreamer().emitDirectiveSetNoReorder();
7065 Parser.Lex(); // Consume the EndOfStatement.
7066 return false;
7067}
7068
7069bool MipsAsmParser::parseSetMacroDirective() {
7070 MCAsmParser &Parser = getParser();
7071 Parser.Lex();
7072 // If this is not the end of the statement, report an error.
7073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7074 reportParseError("unexpected token, expected end of statement");
7075 return false;
7076 }
7077 AssemblerOptions.back()->setMacro();
7078 getTargetStreamer().emitDirectiveSetMacro();
7079 Parser.Lex(); // Consume the EndOfStatement.
7080 return false;
7081}
7082
7083bool MipsAsmParser::parseSetNoMacroDirective() {
7084 MCAsmParser &Parser = getParser();
7085 Parser.Lex();
7086 // If this is not the end of the statement, report an error.
7087 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7088 reportParseError("unexpected token, expected end of statement");
7089 return false;
7090 }
7091 if (AssemblerOptions.back()->isReorder()) {
7092 reportParseError("`noreorder' must be set before `nomacro'");
7093 return false;
7094 }
7095 AssemblerOptions.back()->setNoMacro();
7096 getTargetStreamer().emitDirectiveSetNoMacro();
7097 Parser.Lex(); // Consume the EndOfStatement.
7098 return false;
7099}
7100
7101bool MipsAsmParser::parseSetMsaDirective() {
7102 MCAsmParser &Parser = getParser();
7103 Parser.Lex();
7104
7105 // If this is not the end of the statement, report an error.
7106 if (getLexer().isNot(AsmToken::EndOfStatement))
7107 return reportParseError("unexpected token, expected end of statement");
7108
7109 setFeatureBits(Mips::FeatureMSA, "msa");
7110 getTargetStreamer().emitDirectiveSetMsa();
7111 return false;
7112}
7113
7114bool MipsAsmParser::parseSetNoMsaDirective() {
7115 MCAsmParser &Parser = getParser();
7116 Parser.Lex();
7117
7118 // If this is not the end of the statement, report an error.
7119 if (getLexer().isNot(AsmToken::EndOfStatement))
7120 return reportParseError("unexpected token, expected end of statement");
7121
7122 clearFeatureBits(Mips::FeatureMSA, "msa");
7123 getTargetStreamer().emitDirectiveSetNoMsa();
7124 return false;
7125}
7126
7127bool MipsAsmParser::parseSetNoDspDirective() {
7128 MCAsmParser &Parser = getParser();
7129 Parser.Lex(); // Eat "nodsp".
7130
7131 // If this is not the end of the statement, report an error.
7132 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7133 reportParseError("unexpected token, expected end of statement");
7134 return false;
7135 }
7136
7137 clearFeatureBits(Mips::FeatureDSP, "dsp");
7138 getTargetStreamer().emitDirectiveSetNoDsp();
7139 return false;
7140}
7141
7142bool MipsAsmParser::parseSetNoMips3DDirective() {
7143 MCAsmParser &Parser = getParser();
7144 Parser.Lex(); // Eat "nomips3d".
7145
7146 // If this is not the end of the statement, report an error.
7147 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7148 reportParseError("unexpected token, expected end of statement");
7149 return false;
7150 }
7151
7152 clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7153 getTargetStreamer().emitDirectiveSetNoMips3D();
7154 return false;
7155}
7156
7157bool MipsAsmParser::parseSetMips16Directive() {
7158 MCAsmParser &Parser = getParser();
7159 Parser.Lex(); // Eat "mips16".
7160
7161 // If this is not the end of the statement, report an error.
7162 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7163 reportParseError("unexpected token, expected end of statement");
7164 return false;
7165 }
7166
7167 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7168 setFeatureBits(Mips::FeatureMips16, "mips16");
7169 getTargetStreamer().emitDirectiveSetMips16();
7170 Parser.Lex(); // Consume the EndOfStatement.
7171 return false;
7172}
7173
7174bool MipsAsmParser::parseSetNoMips16Directive() {
7175 MCAsmParser &Parser = getParser();
7176 Parser.Lex(); // Eat "nomips16".
7177
7178 // If this is not the end of the statement, report an error.
7179 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7180 reportParseError("unexpected token, expected end of statement");
7181 return false;
7182 }
7183
7184 clearFeatureBits(Mips::FeatureMips16, "mips16");
7185 getTargetStreamer().emitDirectiveSetNoMips16();
7186 Parser.Lex(); // Consume the EndOfStatement.
7187 return false;
7188}
7189
7190bool MipsAsmParser::parseSetFpDirective() {
7191 MCAsmParser &Parser = getParser();
7193 // Line can be: .set fp=32
7194 // .set fp=xx
7195 // .set fp=64
7196 Parser.Lex(); // Eat fp token
7197 AsmToken Tok = Parser.getTok();
7198 if (Tok.isNot(AsmToken::Equal)) {
7199 reportParseError("unexpected token, expected equals sign '='");
7200 return false;
7201 }
7202 Parser.Lex(); // Eat '=' token.
7203 Tok = Parser.getTok();
7204
7205 if (!parseFpABIValue(FpAbiVal, ".set"))
7206 return false;
7207
7208 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7209 reportParseError("unexpected token, expected end of statement");
7210 return false;
7211 }
7212 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7213 Parser.Lex(); // Consume the EndOfStatement.
7214 return false;
7215}
7216
7217bool MipsAsmParser::parseSetOddSPRegDirective() {
7218 MCAsmParser &Parser = getParser();
7219
7220 Parser.Lex(); // Eat "oddspreg".
7221 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7222 reportParseError("unexpected token, expected end of statement");
7223 return false;
7224 }
7225
7226 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7227 getTargetStreamer().emitDirectiveSetOddSPReg();
7228 return false;
7229}
7230
7231bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7232 MCAsmParser &Parser = getParser();
7233
7234 Parser.Lex(); // Eat "nooddspreg".
7235 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7236 reportParseError("unexpected token, expected end of statement");
7237 return false;
7238 }
7239
7240 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7241 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7242 return false;
7243}
7244
7245bool MipsAsmParser::parseSetMtDirective() {
7246 MCAsmParser &Parser = getParser();
7247 Parser.Lex(); // Eat "mt".
7248
7249 // If this is not the end of the statement, report an error.
7250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7251 reportParseError("unexpected token, expected end of statement");
7252 return false;
7253 }
7254
7255 setFeatureBits(Mips::FeatureMT, "mt");
7256 getTargetStreamer().emitDirectiveSetMt();
7257 Parser.Lex(); // Consume the EndOfStatement.
7258 return false;
7259}
7260
7261bool MipsAsmParser::parseSetNoMtDirective() {
7262 MCAsmParser &Parser = getParser();
7263 Parser.Lex(); // Eat "nomt".
7264
7265 // If this is not the end of the statement, report an error.
7266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7267 reportParseError("unexpected token, expected end of statement");
7268 return false;
7269 }
7270
7271 clearFeatureBits(Mips::FeatureMT, "mt");
7272
7273 getTargetStreamer().emitDirectiveSetNoMt();
7274 Parser.Lex(); // Consume the EndOfStatement.
7275 return false;
7276}
7277
7278bool MipsAsmParser::parseSetNoCRCDirective() {
7279 MCAsmParser &Parser = getParser();
7280 Parser.Lex(); // Eat "nocrc".
7281
7282 // If this is not the end of the statement, report an error.
7283 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7284 reportParseError("unexpected token, expected end of statement");
7285 return false;
7286 }
7287
7288 clearFeatureBits(Mips::FeatureCRC, "crc");
7289
7290 getTargetStreamer().emitDirectiveSetNoCRC();
7291 Parser.Lex(); // Consume the EndOfStatement.
7292 return false;
7293}
7294
7295bool MipsAsmParser::parseSetNoVirtDirective() {
7296 MCAsmParser &Parser = getParser();
7297 Parser.Lex(); // Eat "novirt".
7298
7299 // If this is not the end of the statement, report an error.
7300 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7301 reportParseError("unexpected token, expected end of statement");
7302 return false;
7303 }
7304
7305 clearFeatureBits(Mips::FeatureVirt, "virt");
7306
7307 getTargetStreamer().emitDirectiveSetNoVirt();
7308 Parser.Lex(); // Consume the EndOfStatement.
7309 return false;
7310}
7311
7312bool MipsAsmParser::parseSetNoGINVDirective() {
7313 MCAsmParser &Parser = getParser();
7314 Parser.Lex(); // Eat "noginv".
7315
7316 // If this is not the end of the statement, report an error.
7317 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7318 reportParseError("unexpected token, expected end of statement");
7319 return false;
7320 }
7321
7322 clearFeatureBits(Mips::FeatureGINV, "ginv");
7323
7324 getTargetStreamer().emitDirectiveSetNoGINV();
7325 Parser.Lex(); // Consume the EndOfStatement.
7326 return false;
7327}
7328
7329bool MipsAsmParser::parseSetNoEVADirective() {
7330 MCAsmParser &Parser = getParser();
7331 Parser.Lex(); // Eat "noeva".
7332
7333 // If this is not the end of the statement, report an error.
7334 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7335 reportParseError("unexpected token, expected end of statement");
7336 return false;
7337 }
7338
7339 clearFeatureBits(Mips::FeatureEVA, "eva");
7340
7341 getTargetStreamer().emitDirectiveSetNoEVA();
7342 Parser.Lex(); // Consume the EndOfStatement.
7343 return false;
7344}
7345
7346bool MipsAsmParser::parseSetPopDirective() {
7347 MCAsmParser &Parser = getParser();
7348 SMLoc Loc = getLexer().getLoc();
7349
7350 Parser.Lex();
7351 if (getLexer().isNot(AsmToken::EndOfStatement))
7352 return reportParseError("unexpected token, expected end of statement");
7353
7354 // Always keep an element on the options "stack" to prevent the user
7355 // from changing the initial options. This is how we remember them.
7356 if (AssemblerOptions.size() == 2)
7357 return reportParseError(Loc, ".set pop with no .set push");
7358
7359 MCSubtargetInfo &STI = copySTI();
7360 AssemblerOptions.pop_back();
7361 setAvailableFeatures(
7362 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7363 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7364
7365 getTargetStreamer().emitDirectiveSetPop();
7366 return false;
7367}
7368
7369bool MipsAsmParser::parseSetPushDirective() {
7370 MCAsmParser &Parser = getParser();
7371 Parser.Lex();
7372 if (getLexer().isNot(AsmToken::EndOfStatement))
7373 return reportParseError("unexpected token, expected end of statement");
7374
7375 // Create a copy of the current assembler options environment and push it.
7376 AssemblerOptions.push_back(
7377 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7378
7379 getTargetStreamer().emitDirectiveSetPush();
7380 return false;
7381}
7382
7383bool MipsAsmParser::parseSetSoftFloatDirective() {
7384 MCAsmParser &Parser = getParser();
7385 Parser.Lex();
7386 if (getLexer().isNot(AsmToken::EndOfStatement))
7387 return reportParseError("unexpected token, expected end of statement");
7388
7389 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7390 getTargetStreamer().emitDirectiveSetSoftFloat();
7391 return false;
7392}
7393
7394bool MipsAsmParser::parseSetHardFloatDirective() {
7395 MCAsmParser &Parser = getParser();
7396 Parser.Lex();
7397 if (getLexer().isNot(AsmToken::EndOfStatement))
7398 return reportParseError("unexpected token, expected end of statement");
7399
7400 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7401 getTargetStreamer().emitDirectiveSetHardFloat();
7402 return false;
7403}
7404
7405bool MipsAsmParser::parseSetAssignment() {
7406 StringRef Name;
7407 MCAsmParser &Parser = getParser();
7408
7409 if (Parser.parseIdentifier(Name))
7410 return reportParseError("expected identifier after .set");
7411
7412 if (getLexer().isNot(AsmToken::Comma))
7413 return reportParseError("unexpected token, expected comma");
7414 Lex(); // Eat comma
7415
7416 if (getLexer().is(AsmToken::Dollar) &&
7417 getLexer().peekTok().is(AsmToken::Integer)) {
7418 // Parse assignment of a numeric register:
7419 // .set r1,$1
7420 Parser.Lex(); // Eat $.
7421 RegisterSets[Name] = Parser.getTok();
7422 Parser.Lex(); // Eat identifier.
7423 getContext().getOrCreateSymbol(Name);
7424 return false;
7425 }
7426
7427 MCSymbol *Sym;
7428 const MCExpr *Value;
7429 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7430 Parser, Sym, Value))
7431 return true;
7432 getStreamer().emitAssignment(Sym, Value);
7433
7434 return false;
7435}
7436
7437bool MipsAsmParser::parseSetMips0Directive() {
7438 MCAsmParser &Parser = getParser();
7439 Parser.Lex();
7440 if (getLexer().isNot(AsmToken::EndOfStatement))
7441 return reportParseError("unexpected token, expected end of statement");
7442
7443 // Reset assembler options to their initial values.
7444 MCSubtargetInfo &STI = copySTI();
7445 setAvailableFeatures(
7446 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7447 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7448 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7449
7450 getTargetStreamer().emitDirectiveSetMips0();
7451 return false;
7452}
7453
7454bool MipsAsmParser::parseSetArchDirective() {
7455 MCAsmParser &Parser = getParser();
7456 Parser.Lex();
7457 if (getLexer().isNot(AsmToken::Equal))
7458 return reportParseError("unexpected token, expected equals sign");
7459
7460 Parser.Lex();
7461 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7462 if (Arch.empty())
7463 return reportParseError("expected arch identifier");
7464
7465 StringRef ArchFeatureName =
7466 StringSwitch<StringRef>(Arch)
7467 .Case("mips1", "mips1")
7468 .Case("mips2", "mips2")
7469 .Case("mips3", "mips3")
7470 .Case("mips4", "mips4")
7471 .Case("mips5", "mips5")
7472 .Case("mips32", "mips32")
7473 .Case("mips32r2", "mips32r2")
7474 .Case("mips32r3", "mips32r3")
7475 .Case("mips32r5", "mips32r5")
7476 .Case("mips32r6", "mips32r6")
7477 .Case("mips64", "mips64")
7478 .Case("mips64r2", "mips64r2")
7479 .Case("mips64r3", "mips64r3")
7480 .Case("mips64r5", "mips64r5")
7481 .Case("mips64r6", "mips64r6")
7482 .Case("octeon", "cnmips")
7483 .Case("octeon+", "cnmipsp")
7484 .Case("r4000", "mips3") // This is an implementation of Mips3.
7485 .Default("");
7486
7487 if (ArchFeatureName.empty())
7488 return reportParseError("unsupported architecture");
7489
7490 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7491 return reportParseError("mips64r6 does not support microMIPS");
7492
7493 selectArch(ArchFeatureName);
7494 getTargetStreamer().emitDirectiveSetArch(Arch);
7495 return false;
7496}
7497
7498bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7499 MCAsmParser &Parser = getParser();
7500 Parser.Lex();
7501 if (getLexer().isNot(AsmToken::EndOfStatement))
7502 return reportParseError("unexpected token, expected end of statement");
7503
7504 switch (Feature) {
7505 default:
7506 llvm_unreachable("Unimplemented feature");
7507 case Mips::FeatureMips3D:
7508 setFeatureBits(Mips::FeatureMips3D, "mips3d");
7509 getTargetStreamer().emitDirectiveSetMips3D();
7510 break;
7511 case Mips::FeatureDSP:
7512 setFeatureBits(Mips::FeatureDSP, "dsp");
7513 getTargetStreamer().emitDirectiveSetDsp();
7514 break;
7515 case Mips::FeatureDSPR2:
7516 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7517 getTargetStreamer().emitDirectiveSetDspr2();
7518 break;
7519 case Mips::FeatureMicroMips:
7520 clearFeatureBits(Mips::FeatureMips16, "mips16");
7521 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7522 getTargetStreamer().emitDirectiveSetMicroMips();
7523 break;
7524 case Mips::FeatureMips1:
7525 selectArch("mips1");
7526 getTargetStreamer().emitDirectiveSetMips1();
7527 break;
7528 case Mips::FeatureMips2:
7529 selectArch("mips2");
7530 getTargetStreamer().emitDirectiveSetMips2();
7531 break;
7532 case Mips::FeatureMips3:
7533 selectArch("mips3");
7534 getTargetStreamer().emitDirectiveSetMips3();
7535 break;
7536 case Mips::FeatureMips4:
7537 selectArch("mips4");
7538 getTargetStreamer().emitDirectiveSetMips4();
7539 break;
7540 case Mips::FeatureMips5:
7541 selectArch("mips5");
7542 getTargetStreamer().emitDirectiveSetMips5();
7543 break;
7544 case Mips::FeatureMips32:
7545 selectArch("mips32");
7546 getTargetStreamer().emitDirectiveSetMips32();
7547 break;
7548 case Mips::FeatureMips32r2:
7549 selectArch("mips32r2");
7550 getTargetStreamer().emitDirectiveSetMips32R2();
7551 break;
7552 case Mips::FeatureMips32r3:
7553 selectArch("mips32r3");
7554 getTargetStreamer().emitDirectiveSetMips32R3();
7555 break;
7556 case Mips::FeatureMips32r5:
7557 selectArch("mips32r5");
7558 getTargetStreamer().emitDirectiveSetMips32R5();
7559 break;
7560 case Mips::FeatureMips32r6:
7561 selectArch("mips32r6");
7562 getTargetStreamer().emitDirectiveSetMips32R6();
7563 break;
7564 case Mips::FeatureMips64:
7565 selectArch("mips64");
7566 getTargetStreamer().emitDirectiveSetMips64();
7567 break;
7568 case Mips::FeatureMips64r2:
7569 selectArch("mips64r2");
7570 getTargetStreamer().emitDirectiveSetMips64R2();
7571 break;
7572 case Mips::FeatureMips64r3:
7573 selectArch("mips64r3");
7574 getTargetStreamer().emitDirectiveSetMips64R3();
7575 break;
7576 case Mips::FeatureMips64r5:
7577 selectArch("mips64r5");
7578 getTargetStreamer().emitDirectiveSetMips64R5();
7579 break;
7580 case Mips::FeatureMips64r6:
7581 selectArch("mips64r6");
7582 getTargetStreamer().emitDirectiveSetMips64R6();
7583 break;
7584 case Mips::FeatureCRC:
7585 setFeatureBits(Mips::FeatureCRC, "crc");
7586 getTargetStreamer().emitDirectiveSetCRC();
7587 break;
7588 case Mips::FeatureVirt:
7589 setFeatureBits(Mips::FeatureVirt, "virt");
7590 getTargetStreamer().emitDirectiveSetVirt();
7591 break;
7592 case Mips::FeatureGINV:
7593 setFeatureBits(Mips::FeatureGINV, "ginv");
7594 getTargetStreamer().emitDirectiveSetGINV();
7595 break;
7596 case Mips::FeatureEVA:
7597 setFeatureBits(Mips::FeatureEVA, "eva");
7598 getTargetStreamer().emitDirectiveSetEVA();
7599 break;
7600 }
7601 return false;
7602}
7603
7604bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7605 MCAsmParser &Parser = getParser();
7606 if (getLexer().isNot(AsmToken::Comma)) {
7607 SMLoc Loc = getLexer().getLoc();
7608 return Error(Loc, ErrorStr);
7609 }
7610
7611 Parser.Lex(); // Eat the comma.
7612 return true;
7613}
7614
7615// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7616// In this class, it is only used for .cprestore.
7617// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7618// MipsTargetELFStreamer and MipsAsmParser.
7619bool MipsAsmParser::isPicAndNotNxxAbi() {
7620 return inPicMode() && !(isABI_N32() || isABI_N64());
7621}
7622
7623bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7625 ParseStatus Res = parseAnyRegister(Reg);
7626 if (Res.isNoMatch() || Res.isFailure()) {
7627 reportParseError("expected register");
7628 return false;
7629 }
7630
7631 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7632 if (!RegOpnd.isGPRAsmReg()) {
7633 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7634 return false;
7635 }
7636
7637 // If this is not the end of the statement, report an error.
7638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7639 reportParseError("unexpected token, expected end of statement");
7640 return false;
7641 }
7642 getParser().Lex(); // Consume the EndOfStatement.
7643
7644 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7645 return false;
7646}
7647
7648bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7649 if (AssemblerOptions.back()->isReorder())
7650 Warning(Loc, ".cpload should be inside a noreorder section");
7651
7652 if (inMips16Mode()) {
7653 reportParseError(".cpload is not supported in Mips16 mode");
7654 return false;
7655 }
7656
7658 ParseStatus Res = parseAnyRegister(Reg);
7659 if (Res.isNoMatch() || Res.isFailure()) {
7660 reportParseError("expected register containing function address");
7661 return false;
7662 }
7663
7664 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7665 if (!RegOpnd.isGPRAsmReg()) {
7666 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7667 return false;
7668 }
7669
7670 // If this is not the end of the statement, report an error.
7671 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7672 reportParseError("unexpected token, expected end of statement");
7673 return false;
7674 }
7675
7676 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7677 return false;
7678}
7679
7680bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7681 if (!isABI_N32() && !isABI_N64()) {
7682 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7683 return false;
7684 }
7685
7687 ParseStatus Res = parseAnyRegister(Reg);
7688 if (Res.isNoMatch() || Res.isFailure()) {
7689 reportParseError("expected register containing global pointer");
7690 return false;
7691 }
7692
7693 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7694 if (!RegOpnd.isGPRAsmReg()) {
7695 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7696 return false;
7697 }
7698
7699 // If this is not the end of the statement, report an error.
7700 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7701 reportParseError("unexpected token, expected end of statement");
7702 return false;
7703 }
7704 getParser().Lex(); // Consume the EndOfStatement.
7705
7706 MCRegister NewReg = RegOpnd.getGPR32Reg();
7707 if (IsPicEnabled)
7708 GPReg = NewReg;
7709
7710 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7711 return false;
7712}
7713
7714bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7715 MCAsmParser &Parser = getParser();
7716
7717 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7718 // is used in non-PIC mode.
7719
7720 if (inMips16Mode()) {
7721 reportParseError(".cprestore is not supported in Mips16 mode");
7722 return false;
7723 }
7724
7725 // Get the stack offset value.
7726 const MCExpr *StackOffset;
7727 int64_t StackOffsetVal;
7728 if (Parser.parseExpression(StackOffset)) {
7729 reportParseError("expected stack offset value");
7730 return false;
7731 }
7732
7733 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7734 reportParseError("stack offset is not an absolute expression");
7735 return false;
7736 }
7737
7738 if (StackOffsetVal < 0) {
7739 Warning(Loc, ".cprestore with negative stack offset has no effect");
7740 IsCpRestoreSet = false;
7741 } else {
7742 IsCpRestoreSet = true;
7743 CpRestoreOffset = StackOffsetVal;
7744 }
7745
7746 // If this is not the end of the statement, report an error.
7747 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7748 reportParseError("unexpected token, expected end of statement");
7749 return false;
7750 }
7751
7752 if (!getTargetStreamer().emitDirectiveCpRestore(
7753 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7754 return true;
7755 Parser.Lex(); // Consume the EndOfStatement.
7756 return false;
7757}
7758
7759bool MipsAsmParser::parseDirectiveCPSetup() {
7760 MCAsmParser &Parser = getParser();
7761 unsigned Save;
7762 bool SaveIsReg = true;
7763
7765 ParseStatus Res = parseAnyRegister(TmpReg);
7766 if (Res.isNoMatch()) {
7767 reportParseError("expected register containing function address");
7768 return false;
7769 }
7770
7771 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7772 if (!FuncRegOpnd.isGPRAsmReg()) {
7773 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7774 return false;
7775 }
7776
7777 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7778 TmpReg.clear();
7779
7780 if (!eatComma("unexpected token, expected comma"))
7781 return true;
7782
7783 Res = parseAnyRegister(TmpReg);
7784 if (Res.isNoMatch()) {
7785 const MCExpr *OffsetExpr;
7786 int64_t OffsetVal;
7787 SMLoc ExprLoc = getLexer().getLoc();
7788
7789 if (Parser.parseExpression(OffsetExpr) ||
7790 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7791 reportParseError(ExprLoc, "expected save register or stack offset");
7792 return false;
7793 }
7794
7795 Save = OffsetVal;
7796 SaveIsReg = false;
7797 } else {
7798 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7799 if (!SaveOpnd.isGPRAsmReg()) {
7800 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7801 return false;
7802 }
7803 Save = SaveOpnd.getGPR32Reg().id();
7804 }
7805
7806 if (!eatComma("unexpected token, expected comma"))
7807 return true;
7808
7809 const MCExpr *Expr;
7810 if (Parser.parseExpression(Expr)) {
7811 reportParseError("expected expression");
7812 return false;
7813 }
7814
7815 if (Expr->getKind() != MCExpr::SymbolRef) {
7816 reportParseError("expected symbol");
7817 return false;
7818 }
7819 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7820
7821 CpSaveLocation = Save;
7822 CpSaveLocationIsRegister = SaveIsReg;
7823
7824 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7825 SaveIsReg);
7826 return false;
7827}
7828
7829bool MipsAsmParser::parseDirectiveCPReturn() {
7830 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7831 CpSaveLocationIsRegister);
7832 return false;
7833}
7834
7835bool MipsAsmParser::parseDirectiveNaN() {
7836 MCAsmParser &Parser = getParser();
7837 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7838 const AsmToken &Tok = Parser.getTok();
7839
7840 if (Tok.getString() == "2008") {
7841 Parser.Lex();
7842 getTargetStreamer().emitDirectiveNaN2008();
7843 return false;
7844 } else if (Tok.getString() == "legacy") {
7845 Parser.Lex();
7846 getTargetStreamer().emitDirectiveNaNLegacy();
7847 return false;
7848 }
7849 }
7850 // If we don't recognize the option passed to the .nan
7851 // directive (e.g. no option or unknown option), emit an error.
7852 reportParseError("invalid option in .nan directive");
7853 return false;
7854}
7855
7856bool MipsAsmParser::parseDirectiveSet() {
7857 const AsmToken &Tok = getParser().getTok();
7858 StringRef IdVal = Tok.getString();
7859 SMLoc Loc = Tok.getLoc();
7860
7861 if (IdVal == "noat")
7862 return parseSetNoAtDirective();
7863 if (IdVal == "at")
7864 return parseSetAtDirective();
7865 if (IdVal == "arch")
7866 return parseSetArchDirective();
7867 if (IdVal == "bopt") {
7868 Warning(Loc, "'bopt' feature is unsupported");
7869 getParser().Lex();
7870 return false;
7871 }
7872 if (IdVal == "nobopt") {
7873 // We're already running in nobopt mode, so nothing to do.
7874 getParser().Lex();
7875 return false;
7876 }
7877 if (IdVal == "fp")
7878 return parseSetFpDirective();
7879 if (IdVal == "oddspreg")
7880 return parseSetOddSPRegDirective();
7881 if (IdVal == "nooddspreg")
7882 return parseSetNoOddSPRegDirective();
7883 if (IdVal == "pop")
7884 return parseSetPopDirective();
7885 if (IdVal == "push")
7886 return parseSetPushDirective();
7887 if (IdVal == "reorder")
7888 return parseSetReorderDirective();
7889 if (IdVal == "noreorder")
7890 return parseSetNoReorderDirective();
7891 if (IdVal == "macro")
7892 return parseSetMacroDirective();
7893 if (IdVal == "nomacro")
7894 return parseSetNoMacroDirective();
7895 if (IdVal == "mips16")
7896 return parseSetMips16Directive();
7897 if (IdVal == "nomips16")
7898 return parseSetNoMips16Directive();
7899 if (IdVal == "nomicromips") {
7900 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7901 getTargetStreamer().emitDirectiveSetNoMicroMips();
7902 getParser().eatToEndOfStatement();
7903 return false;
7904 }
7905 if (IdVal == "micromips") {
7906 if (hasMips64r6()) {
7907 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7908 return false;
7909 }
7910 return parseSetFeature(Mips::FeatureMicroMips);
7911 }
7912 if (IdVal == "mips0")
7913 return parseSetMips0Directive();
7914 if (IdVal == "mips1")
7915 return parseSetFeature(Mips::FeatureMips1);
7916 if (IdVal == "mips2")
7917 return parseSetFeature(Mips::FeatureMips2);
7918 if (IdVal == "mips3")
7919 return parseSetFeature(Mips::FeatureMips3);
7920 if (IdVal == "mips4")
7921 return parseSetFeature(Mips::FeatureMips4);
7922 if (IdVal == "mips5")
7923 return parseSetFeature(Mips::FeatureMips5);
7924 if (IdVal == "mips32")
7925 return parseSetFeature(Mips::FeatureMips32);
7926 if (IdVal == "mips32r2")
7927 return parseSetFeature(Mips::FeatureMips32r2);
7928 if (IdVal == "mips32r3")
7929 return parseSetFeature(Mips::FeatureMips32r3);
7930 if (IdVal == "mips32r5")
7931 return parseSetFeature(Mips::FeatureMips32r5);
7932 if (IdVal == "mips32r6")
7933 return parseSetFeature(Mips::FeatureMips32r6);
7934 if (IdVal == "mips64")
7935 return parseSetFeature(Mips::FeatureMips64);
7936 if (IdVal == "mips64r2")
7937 return parseSetFeature(Mips::FeatureMips64r2);
7938 if (IdVal == "mips64r3")
7939 return parseSetFeature(Mips::FeatureMips64r3);
7940 if (IdVal == "mips64r5")
7941 return parseSetFeature(Mips::FeatureMips64r5);
7942 if (IdVal == "mips64r6") {
7943 if (inMicroMipsMode()) {
7944 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7945 return false;
7946 }
7947 return parseSetFeature(Mips::FeatureMips64r6);
7948 }
7949 if (IdVal == "dsp")
7950 return parseSetFeature(Mips::FeatureDSP);
7951 if (IdVal == "dspr2")
7952 return parseSetFeature(Mips::FeatureDSPR2);
7953 if (IdVal == "nodsp")
7954 return parseSetNoDspDirective();
7955 if (IdVal == "mips3d")
7956 return parseSetFeature(Mips::FeatureMips3D);
7957 if (IdVal == "nomips3d")
7958 return parseSetNoMips3DDirective();
7959 if (IdVal == "msa")
7960 return parseSetMsaDirective();
7961 if (IdVal == "nomsa")
7962 return parseSetNoMsaDirective();
7963 if (IdVal == "mt")
7964 return parseSetMtDirective();
7965 if (IdVal == "nomt")
7966 return parseSetNoMtDirective();
7967 if (IdVal == "softfloat")
7968 return parseSetSoftFloatDirective();
7969 if (IdVal == "hardfloat")
7970 return parseSetHardFloatDirective();
7971 if (IdVal == "crc")
7972 return parseSetFeature(Mips::FeatureCRC);
7973 if (IdVal == "nocrc")
7974 return parseSetNoCRCDirective();
7975 if (IdVal == "virt")
7976 return parseSetFeature(Mips::FeatureVirt);
7977 if (IdVal == "novirt")
7978 return parseSetNoVirtDirective();
7979 if (IdVal == "ginv")
7980 return parseSetFeature(Mips::FeatureGINV);
7981 if (IdVal == "noginv")
7982 return parseSetNoGINVDirective();
7983 if (IdVal == "eva")
7984 return parseSetFeature(Mips::FeatureEVA);
7985 if (IdVal == "noeva")
7986 return parseSetNoEVADirective();
7987
7988 // It is just an identifier, look for an assignment.
7989 return parseSetAssignment();
7990}
7991
7992/// parseDirectiveGpWord
7993/// ::= .gpword local_sym
7994bool MipsAsmParser::parseDirectiveGpWord() {
7995 const MCExpr *Value;
7996 if (getParser().parseExpression(Value))
7997 return true;
7998 getTargetStreamer().emitGPRel32Value(Value);
7999 return parseEOL();
8000}
8001
8002/// parseDirectiveGpDWord
8003/// ::= .gpdword local_sym
8004bool MipsAsmParser::parseDirectiveGpDWord() {
8005 const MCExpr *Value;
8006 if (getParser().parseExpression(Value))
8007 return true;
8008 getTargetStreamer().emitGPRel64Value(Value);
8009 return parseEOL();
8010}
8011
8012/// parseDirectiveDtpRelWord
8013/// ::= .dtprelword tls_sym
8014bool MipsAsmParser::parseDirectiveDtpRelWord() {
8015 const MCExpr *Value;
8016 if (getParser().parseExpression(Value))
8017 return true;
8018 getTargetStreamer().emitDTPRel32Value(Value);
8019 return parseEOL();
8020}
8021
8022/// parseDirectiveDtpRelDWord
8023/// ::= .dtpreldword tls_sym
8024bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8025 const MCExpr *Value;
8026 if (getParser().parseExpression(Value))
8027 return true;
8028 getTargetStreamer().emitDTPRel64Value(Value);
8029 return parseEOL();
8030}
8031
8032/// parseDirectiveTpRelWord
8033/// ::= .tprelword tls_sym
8034bool MipsAsmParser::parseDirectiveTpRelWord() {
8035 const MCExpr *Value;
8036 if (getParser().parseExpression(Value))
8037 return true;
8038 getTargetStreamer().emitTPRel32Value(Value);
8039 return parseEOL();
8040}
8041
8042/// parseDirectiveTpRelDWord
8043/// ::= .tpreldword tls_sym
8044bool MipsAsmParser::parseDirectiveTpRelDWord() {
8045 const MCExpr *Value;
8046 if (getParser().parseExpression(Value))
8047 return true;
8048 getTargetStreamer().emitTPRel64Value(Value);
8049 return parseEOL();
8050}
8051
8052bool MipsAsmParser::parseDirectiveOption() {
8053 MCAsmParser &Parser = getParser();
8054 // Get the option token.
8055 AsmToken Tok = Parser.getTok();
8056 // At the moment only identifiers are supported.
8057 if (Tok.isNot(AsmToken::Identifier)) {
8058 return Error(Parser.getTok().getLoc(),
8059 "unexpected token, expected identifier");
8060 }
8061
8062 StringRef Option = Tok.getIdentifier();
8063
8064 if (Option == "pic0") {
8065 // MipsAsmParser needs to know if the current PIC mode changes.
8066 IsPicEnabled = false;
8067
8068 getTargetStreamer().emitDirectiveOptionPic0();
8069 Parser.Lex();
8070 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8071 return Error(Parser.getTok().getLoc(),
8072 "unexpected token, expected end of statement");
8073 }
8074 return false;
8075 }
8076
8077 if (Option == "pic2") {
8078 // MipsAsmParser needs to know if the current PIC mode changes.
8079 IsPicEnabled = true;
8080
8081 getTargetStreamer().emitDirectiveOptionPic2();
8082 Parser.Lex();
8083 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8084 return Error(Parser.getTok().getLoc(),
8085 "unexpected token, expected end of statement");
8086 }
8087 return false;
8088 }
8089
8090 // Unknown option.
8091 Warning(Parser.getTok().getLoc(),
8092 "unknown option, expected 'pic0' or 'pic2'");
8093 Parser.eatToEndOfStatement();
8094 return false;
8095}
8096
8097/// parseInsnDirective
8098/// ::= .insn
8099bool MipsAsmParser::parseInsnDirective() {
8100 // If this is not the end of the statement, report an error.
8101 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8102 reportParseError("unexpected token, expected end of statement");
8103 return false;
8104 }
8105
8106 // The actual label marking happens in
8107 // MipsELFStreamer::createPendingLabelRelocs().
8108 getTargetStreamer().emitDirectiveInsn();
8109
8110 getParser().Lex(); // Eat EndOfStatement token.
8111 return false;
8112}
8113
8114/// parseRSectionDirective
8115/// ::= .rdata
8116bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8117 // If this is not the end of the statement, report an error.
8118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8119 reportParseError("unexpected token, expected end of statement");
8120 return false;
8121 }
8122
8123 MCSection *ELFSection = getContext().getELFSection(
8125 getParser().getStreamer().switchSection(ELFSection);
8126
8127 getParser().Lex(); // Eat EndOfStatement token.
8128 return false;
8129}
8130
8131/// parseSSectionDirective
8132/// ::= .sbss
8133/// ::= .sdata
8134bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8135 // If this is not the end of the statement, report an error.
8136 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8137 reportParseError("unexpected token, expected end of statement");
8138 return false;
8139 }
8140
8141 MCSection *ELFSection = getContext().getELFSection(
8143 getParser().getStreamer().switchSection(ELFSection);
8144
8145 getParser().Lex(); // Eat EndOfStatement token.
8146 return false;
8147}
8148
8149/// parseDirectiveModule
8150/// ::= .module oddspreg
8151/// ::= .module nooddspreg
8152/// ::= .module fp=value
8153/// ::= .module softfloat
8154/// ::= .module hardfloat
8155/// ::= .module mt
8156/// ::= .module crc
8157/// ::= .module nocrc
8158/// ::= .module virt
8159/// ::= .module novirt
8160/// ::= .module ginv
8161/// ::= .module noginv
8162bool MipsAsmParser::parseDirectiveModule() {
8163 MCAsmParser &Parser = getParser();
8164 AsmLexer &Lexer = getLexer();
8165 SMLoc L = Lexer.getLoc();
8166
8167 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8168 // TODO : get a better message.
8169 reportParseError(".module directive must appear before any code");
8170 return false;
8171 }
8172
8173 StringRef Option;
8174 if (Parser.parseIdentifier(Option)) {
8175 reportParseError("expected .module option identifier");
8176 return false;
8177 }
8178
8179 if (Option == "oddspreg") {
8180 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8181
8182 // Synchronize the abiflags information with the FeatureBits information we
8183 // changed above.
8184 getTargetStreamer().updateABIInfo(*this);
8185
8186 // If printing assembly, use the recently updated abiflags information.
8187 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8188 // emitted at the end).
8189 getTargetStreamer().emitDirectiveModuleOddSPReg();
8190
8191 // If this is not the end of the statement, report an error.
8192 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8193 reportParseError("unexpected token, expected end of statement");
8194 return false;
8195 }
8196
8197 return false; // parseDirectiveModule has finished successfully.
8198 } else if (Option == "nooddspreg") {
8199 if (!isABI_O32()) {
8200 return Error(L, "'.module nooddspreg' requires the O32 ABI");
8201 }
8202
8203 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8204
8205 // Synchronize the abiflags information with the FeatureBits information we
8206 // changed above.
8207 getTargetStreamer().updateABIInfo(*this);
8208
8209 // If printing assembly, use the recently updated abiflags information.
8210 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8211 // emitted at the end).
8212 getTargetStreamer().emitDirectiveModuleOddSPReg();
8213
8214 // If this is not the end of the statement, report an error.
8215 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8216 reportParseError("unexpected token, expected end of statement");
8217 return false;
8218 }
8219
8220 return false; // parseDirectiveModule has finished successfully.
8221 } else if (Option == "fp") {
8222 return parseDirectiveModuleFP();
8223 } else if (Option == "softfloat") {
8224 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8225
8226 // Synchronize the ABI Flags information with the FeatureBits information we
8227 // updated above.
8228 getTargetStreamer().updateABIInfo(*this);
8229
8230 // If printing assembly, use the recently updated ABI Flags information.
8231 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8232 // emitted later).
8233 getTargetStreamer().emitDirectiveModuleSoftFloat();
8234
8235 // If this is not the end of the statement, report an error.
8236 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8237 reportParseError("unexpected token, expected end of statement");
8238 return false;
8239 }
8240
8241 return false; // parseDirectiveModule has finished successfully.
8242 } else if (Option == "hardfloat") {
8243 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8244
8245 // Synchronize the ABI Flags information with the FeatureBits information we
8246 // updated above.
8247 getTargetStreamer().updateABIInfo(*this);
8248
8249 // If printing assembly, use the recently updated ABI Flags information.
8250 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8251 // emitted later).
8252 getTargetStreamer().emitDirectiveModuleHardFloat();
8253
8254 // If this is not the end of the statement, report an error.
8255 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8256 reportParseError("unexpected token, expected end of statement");
8257 return false;
8258 }
8259
8260 return false; // parseDirectiveModule has finished successfully.
8261 } else if (Option == "mt") {
8262 setModuleFeatureBits(Mips::FeatureMT, "mt");
8263
8264 // Synchronize the ABI Flags information with the FeatureBits information we
8265 // updated above.
8266 getTargetStreamer().updateABIInfo(*this);
8267
8268 // If printing assembly, use the recently updated ABI Flags information.
8269 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8270 // emitted later).
8271 getTargetStreamer().emitDirectiveModuleMT();
8272
8273 // If this is not the end of the statement, report an error.
8274 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8275 reportParseError("unexpected token, expected end of statement");
8276 return false;
8277 }
8278
8279 return false; // parseDirectiveModule has finished successfully.
8280 } else if (Option == "crc") {
8281 setModuleFeatureBits(Mips::FeatureCRC, "crc");
8282
8283 // Synchronize the ABI Flags information with the FeatureBits information we
8284 // updated above.
8285 getTargetStreamer().updateABIInfo(*this);
8286
8287 // If printing assembly, use the recently updated ABI Flags information.
8288 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8289 // emitted later).
8290 getTargetStreamer().emitDirectiveModuleCRC();
8291
8292 // If this is not the end of the statement, report an error.
8293 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8294 reportParseError("unexpected token, expected end of statement");
8295 return false;
8296 }
8297
8298 return false; // parseDirectiveModule has finished successfully.
8299 } else if (Option == "nocrc") {
8300 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8301
8302 // Synchronize the ABI Flags information with the FeatureBits information we
8303 // updated above.
8304 getTargetStreamer().updateABIInfo(*this);
8305
8306 // If printing assembly, use the recently updated ABI Flags information.
8307 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8308 // emitted later).
8309 getTargetStreamer().emitDirectiveModuleNoCRC();
8310
8311 // If this is not the end of the statement, report an error.
8312 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8313 reportParseError("unexpected token, expected end of statement");
8314 return false;
8315 }
8316
8317 return false; // parseDirectiveModule has finished successfully.
8318 } else if (Option == "virt") {
8319 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8320
8321 // Synchronize the ABI Flags information with the FeatureBits information we
8322 // updated above.
8323 getTargetStreamer().updateABIInfo(*this);
8324
8325 // If printing assembly, use the recently updated ABI Flags information.
8326 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8327 // emitted later).
8328 getTargetStreamer().emitDirectiveModuleVirt();
8329
8330 // If this is not the end of the statement, report an error.
8331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8332 reportParseError("unexpected token, expected end of statement");
8333 return false;
8334 }
8335
8336 return false; // parseDirectiveModule has finished successfully.
8337 } else if (Option == "novirt") {
8338 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8339
8340 // Synchronize the ABI Flags information with the FeatureBits information we
8341 // updated above.
8342 getTargetStreamer().updateABIInfo(*this);
8343
8344 // If printing assembly, use the recently updated ABI Flags information.
8345 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8346 // emitted later).
8347 getTargetStreamer().emitDirectiveModuleNoVirt();
8348
8349 // If this is not the end of the statement, report an error.
8350 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8351 reportParseError("unexpected token, expected end of statement");
8352 return false;
8353 }
8354
8355 return false; // parseDirectiveModule has finished successfully.
8356 } else if (Option == "ginv") {
8357 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8358
8359 // Synchronize the ABI Flags information with the FeatureBits information we
8360 // updated above.
8361 getTargetStreamer().updateABIInfo(*this);
8362
8363 // If printing assembly, use the recently updated ABI Flags information.
8364 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8365 // emitted later).
8366 getTargetStreamer().emitDirectiveModuleGINV();
8367
8368 // If this is not the end of the statement, report an error.
8369 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8370 reportParseError("unexpected token, expected end of statement");
8371 return false;
8372 }
8373
8374 return false; // parseDirectiveModule has finished successfully.
8375 } else if (Option == "noginv") {
8376 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8377
8378 // Synchronize the ABI Flags information with the FeatureBits information we
8379 // updated above.
8380 getTargetStreamer().updateABIInfo(*this);
8381
8382 // If printing assembly, use the recently updated ABI Flags information.
8383 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8384 // emitted later).
8385 getTargetStreamer().emitDirectiveModuleNoGINV();
8386
8387 // If this is not the end of the statement, report an error.
8388 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8389 reportParseError("unexpected token, expected end of statement");
8390 return false;
8391 }
8392
8393 return false; // parseDirectiveModule has finished successfully.
8394 } else {
8395 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8396 }
8397}
8398
8399/// parseDirectiveModuleFP
8400/// ::= =32
8401/// ::= =xx
8402/// ::= =64
8403bool MipsAsmParser::parseDirectiveModuleFP() {
8404 MCAsmParser &Parser = getParser();
8405 AsmLexer &Lexer = getLexer();
8406
8407 if (Lexer.isNot(AsmToken::Equal)) {
8408 reportParseError("unexpected token, expected equals sign '='");
8409 return false;
8410 }
8411 Parser.Lex(); // Eat '=' token.
8412
8414 if (!parseFpABIValue(FpABI, ".module"))
8415 return false;
8416
8417 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8418 reportParseError("unexpected token, expected end of statement");
8419 return false;
8420 }
8421
8422 // Synchronize the abiflags information with the FeatureBits information we
8423 // changed above.
8424 getTargetStreamer().updateABIInfo(*this);
8425
8426 // If printing assembly, use the recently updated abiflags information.
8427 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8428 // emitted at the end).
8429 getTargetStreamer().emitDirectiveModuleFP();
8430
8431 Parser.Lex(); // Consume the EndOfStatement.
8432 return false;
8433}
8434
8435bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8436 StringRef Directive) {
8437 MCAsmParser &Parser = getParser();
8438 AsmLexer &Lexer = getLexer();
8439 bool ModuleLevelOptions = Directive == ".module";
8440
8441 if (Lexer.is(AsmToken::Identifier)) {
8442 StringRef Value = Parser.getTok().getString();
8443 Parser.Lex();
8444
8445 if (Value != "xx") {
8446 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8447 return false;
8448 }
8449
8450 if (!isABI_O32()) {
8451 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8452 return false;
8453 }
8454
8455 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8456 if (ModuleLevelOptions) {
8457 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8458 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8459 } else {
8460 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8461 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8462 }
8463 return true;
8464 }
8465
8466 if (Lexer.is(AsmToken::Integer)) {
8467 unsigned Value = Parser.getTok().getIntVal();
8468 Parser.Lex();
8469
8470 if (Value != 32 && Value != 64) {
8471 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8472 return false;
8473 }
8474
8475 if (Value == 32) {
8476 if (!isABI_O32()) {
8477 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8478 return false;
8479 }
8480
8481 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8482 if (ModuleLevelOptions) {
8483 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8484 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8485 } else {
8486 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8487 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8488 }
8489 } else {
8490 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8491 if (ModuleLevelOptions) {
8492 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8493 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8494 } else {
8495 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8496 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8497 }
8498 }
8499
8500 return true;
8501 }
8502
8503 return false;
8504}
8505
8506bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8507 // This returns false if this function recognizes the directive
8508 // regardless of whether it is successfully handles or reports an
8509 // error. Otherwise it returns true to give the generic parser a
8510 // chance at recognizing it.
8511
8512 MCAsmParser &Parser = getParser();
8513 StringRef IDVal = DirectiveID.getString();
8514
8515 if (IDVal == ".cpadd") {
8516 parseDirectiveCpAdd(DirectiveID.getLoc());
8517 return false;
8518 }
8519 if (IDVal == ".cpload") {
8520 parseDirectiveCpLoad(DirectiveID.getLoc());
8521 return false;
8522 }
8523 if (IDVal == ".cprestore") {
8524 parseDirectiveCpRestore(DirectiveID.getLoc());
8525 return false;
8526 }
8527 if (IDVal == ".cplocal") {
8528 parseDirectiveCpLocal(DirectiveID.getLoc());
8529 return false;
8530 }
8531 if (IDVal == ".ent") {
8532 StringRef SymbolName;
8533
8534 if (Parser.parseIdentifier(SymbolName)) {
8535 reportParseError("expected identifier after .ent");
8536 return false;
8537 }
8538
8539 // There's an undocumented extension that allows an integer to
8540 // follow the name of the procedure which AFAICS is ignored by GAS.
8541 // Example: .ent foo,2
8542 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8543 if (getLexer().isNot(AsmToken::Comma)) {
8544 // Even though we accept this undocumented extension for compatibility
8545 // reasons, the additional integer argument does not actually change
8546 // the behaviour of the '.ent' directive, so we would like to discourage
8547 // its use. We do this by not referring to the extended version in
8548 // error messages which are not directly related to its use.
8549 reportParseError("unexpected token, expected end of statement");
8550 return false;
8551 }
8552 Parser.Lex(); // Eat the comma.
8553 const MCExpr *DummyNumber;
8554 int64_t DummyNumberVal;
8555 // If the user was explicitly trying to use the extended version,
8556 // we still give helpful extension-related error messages.
8557 if (Parser.parseExpression(DummyNumber)) {
8558 reportParseError("expected number after comma");
8559 return false;
8560 }
8561 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8562 reportParseError("expected an absolute expression after comma");
8563 return false;
8564 }
8565 }
8566
8567 // If this is not the end of the statement, report an error.
8568 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8569 reportParseError("unexpected token, expected end of statement");
8570 return false;
8571 }
8572
8573 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8574
8575 getTargetStreamer().emitDirectiveEnt(*Sym);
8576 CurrentFn = Sym;
8577 IsCpRestoreSet = false;
8578 return false;
8579 }
8580
8581 if (IDVal == ".end") {
8582 StringRef SymbolName;
8583
8584 if (Parser.parseIdentifier(SymbolName)) {
8585 reportParseError("expected identifier after .end");
8586 return false;
8587 }
8588
8589 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8590 reportParseError("unexpected token, expected end of statement");
8591 return false;
8592 }
8593
8594 if (CurrentFn == nullptr) {
8595 reportParseError(".end used without .ent");
8596 return false;
8597 }
8598
8599 if ((SymbolName != CurrentFn->getName())) {
8600 reportParseError(".end symbol does not match .ent symbol");
8601 return false;
8602 }
8603
8604 getTargetStreamer().emitDirectiveEnd(SymbolName);
8605 CurrentFn = nullptr;
8606 IsCpRestoreSet = false;
8607 return false;
8608 }
8609
8610 if (IDVal == ".frame") {
8611 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8613 ParseStatus Res = parseAnyRegister(TmpReg);
8614 if (Res.isNoMatch() || Res.isFailure()) {
8615 reportParseError("expected stack register");
8616 return false;
8617 }
8618
8619 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8620 if (!StackRegOpnd.isGPRAsmReg()) {
8621 reportParseError(StackRegOpnd.getStartLoc(),
8622 "expected general purpose register");
8623 return false;
8624 }
8625 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8626
8627 if (Parser.getTok().is(AsmToken::Comma))
8628 Parser.Lex();
8629 else {
8630 reportParseError("unexpected token, expected comma");
8631 return false;
8632 }
8633
8634 // Parse the frame size.
8635 const MCExpr *FrameSize;
8636 int64_t FrameSizeVal;
8637
8638 if (Parser.parseExpression(FrameSize)) {
8639 reportParseError("expected frame size value");
8640 return false;
8641 }
8642
8643 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8644 reportParseError("frame size not an absolute expression");
8645 return false;
8646 }
8647
8648 if (Parser.getTok().is(AsmToken::Comma))
8649 Parser.Lex();
8650 else {
8651 reportParseError("unexpected token, expected comma");
8652 return false;
8653 }
8654
8655 // Parse the return register.
8656 TmpReg.clear();
8657 Res = parseAnyRegister(TmpReg);
8658 if (Res.isNoMatch() || Res.isFailure()) {
8659 reportParseError("expected return register");
8660 return false;
8661 }
8662
8663 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8664 if (!ReturnRegOpnd.isGPRAsmReg()) {
8665 reportParseError(ReturnRegOpnd.getStartLoc(),
8666 "expected general purpose register");
8667 return false;
8668 }
8669
8670 // If this is not the end of the statement, report an error.
8671 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8672 reportParseError("unexpected token, expected end of statement");
8673 return false;
8674 }
8675
8676 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8677 ReturnRegOpnd.getGPR32Reg());
8678 IsCpRestoreSet = false;
8679 return false;
8680 }
8681
8682 if (IDVal == ".set") {
8683 parseDirectiveSet();
8684 return false;
8685 }
8686
8687 if (IDVal == ".mask" || IDVal == ".fmask") {
8688 // .mask bitmask, frame_offset
8689 // bitmask: One bit for each register used.
8690 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8691 // first register is expected to be saved.
8692 // Examples:
8693 // .mask 0x80000000, -4
8694 // .fmask 0x80000000, -4
8695 //
8696
8697 // Parse the bitmask
8698 const MCExpr *BitMask;
8699 int64_t BitMaskVal;
8700
8701 if (Parser.parseExpression(BitMask)) {
8702 reportParseError("expected bitmask value");
8703 return false;
8704 }
8705
8706 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8707 reportParseError("bitmask not an absolute expression");
8708 return false;
8709 }
8710
8711 if (Parser.getTok().is(AsmToken::Comma))
8712 Parser.Lex();
8713 else {
8714 reportParseError("unexpected token, expected comma");
8715 return false;
8716 }
8717
8718 // Parse the frame_offset
8719 const MCExpr *FrameOffset;
8720 int64_t FrameOffsetVal;
8721
8722 if (Parser.parseExpression(FrameOffset)) {
8723 reportParseError("expected frame offset value");
8724 return false;
8725 }
8726
8727 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8728 reportParseError("frame offset not an absolute expression");
8729 return false;
8730 }
8731
8732 // If this is not the end of the statement, report an error.
8733 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8734 reportParseError("unexpected token, expected end of statement");
8735 return false;
8736 }
8737
8738 if (IDVal == ".mask")
8739 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8740 else
8741 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8742 return false;
8743 }
8744
8745 if (IDVal == ".nan")
8746 return parseDirectiveNaN();
8747
8748 if (IDVal == ".gpword") {
8749 parseDirectiveGpWord();
8750 return false;
8751 }
8752
8753 if (IDVal == ".gpdword") {
8754 parseDirectiveGpDWord();
8755 return false;
8756 }
8757
8758 if (IDVal == ".dtprelword") {
8759 parseDirectiveDtpRelWord();
8760 return false;
8761 }
8762
8763 if (IDVal == ".dtpreldword") {
8764 parseDirectiveDtpRelDWord();
8765 return false;
8766 }
8767
8768 if (IDVal == ".tprelword") {
8769 parseDirectiveTpRelWord();
8770 return false;
8771 }
8772
8773 if (IDVal == ".tpreldword") {
8774 parseDirectiveTpRelDWord();
8775 return false;
8776 }
8777
8778 if (IDVal == ".option") {
8779 parseDirectiveOption();
8780 return false;
8781 }
8782
8783 if (IDVal == ".abicalls") {
8784 getTargetStreamer().emitDirectiveAbiCalls();
8785 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8786 Error(Parser.getTok().getLoc(),
8787 "unexpected token, expected end of statement");
8788 }
8789 return false;
8790 }
8791
8792 if (IDVal == ".cpsetup") {
8793 parseDirectiveCPSetup();
8794 return false;
8795 }
8796 if (IDVal == ".cpreturn") {
8797 parseDirectiveCPReturn();
8798 return false;
8799 }
8800 if (IDVal == ".module") {
8801 parseDirectiveModule();
8802 return false;
8803 }
8804 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8805 parseInternalDirectiveReallowModule();
8806 return false;
8807 }
8808 if (IDVal == ".insn") {
8809 parseInsnDirective();
8810 return false;
8811 }
8812 if (IDVal == ".rdata") {
8813 parseRSectionDirective(".rodata");
8814 return false;
8815 }
8816 if (IDVal == ".sbss") {
8817 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8818 return false;
8819 }
8820 if (IDVal == ".sdata") {
8821 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8822 return false;
8823 }
8824
8825 return true;
8826}
8827
8828bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8829 // If this is not the end of the statement, report an error.
8830 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8831 reportParseError("unexpected token, expected end of statement");
8832 return false;
8833 }
8834
8835 getTargetStreamer().reallowModuleDirective();
8836
8837 getParser().Lex(); // Eat EndOfStatement token.
8838 return false;
8839}
8840
8841extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
8848
8849#define GET_REGISTER_MATCHER
8850#define GET_MATCHER_IMPLEMENTATION
8851#define GET_MNEMONIC_SPELL_CHECKER
8852#include "MipsGenAsmMatcher.inc"
8853
8854bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8855 // Find the appropriate table for this asm variant.
8856 const MatchEntry *Start, *End;
8857 switch (VariantID) {
8858 default: llvm_unreachable("invalid variant!");
8859 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8860 }
8861 // Search the table.
8862 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8863 return MnemonicRange.first != MnemonicRange.second;
8864}
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:857
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h: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))
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.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
constexpr bool isValid() const
Definition MCRegister.h:84
constexpr unsigned id() const
Definition MCRegister.h:82
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
uint16_t getSpecifier() const
Definition MCExpr.h:232
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition MCSymbol.h:237
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition MCSymbol.h:243
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition MCSymbol.h:267
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
Definition MCSymbol.h:270
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition MCSymbol.h:205
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Definition MCStreamer.h:103
MCContext & getContext()
Unary assembler expressions.
Definition MCExpr.h:242
const MCSymbol * getAddSym() const
Definition MCValue.h:49
int64_t getConstant() const
Definition MCValue.h:44
const MCSymbol * getSubSym() const
Definition MCValue.h:51
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=Mips::NoRegAltName)
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Definition Register.h:100
Represents a location in source code.
Definition SMLoc.h:22
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:35
constexpr const char * getPointer() const
Definition SMLoc.h:33
void push_back(const T &Elt)
iterator end()
Definition StringMap.h:214
iterator find(StringRef Key)
Definition StringMap.h:227
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
Definition Triple.cpp:2213
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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:1259
@ SHF_MIPS_GPREL
Definition ELF.h:1342
@ SHF_WRITE
Definition ELF.h:1256
@ SHT_PROGBITS
Definition ELF.h:1157
@ SHT_NOBITS
Definition ELF.h:1164
@ STB_LOCAL
Definition ELF.h:1421
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
constexpr MCPhysReg FP_64
constexpr MCPhysReg GP_64
constexpr MCPhysReg FP
constexpr MCPhysReg GP
constexpr MCPhysReg RA_64
constexpr MCPhysReg SP
constexpr MCPhysReg SP_64
constexpr MCPhysReg RA
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:51
LLVM_ABI StringRef getABIName()
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:325
Op::Description Desc
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:151
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:156
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition Alignment.h:191
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
@ Other
Any other memory.
Definition ModRef.h:68
To bit_cast(const From &from) noexcept
Definition bit.h:90
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition MathExtras.h:183
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:567
Target & getTheMipsTarget()
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:199
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...