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