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