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 }
4305
4306 if (!UseTraps)
4307 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4308
4309 if (!UseTraps)
4310 TOut.getStreamer().emitLabel(BrTarget);
4311 }
4312
4313 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4314 return false;
4315}
4316
4317bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4318 SMLoc IDLoc, MCStreamer &Out,
4319 const MCSubtargetInfo *STI) {
4320 MipsTargetStreamer &TOut = getTargetStreamer();
4321
4322 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4323 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4324 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4325
4326 MCRegister FirstReg = Inst.getOperand(0).getReg();
4327 MCRegister SecondReg = Inst.getOperand(1).getReg();
4328 MCRegister ThirdReg = Inst.getOperand(2).getReg();
4329
4330 if (hasMips1() && !hasMips2()) {
4331 MCRegister ATReg = getATReg(IDLoc);
4332 if (!ATReg)
4333 return true;
4334 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4335 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4336 TOut.emitNop(IDLoc, STI);
4337 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4338 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4339 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4340 TOut.emitNop(IDLoc, STI);
4341 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4342 : Mips::CVT_W_S,
4343 FirstReg, SecondReg, IDLoc, STI);
4344 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4345 TOut.emitNop(IDLoc, STI);
4346 return false;
4347 }
4348
4349 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4350 : Mips::TRUNC_W_S,
4351 FirstReg, SecondReg, IDLoc, STI);
4352
4353 return false;
4354}
4355
4356bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4357 MCStreamer &Out, const MCSubtargetInfo *STI) {
4358 if (hasMips32r6() || hasMips64r6()) {
4359 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4360 }
4361
4362 const MCOperand &DstRegOp = Inst.getOperand(0);
4363 assert(DstRegOp.isReg() && "expected register operand kind");
4364 const MCOperand &SrcRegOp = Inst.getOperand(1);
4365 assert(SrcRegOp.isReg() && "expected register operand kind");
4366 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4367 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4368
4369 MipsTargetStreamer &TOut = getTargetStreamer();
4370 MCRegister DstReg = DstRegOp.getReg();
4371 MCRegister SrcReg = SrcRegOp.getReg();
4372 int64_t OffsetValue = OffsetImmOp.getImm();
4373
4374 // NOTE: We always need AT for ULHU, as it is always used as the source
4375 // register for one of the LBu's.
4376 warnIfNoMacro(IDLoc);
4377 MCRegister ATReg = getATReg(IDLoc);
4378 if (!ATReg)
4379 return true;
4380
4381 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4382 if (IsLargeOffset) {
4383 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4384 IDLoc, Out, STI))
4385 return true;
4386 }
4387
4388 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4389 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4390 if (isLittle())
4391 std::swap(FirstOffset, SecondOffset);
4392
4393 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4394 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4395
4396 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4397 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4398
4399 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4400 FirstOffset, IDLoc, STI);
4401 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4402 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4403 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4404
4405 return false;
4406}
4407
4408bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4409 const MCSubtargetInfo *STI) {
4410 if (hasMips32r6() || hasMips64r6()) {
4411 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4412 }
4413
4414 const MCOperand &DstRegOp = Inst.getOperand(0);
4415 assert(DstRegOp.isReg() && "expected register operand kind");
4416 const MCOperand &SrcRegOp = Inst.getOperand(1);
4417 assert(SrcRegOp.isReg() && "expected register operand kind");
4418 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4419 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4420
4421 MipsTargetStreamer &TOut = getTargetStreamer();
4422 MCRegister DstReg = DstRegOp.getReg();
4423 MCRegister SrcReg = SrcRegOp.getReg();
4424 int64_t OffsetValue = OffsetImmOp.getImm();
4425
4426 warnIfNoMacro(IDLoc);
4427 MCRegister ATReg = getATReg(IDLoc);
4428 if (!ATReg)
4429 return true;
4430
4431 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4432 if (IsLargeOffset) {
4433 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4434 IDLoc, Out, STI))
4435 return true;
4436 }
4437
4438 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4439 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4440 if (isLittle())
4441 std::swap(FirstOffset, SecondOffset);
4442
4443 if (IsLargeOffset) {
4444 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4445 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4446 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4447 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4448 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4449 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4450 } else {
4451 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4452 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4453 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4454 }
4455
4456 return false;
4457}
4458
4459bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4460 const MCSubtargetInfo *STI) {
4461 if (hasMips32r6() || hasMips64r6()) {
4462 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4463 }
4464
4465 const MCOperand &DstRegOp = Inst.getOperand(0);
4466 assert(DstRegOp.isReg() && "expected register operand kind");
4467 const MCOperand &SrcRegOp = Inst.getOperand(1);
4468 assert(SrcRegOp.isReg() && "expected register operand kind");
4469 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4470 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4471
4472 MipsTargetStreamer &TOut = getTargetStreamer();
4473 MCRegister DstReg = DstRegOp.getReg();
4474 MCRegister SrcReg = SrcRegOp.getReg();
4475 int64_t OffsetValue = OffsetImmOp.getImm();
4476
4477 // Compute left/right load/store offsets.
4478 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4479 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4480 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4481 if (isLittle())
4482 std::swap(LxlOffset, LxrOffset);
4483
4484 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4485 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4486 MCRegister TmpReg = SrcReg;
4487 if (IsLargeOffset || DoMove) {
4488 warnIfNoMacro(IDLoc);
4489 TmpReg = getATReg(IDLoc);
4490 if (!TmpReg)
4491 return true;
4492 }
4493
4494 if (IsLargeOffset) {
4495 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4496 IDLoc, Out, STI))
4497 return true;
4498 }
4499
4500 if (DoMove)
4501 std::swap(DstReg, TmpReg);
4502
4503 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4504 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4505 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4506 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4507
4508 if (DoMove)
4509 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4510
4511 return false;
4512}
4513
4514bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4515 const MCSubtargetInfo *STI) {
4516 MipsTargetStreamer &TOut = getTargetStreamer();
4517
4518 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4519 assert(Inst.getOperand(0).isReg() &&
4520 Inst.getOperand(1).isReg() &&
4521 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4522
4523 MCRegister DstReg = Inst.getOperand(0).getReg();
4524 MCRegister SrcReg = Inst.getOperand(1).getReg();
4525 MCRegister OpReg = Inst.getOperand(2).getReg();
4526 unsigned OpCode;
4527
4528 warnIfNoMacro(IDLoc);
4529
4530 switch (Inst.getOpcode()) {
4531 case Mips::SGE:
4532 OpCode = Mips::SLT;
4533 break;
4534 case Mips::SGEU:
4535 OpCode = Mips::SLTu;
4536 break;
4537 default:
4538 llvm_unreachable("unexpected 'sge' opcode");
4539 }
4540
4541 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4542 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4543 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4544
4545 return false;
4546}
4547
4548bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4549 const MCSubtargetInfo *STI) {
4550 MipsTargetStreamer &TOut = getTargetStreamer();
4551
4552 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4553 assert(Inst.getOperand(0).isReg() &&
4554 Inst.getOperand(1).isReg() &&
4555 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4556
4557 MCRegister DstReg = Inst.getOperand(0).getReg();
4558 MCRegister SrcReg = Inst.getOperand(1).getReg();
4559 int64_t ImmValue = Inst.getOperand(2).getImm();
4560 unsigned OpRegCode, OpImmCode;
4561
4562 warnIfNoMacro(IDLoc);
4563
4564 switch (Inst.getOpcode()) {
4565 case Mips::SGEImm:
4566 case Mips::SGEImm64:
4567 OpRegCode = Mips::SLT;
4568 OpImmCode = Mips::SLTi;
4569 break;
4570 case Mips::SGEUImm:
4571 case Mips::SGEUImm64:
4572 OpRegCode = Mips::SLTu;
4573 OpImmCode = Mips::SLTiu;
4574 break;
4575 default:
4576 llvm_unreachable("unexpected 'sge' opcode with immediate");
4577 }
4578
4579 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4580 if (isInt<16>(ImmValue)) {
4581 // Use immediate version of STL.
4582 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4583 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4584 } else {
4585 MCRegister ImmReg = DstReg;
4586 if (DstReg == SrcReg) {
4587 MCRegister ATReg = getATReg(Inst.getLoc());
4588 if (!ATReg)
4589 return true;
4590 ImmReg = ATReg;
4591 }
4592
4593 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue),
4594 false, IDLoc, Out, STI))
4595 return true;
4596
4597 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4598 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4599 }
4600
4601 return false;
4602}
4603
4604bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4605 const MCSubtargetInfo *STI) {
4606 MipsTargetStreamer &TOut = getTargetStreamer();
4607
4608 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4609 assert(Inst.getOperand(0).isReg() &&
4610 Inst.getOperand(1).isReg() &&
4611 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4612
4613 MCRegister DstReg = Inst.getOperand(0).getReg();
4614 MCRegister SrcReg = Inst.getOperand(1).getReg();
4615 MCRegister ImmReg = DstReg;
4616 int64_t ImmValue = Inst.getOperand(2).getImm();
4617 unsigned OpCode;
4618
4619 warnIfNoMacro(IDLoc);
4620
4621 switch (Inst.getOpcode()) {
4622 case Mips::SGTImm:
4623 case Mips::SGTImm64:
4624 OpCode = Mips::SLT;
4625 break;
4626 case Mips::SGTUImm:
4627 case Mips::SGTUImm64:
4628 OpCode = Mips::SLTu;
4629 break;
4630 default:
4631 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4632 }
4633
4634 if (DstReg == SrcReg) {
4635 MCRegister ATReg = getATReg(Inst.getLoc());
4636 if (!ATReg)
4637 return true;
4638 ImmReg = ATReg;
4639 }
4640
4641 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4642 IDLoc, Out, STI))
4643 return true;
4644
4645 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4646 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4647
4648 return false;
4649}
4650
4651bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4652 const MCSubtargetInfo *STI) {
4653 MipsTargetStreamer &TOut = getTargetStreamer();
4654
4655 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4656 assert(Inst.getOperand(0).isReg() &&
4657 Inst.getOperand(1).isReg() &&
4658 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4659
4660 MCRegister DstReg = Inst.getOperand(0).getReg();
4661 MCRegister SrcReg = Inst.getOperand(1).getReg();
4662 MCRegister OpReg = Inst.getOperand(2).getReg();
4663 unsigned OpCode;
4664
4665 warnIfNoMacro(IDLoc);
4666
4667 switch (Inst.getOpcode()) {
4668 case Mips::SLE:
4669 OpCode = Mips::SLT;
4670 break;
4671 case Mips::SLEU:
4672 OpCode = Mips::SLTu;
4673 break;
4674 default:
4675 llvm_unreachable("unexpected 'sge' opcode");
4676 }
4677
4678 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4679 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4680 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4681
4682 return false;
4683}
4684
4685bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4686 const MCSubtargetInfo *STI) {
4687 MipsTargetStreamer &TOut = getTargetStreamer();
4688
4689 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4690 assert(Inst.getOperand(0).isReg() &&
4691 Inst.getOperand(1).isReg() &&
4692 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4693
4694 MCRegister DstReg = Inst.getOperand(0).getReg();
4695 MCRegister SrcReg = Inst.getOperand(1).getReg();
4696 int64_t ImmValue = Inst.getOperand(2).getImm();
4697 unsigned OpRegCode;
4698
4699 warnIfNoMacro(IDLoc);
4700
4701 switch (Inst.getOpcode()) {
4702 case Mips::SLEImm:
4703 case Mips::SLEImm64:
4704 OpRegCode = Mips::SLT;
4705 break;
4706 case Mips::SLEUImm:
4707 case Mips::SLEUImm64:
4708 OpRegCode = Mips::SLTu;
4709 break;
4710 default:
4711 llvm_unreachable("unexpected 'sge' opcode with immediate");
4712 }
4713
4714 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4715 MCRegister ImmReg = DstReg;
4716 if (DstReg == SrcReg) {
4717 MCRegister ATReg = getATReg(Inst.getLoc());
4718 if (!ATReg)
4719 return true;
4720 ImmReg = ATReg;
4721 }
4722
4723 if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4724 IDLoc, Out, STI))
4725 return true;
4726
4727 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4728 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4729
4730 return false;
4731}
4732
4733bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4734 MCStreamer &Out,
4735 const MCSubtargetInfo *STI) {
4736 MipsTargetStreamer &TOut = getTargetStreamer();
4737
4738 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4739 assert(Inst.getOperand(0).isReg() &&
4740 Inst.getOperand(1).isReg() &&
4741 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4742
4743 MCRegister ATReg;
4744 MCRegister FinalDstReg;
4745 MCRegister DstReg = Inst.getOperand(0).getReg();
4746 MCRegister SrcReg = Inst.getOperand(1).getReg();
4747 int64_t ImmValue = Inst.getOperand(2).getImm();
4748
4749 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4750
4751 unsigned FinalOpcode = Inst.getOpcode();
4752
4753 if (DstReg == SrcReg) {
4754 ATReg = getATReg(Inst.getLoc());
4755 if (!ATReg)
4756 return true;
4757 FinalDstReg = DstReg;
4758 DstReg = ATReg;
4759 }
4760
4761 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit, false,
4762 Inst.getLoc(), Out, STI)) {
4763 switch (FinalOpcode) {
4764 default:
4765 llvm_unreachable("unimplemented expansion");
4766 case Mips::ADDi:
4767 FinalOpcode = Mips::ADD;
4768 break;
4769 case Mips::ADDiu:
4770 FinalOpcode = Mips::ADDu;
4771 break;
4772 case Mips::ANDi:
4773 FinalOpcode = Mips::AND;
4774 break;
4775 case Mips::NORImm:
4776 FinalOpcode = Mips::NOR;
4777 break;
4778 case Mips::ORi:
4779 FinalOpcode = Mips::OR;
4780 break;
4781 case Mips::SLTi:
4782 FinalOpcode = Mips::SLT;
4783 break;
4784 case Mips::SLTiu:
4785 FinalOpcode = Mips::SLTu;
4786 break;
4787 case Mips::XORi:
4788 FinalOpcode = Mips::XOR;
4789 break;
4790 case Mips::ADDi_MM:
4791 FinalOpcode = Mips::ADD_MM;
4792 break;
4793 case Mips::ADDiu_MM:
4794 FinalOpcode = Mips::ADDu_MM;
4795 break;
4796 case Mips::ANDi_MM:
4797 FinalOpcode = Mips::AND_MM;
4798 break;
4799 case Mips::ORi_MM:
4800 FinalOpcode = Mips::OR_MM;
4801 break;
4802 case Mips::SLTi_MM:
4803 FinalOpcode = Mips::SLT_MM;
4804 break;
4805 case Mips::SLTiu_MM:
4806 FinalOpcode = Mips::SLTu_MM;
4807 break;
4808 case Mips::XORi_MM:
4809 FinalOpcode = Mips::XOR_MM;
4810 break;
4811 case Mips::ANDi64:
4812 FinalOpcode = Mips::AND64;
4813 break;
4814 case Mips::NORImm64:
4815 FinalOpcode = Mips::NOR64;
4816 break;
4817 case Mips::ORi64:
4818 FinalOpcode = Mips::OR64;
4819 break;
4820 case Mips::SLTImm64:
4821 FinalOpcode = Mips::SLT64;
4822 break;
4823 case Mips::SLTUImm64:
4824 FinalOpcode = Mips::SLTu64;
4825 break;
4826 case Mips::XORi64:
4827 FinalOpcode = Mips::XOR64;
4828 break;
4829 }
4830
4831 if (!FinalDstReg)
4832 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4833 else
4834 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4835 return false;
4836 }
4837 return true;
4838}
4839
4840bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4841 const MCSubtargetInfo *STI) {
4842 MipsTargetStreamer &TOut = getTargetStreamer();
4843 MCRegister ATReg;
4844 MCRegister DReg = Inst.getOperand(0).getReg();
4845 MCRegister SReg = Inst.getOperand(1).getReg();
4846 MCRegister TReg = Inst.getOperand(2).getReg();
4847 MCRegister TmpReg = DReg;
4848
4849 unsigned FirstShift = Mips::NOP;
4850 unsigned SecondShift = Mips::NOP;
4851
4852 if (hasMips32r2()) {
4853 if (DReg == SReg) {
4854 TmpReg = getATReg(Inst.getLoc());
4855 if (!TmpReg)
4856 return true;
4857 }
4858
4859 if (Inst.getOpcode() == Mips::ROL) {
4860 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4861 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4862 return false;
4863 }
4864
4865 if (Inst.getOpcode() == Mips::ROR) {
4866 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4867 return false;
4868 }
4869
4870 return true;
4871 }
4872
4873 if (hasMips32()) {
4874 switch (Inst.getOpcode()) {
4875 default:
4876 llvm_unreachable("unexpected instruction opcode");
4877 case Mips::ROL:
4878 FirstShift = Mips::SRLV;
4879 SecondShift = Mips::SLLV;
4880 break;
4881 case Mips::ROR:
4882 FirstShift = Mips::SLLV;
4883 SecondShift = Mips::SRLV;
4884 break;
4885 }
4886
4887 ATReg = getATReg(Inst.getLoc());
4888 if (!ATReg)
4889 return true;
4890
4891 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4892 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4893 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4894 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4895
4896 return false;
4897 }
4898
4899 return true;
4900}
4901
4902bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4903 MCStreamer &Out,
4904 const MCSubtargetInfo *STI) {
4905 MipsTargetStreamer &TOut = getTargetStreamer();
4906 MCRegister ATReg;
4907 MCRegister DReg = Inst.getOperand(0).getReg();
4908 MCRegister SReg = Inst.getOperand(1).getReg();
4909 int64_t ImmValue = Inst.getOperand(2).getImm();
4910
4911 unsigned FirstShift = Mips::NOP;
4912 unsigned SecondShift = Mips::NOP;
4913
4914 if (hasMips32r2()) {
4915 if (Inst.getOpcode() == Mips::ROLImm) {
4916 uint64_t MaxShift = 32;
4917 uint64_t ShiftValue = ImmValue;
4918 if (ImmValue != 0)
4919 ShiftValue = MaxShift - ImmValue;
4920 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4921 return false;
4922 }
4923
4924 if (Inst.getOpcode() == Mips::RORImm) {
4925 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4926 return false;
4927 }
4928
4929 return true;
4930 }
4931
4932 if (hasMips32()) {
4933 if (ImmValue == 0) {
4934 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4935 return false;
4936 }
4937
4938 switch (Inst.getOpcode()) {
4939 default:
4940 llvm_unreachable("unexpected instruction opcode");
4941 case Mips::ROLImm:
4942 FirstShift = Mips::SLL;
4943 SecondShift = Mips::SRL;
4944 break;
4945 case Mips::RORImm:
4946 FirstShift = Mips::SRL;
4947 SecondShift = Mips::SLL;
4948 break;
4949 }
4950
4951 ATReg = getATReg(Inst.getLoc());
4952 if (!ATReg)
4953 return true;
4954
4955 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4956 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4957 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4958
4959 return false;
4960 }
4961
4962 return true;
4963}
4964
4965bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4966 const MCSubtargetInfo *STI) {
4967 MipsTargetStreamer &TOut = getTargetStreamer();
4968 MCRegister ATReg;
4969 MCRegister DReg = Inst.getOperand(0).getReg();
4970 MCRegister SReg = Inst.getOperand(1).getReg();
4971 MCRegister TReg = Inst.getOperand(2).getReg();
4972 MCRegister TmpReg = DReg;
4973
4974 unsigned FirstShift = Mips::NOP;
4975 unsigned SecondShift = Mips::NOP;
4976
4977 if (hasMips64r2()) {
4978 if (TmpReg == SReg) {
4979 TmpReg = getATReg(Inst.getLoc());
4980 if (!TmpReg)
4981 return true;
4982 }
4983
4984 if (Inst.getOpcode() == Mips::DROL) {
4985 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4986 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4987 return false;
4988 }
4989
4990 if (Inst.getOpcode() == Mips::DROR) {
4991 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4992 return false;
4993 }
4994
4995 return true;
4996 }
4997
4998 if (hasMips64()) {
4999 switch (Inst.getOpcode()) {
5000 default:
5001 llvm_unreachable("unexpected instruction opcode");
5002 case Mips::DROL:
5003 FirstShift = Mips::DSRLV;
5004 SecondShift = Mips::DSLLV;
5005 break;
5006 case Mips::DROR:
5007 FirstShift = Mips::DSLLV;
5008 SecondShift = Mips::DSRLV;
5009 break;
5010 }
5011
5012 ATReg = getATReg(Inst.getLoc());
5013 if (!ATReg)
5014 return true;
5015
5016 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5017 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5018 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5019 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5020
5021 return false;
5022 }
5023
5024 return true;
5025}
5026
5027bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5028 MCStreamer &Out,
5029 const MCSubtargetInfo *STI) {
5030 MipsTargetStreamer &TOut = getTargetStreamer();
5031 MCRegister ATReg;
5032 MCRegister DReg = Inst.getOperand(0).getReg();
5033 MCRegister SReg = Inst.getOperand(1).getReg();
5034 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5035
5036 unsigned FirstShift = Mips::NOP;
5037 unsigned SecondShift = Mips::NOP;
5038
5039 MCInst TmpInst;
5040
5041 if (hasMips64r2()) {
5042 unsigned FinalOpcode = Mips::NOP;
5043 if (ImmValue == 0)
5044 FinalOpcode = Mips::DROTR;
5045 else if (ImmValue % 32 == 0)
5046 FinalOpcode = Mips::DROTR32;
5047 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5048 if (Inst.getOpcode() == Mips::DROLImm)
5049 FinalOpcode = Mips::DROTR32;
5050 else
5051 FinalOpcode = Mips::DROTR;
5052 } else if (ImmValue >= 33) {
5053 if (Inst.getOpcode() == Mips::DROLImm)
5054 FinalOpcode = Mips::DROTR;
5055 else
5056 FinalOpcode = Mips::DROTR32;
5057 }
5058
5059 uint64_t ShiftValue = ImmValue % 32;
5060 if (Inst.getOpcode() == Mips::DROLImm)
5061 ShiftValue = (32 - ImmValue % 32) % 32;
5062
5063 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5064
5065 return false;
5066 }
5067
5068 if (hasMips64()) {
5069 if (ImmValue == 0) {
5070 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5071 return false;
5072 }
5073
5074 switch (Inst.getOpcode()) {
5075 default:
5076 llvm_unreachable("unexpected instruction opcode");
5077 case Mips::DROLImm:
5078 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5079 FirstShift = Mips::DSLL;
5080 SecondShift = Mips::DSRL32;
5081 }
5082 if (ImmValue == 32) {
5083 FirstShift = Mips::DSLL32;
5084 SecondShift = Mips::DSRL32;
5085 }
5086 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5087 FirstShift = Mips::DSLL32;
5088 SecondShift = Mips::DSRL;
5089 }
5090 break;
5091 case Mips::DRORImm:
5092 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5093 FirstShift = Mips::DSRL;
5094 SecondShift = Mips::DSLL32;
5095 }
5096 if (ImmValue == 32) {
5097 FirstShift = Mips::DSRL32;
5098 SecondShift = Mips::DSLL32;
5099 }
5100 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5101 FirstShift = Mips::DSRL32;
5102 SecondShift = Mips::DSLL;
5103 }
5104 break;
5105 }
5106
5107 ATReg = getATReg(Inst.getLoc());
5108 if (!ATReg)
5109 return true;
5110
5111 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5112 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5113 Inst.getLoc(), STI);
5114 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5115
5116 return false;
5117 }
5118
5119 return true;
5120}
5121
5122bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5123 const MCSubtargetInfo *STI) {
5124 MipsTargetStreamer &TOut = getTargetStreamer();
5125 MCRegister FirstRegOp = Inst.getOperand(0).getReg();
5126 MCRegister SecondRegOp = Inst.getOperand(1).getReg();
5127
5128 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5129 if (FirstRegOp != SecondRegOp)
5130 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5131 else
5132 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5133 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5134
5135 return false;
5136}
5137
5138bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5139 const MCSubtargetInfo *STI) {
5140 MipsTargetStreamer &TOut = getTargetStreamer();
5141 MCRegister ATReg;
5142 MCRegister DstReg = Inst.getOperand(0).getReg();
5143 MCRegister SrcReg = Inst.getOperand(1).getReg();
5144 int32_t ImmValue = Inst.getOperand(2).getImm();
5145
5146 ATReg = getATReg(IDLoc);
5147 if (!ATReg)
5148 return true;
5149
5150 loadImmediate(ImmValue, ATReg, MCRegister(), true, false, IDLoc, Out, STI);
5151
5152 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5153 SrcReg, ATReg, IDLoc, STI);
5154
5155 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5156
5157 return false;
5158}
5159
5160bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5161 const MCSubtargetInfo *STI) {
5162 MipsTargetStreamer &TOut = getTargetStreamer();
5163 MCRegister ATReg;
5164 MCRegister DstReg = Inst.getOperand(0).getReg();
5165 MCRegister SrcReg = Inst.getOperand(1).getReg();
5166 MCRegister TmpReg = Inst.getOperand(2).getReg();
5167
5168 ATReg = getATReg(Inst.getLoc());
5169 if (!ATReg)
5170 return true;
5171
5172 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5173 SrcReg, TmpReg, IDLoc, STI);
5174
5175 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5176
5177 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5178 DstReg, DstReg, 0x1F, IDLoc, STI);
5179
5180 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5181
5182 if (useTraps()) {
5183 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5184 } else {
5185 MCContext &Context = TOut.getContext();
5186 MCSymbol * BrTarget = Context.createTempSymbol();
5187 MCOperand LabelOp =
5189
5190 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5191 if (AssemblerOptions.back()->isReorder())
5192 TOut.emitNop(IDLoc, STI);
5193 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5194
5195 TOut.getStreamer().emitLabel(BrTarget);
5196 }
5197 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5198
5199 return false;
5200}
5201
5202bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5203 const MCSubtargetInfo *STI) {
5204 MipsTargetStreamer &TOut = getTargetStreamer();
5205 MCRegister ATReg;
5206 MCRegister DstReg = Inst.getOperand(0).getReg();
5207 MCRegister SrcReg = Inst.getOperand(1).getReg();
5208 MCRegister TmpReg = Inst.getOperand(2).getReg();
5209
5210 ATReg = getATReg(IDLoc);
5211 if (!ATReg)
5212 return true;
5213
5214 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5215 SrcReg, TmpReg, IDLoc, STI);
5216
5217 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5218 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5219 if (useTraps()) {
5220 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5221 } else {
5222 MCContext &Context = TOut.getContext();
5223 MCSymbol * BrTarget = Context.createTempSymbol();
5224 MCOperand LabelOp =
5226
5227 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5228 if (AssemblerOptions.back()->isReorder())
5229 TOut.emitNop(IDLoc, STI);
5230 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5231
5232 TOut.getStreamer().emitLabel(BrTarget);
5233 }
5234
5235 return false;
5236}
5237
5238bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5239 const MCSubtargetInfo *STI) {
5240 MipsTargetStreamer &TOut = getTargetStreamer();
5241 MCRegister DstReg = Inst.getOperand(0).getReg();
5242 MCRegister SrcReg = Inst.getOperand(1).getReg();
5243 MCRegister TmpReg = Inst.getOperand(2).getReg();
5244
5245 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5246 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5247
5248 return false;
5249}
5250
5251// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5252// lw $<reg+1>>, offset+4($reg2)'
5253// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5254// sw $<reg+1>>, offset+4($reg2)'
5255// for O32.
5256bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5257 MCStreamer &Out,
5258 const MCSubtargetInfo *STI,
5259 bool IsLoad) {
5260 if (!isABI_O32())
5261 return true;
5262
5263 warnIfNoMacro(IDLoc);
5264
5265 MipsTargetStreamer &TOut = getTargetStreamer();
5266 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5267 MCRegister FirstReg = Inst.getOperand(0).getReg();
5268 MCRegister SecondReg = nextReg(FirstReg);
5269 MCRegister BaseReg = Inst.getOperand(1).getReg();
5270 if (!SecondReg)
5271 return true;
5272
5273 warnIfRegIndexIsAT(FirstReg, IDLoc);
5274
5275 assert(Inst.getOperand(2).isImm() &&
5276 "Offset for load macro is not immediate!");
5277
5278 MCOperand &FirstOffset = Inst.getOperand(2);
5279 signed NextOffset = FirstOffset.getImm() + 4;
5280 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5281
5282 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5283 return true;
5284
5285 // For loads, clobber the base register with the second load instead of the
5286 // first if the BaseReg == FirstReg.
5287 if (FirstReg != BaseReg || !IsLoad) {
5288 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5289 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5290 } else {
5291 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5292 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5293 }
5294
5295 return false;
5296}
5297
5298
5299// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5300// swc1 $<reg>, offset+4($reg2)'
5301// or if little endian to 'swc1 $<reg>, offset($reg2);
5302// swc1 $<reg+1>, offset+4($reg2)'
5303// for Mips1.
5304bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5305 MCStreamer &Out,
5306 const MCSubtargetInfo *STI) {
5307 if (!isABI_O32())
5308 return true;
5309
5310 warnIfNoMacro(IDLoc);
5311
5312 MipsTargetStreamer &TOut = getTargetStreamer();
5313 unsigned Opcode = Mips::SWC1;
5314 MCRegister FirstReg = Inst.getOperand(0).getReg();
5315 MCRegister SecondReg = nextReg(FirstReg);
5316 MCRegister BaseReg = Inst.getOperand(1).getReg();
5317 if (!SecondReg)
5318 return true;
5319
5320 warnIfRegIndexIsAT(FirstReg, IDLoc);
5321
5322 assert(Inst.getOperand(2).isImm() &&
5323 "Offset for macro is not immediate!");
5324
5325 MCOperand &FirstOffset = Inst.getOperand(2);
5326 signed NextOffset = FirstOffset.getImm() + 4;
5327 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5328
5329 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5330 return true;
5331
5332 if (!IsLittleEndian)
5333 std::swap(FirstReg, SecondReg);
5334
5335 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5336 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5337
5338 return false;
5339}
5340
5341bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5342 const MCSubtargetInfo *STI) {
5343 MipsTargetStreamer &TOut = getTargetStreamer();
5344
5345 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5346 assert(Inst.getOperand(0).isReg() &&
5347 Inst.getOperand(1).isReg() &&
5348 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5349
5350 MCRegister DstReg = Inst.getOperand(0).getReg();
5351 MCRegister SrcReg = Inst.getOperand(1).getReg();
5352 MCRegister OpReg = Inst.getOperand(2).getReg();
5353
5354 warnIfNoMacro(IDLoc);
5355
5356 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5357 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5358 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5359 return false;
5360 }
5361
5362 MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5363 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5364 return false;
5365}
5366
5367bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5368 const MCSubtargetInfo *STI) {
5369 MipsTargetStreamer &TOut = getTargetStreamer();
5370
5371 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5372 assert(Inst.getOperand(0).isReg() &&
5373 Inst.getOperand(1).isReg() &&
5374 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5375
5376 MCRegister DstReg = Inst.getOperand(0).getReg();
5377 MCRegister SrcReg = Inst.getOperand(1).getReg();
5378 int64_t Imm = Inst.getOperand(2).getImm();
5379
5380 warnIfNoMacro(IDLoc);
5381
5382 if (Imm == 0) {
5383 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5384 return false;
5385 }
5386
5387 if (SrcReg == Mips::ZERO) {
5388 Warning(IDLoc, "comparison is always false");
5389 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5390 DstReg, SrcReg, SrcReg, IDLoc, STI);
5391 return false;
5392 }
5393
5394 unsigned Opc;
5395 if (Imm > -0x8000 && Imm < 0) {
5396 Imm = -Imm;
5397 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5398 } else {
5399 Opc = Mips::XORi;
5400 }
5401
5402 if (!isUInt<16>(Imm)) {
5403 MCRegister ATReg = getATReg(IDLoc);
5404 if (!ATReg)
5405 return true;
5406
5407 if (loadImmediate(Imm, ATReg, MCRegister(), true, isGP64bit(), IDLoc, Out,
5408 STI))
5409 return true;
5410
5411 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5412 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5413 return false;
5414 }
5415
5416 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5417 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5418 return false;
5419}
5420
5421bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5422 const MCSubtargetInfo *STI) {
5423
5424 MipsTargetStreamer &TOut = getTargetStreamer();
5425
5426 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5427 assert(Inst.getOperand(0).isReg() &&
5428 Inst.getOperand(1).isReg() &&
5429 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5430
5431 MCRegister DstReg = Inst.getOperand(0).getReg();
5432 MCRegister SrcReg = Inst.getOperand(1).getReg();
5433 MCRegister OpReg = Inst.getOperand(2).getReg();
5434
5435 warnIfNoMacro(IDLoc);
5436
5437 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5438 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5439 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5440 return false;
5441 }
5442
5443 MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5444 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5445 return false;
5446}
5447
5448bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5449 const MCSubtargetInfo *STI) {
5450 MipsTargetStreamer &TOut = getTargetStreamer();
5451
5452 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5453 assert(Inst.getOperand(0).isReg() &&
5454 Inst.getOperand(1).isReg() &&
5455 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5456
5457 MCRegister DstReg = Inst.getOperand(0).getReg();
5458 MCRegister SrcReg = Inst.getOperand(1).getReg();
5459 int64_t ImmValue = Inst.getOperand(2).getImm();
5460
5461 warnIfNoMacro(IDLoc);
5462
5463 if (ImmValue == 0) {
5464 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5465 return false;
5466 }
5467
5468 if (SrcReg == Mips::ZERO) {
5469 Warning(IDLoc, "comparison is always true");
5470 if (loadImmediate(1, DstReg, MCRegister(), true, false, IDLoc, Out, STI))
5471 return true;
5472 return false;
5473 }
5474
5475 unsigned Opc;
5476 if (ImmValue > -0x8000 && ImmValue < 0) {
5477 ImmValue = -ImmValue;
5478 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5479 } else {
5480 Opc = Mips::XORi;
5481 }
5482
5483 if (isUInt<16>(ImmValue)) {
5484 TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5485 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5486 return false;
5487 }
5488
5489 MCRegister ATReg = getATReg(IDLoc);
5490 if (!ATReg)
5491 return true;
5492
5493 if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue), false,
5494 IDLoc, Out, STI))
5495 return true;
5496
5497 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5498 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5499 return false;
5500}
5501
5502// Map the DSP accumulator and control register to the corresponding gpr
5503// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5504// do not map the DSP registers contigously to gpr registers.
5505static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5506 switch (Inst.getOpcode()) {
5507 case Mips::MFTLO:
5508 case Mips::MTTLO:
5509 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5510 case Mips::AC0:
5511 return Mips::ZERO;
5512 case Mips::AC1:
5513 return Mips::A0;
5514 case Mips::AC2:
5515 return Mips::T0;
5516 case Mips::AC3:
5517 return Mips::T4;
5518 default:
5519 llvm_unreachable("Unknown register for 'mttr' alias!");
5520 }
5521 case Mips::MFTHI:
5522 case Mips::MTTHI:
5523 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5524 case Mips::AC0:
5525 return Mips::AT;
5526 case Mips::AC1:
5527 return Mips::A1;
5528 case Mips::AC2:
5529 return Mips::T1;
5530 case Mips::AC3:
5531 return Mips::T5;
5532 default:
5533 llvm_unreachable("Unknown register for 'mttr' alias!");
5534 }
5535 case Mips::MFTACX:
5536 case Mips::MTTACX:
5537 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5538 case Mips::AC0:
5539 return Mips::V0;
5540 case Mips::AC1:
5541 return Mips::A2;
5542 case Mips::AC2:
5543 return Mips::T2;
5544 case Mips::AC3:
5545 return Mips::T6;
5546 default:
5547 llvm_unreachable("Unknown register for 'mttr' alias!");
5548 }
5549 case Mips::MFTDSP:
5550 case Mips::MTTDSP:
5551 return Mips::S0;
5552 default:
5553 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5554 }
5555}
5556
5557// Map the floating point register operand to the corresponding register
5558// operand.
5559static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5560 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg().id()) {
5561 case Mips::F0: return Mips::ZERO;
5562 case Mips::F1: return Mips::AT;
5563 case Mips::F2: return Mips::V0;
5564 case Mips::F3: return Mips::V1;
5565 case Mips::F4: return Mips::A0;
5566 case Mips::F5: return Mips::A1;
5567 case Mips::F6: return Mips::A2;
5568 case Mips::F7: return Mips::A3;
5569 case Mips::F8: return Mips::T0;
5570 case Mips::F9: return Mips::T1;
5571 case Mips::F10: return Mips::T2;
5572 case Mips::F11: return Mips::T3;
5573 case Mips::F12: return Mips::T4;
5574 case Mips::F13: return Mips::T5;
5575 case Mips::F14: return Mips::T6;
5576 case Mips::F15: return Mips::T7;
5577 case Mips::F16: return Mips::S0;
5578 case Mips::F17: return Mips::S1;
5579 case Mips::F18: return Mips::S2;
5580 case Mips::F19: return Mips::S3;
5581 case Mips::F20: return Mips::S4;
5582 case Mips::F21: return Mips::S5;
5583 case Mips::F22: return Mips::S6;
5584 case Mips::F23: return Mips::S7;
5585 case Mips::F24: return Mips::T8;
5586 case Mips::F25: return Mips::T9;
5587 case Mips::F26: return Mips::K0;
5588 case Mips::F27: return Mips::K1;
5589 case Mips::F28: return Mips::GP;
5590 case Mips::F29: return Mips::SP;
5591 case Mips::F30: return Mips::FP;
5592 case Mips::F31: return Mips::RA;
5593 default: llvm_unreachable("Unknown register for mttc1 alias!");
5594 }
5595}
5596
5597// Map the coprocessor operand the corresponding gpr register operand.
5598static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5599 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg().id()) {
5600 case Mips::COP00: return Mips::ZERO;
5601 case Mips::COP01: return Mips::AT;
5602 case Mips::COP02: return Mips::V0;
5603 case Mips::COP03: return Mips::V1;
5604 case Mips::COP04: return Mips::A0;
5605 case Mips::COP05: return Mips::A1;
5606 case Mips::COP06: return Mips::A2;
5607 case Mips::COP07: return Mips::A3;
5608 case Mips::COP08: return Mips::T0;
5609 case Mips::COP09: return Mips::T1;
5610 case Mips::COP010: return Mips::T2;
5611 case Mips::COP011: return Mips::T3;
5612 case Mips::COP012: return Mips::T4;
5613 case Mips::COP013: return Mips::T5;
5614 case Mips::COP014: return Mips::T6;
5615 case Mips::COP015: return Mips::T7;
5616 case Mips::COP016: return Mips::S0;
5617 case Mips::COP017: return Mips::S1;
5618 case Mips::COP018: return Mips::S2;
5619 case Mips::COP019: return Mips::S3;
5620 case Mips::COP020: return Mips::S4;
5621 case Mips::COP021: return Mips::S5;
5622 case Mips::COP022: return Mips::S6;
5623 case Mips::COP023: return Mips::S7;
5624 case Mips::COP024: return Mips::T8;
5625 case Mips::COP025: return Mips::T9;
5626 case Mips::COP026: return Mips::K0;
5627 case Mips::COP027: return Mips::K1;
5628 case Mips::COP028: return Mips::GP;
5629 case Mips::COP029: return Mips::SP;
5630 case Mips::COP030: return Mips::FP;
5631 case Mips::COP031: return Mips::RA;
5632 default: llvm_unreachable("Unknown register for mttc0 alias!");
5633 }
5634}
5635
5636/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5637/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5638bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5639 const MCSubtargetInfo *STI) {
5640 MipsTargetStreamer &TOut = getTargetStreamer();
5641 MCRegister rd;
5642 unsigned u = 1;
5643 unsigned sel = 0;
5644 unsigned h = 0;
5645 bool IsMFTR = false;
5646 switch (Inst.getOpcode()) {
5647 case Mips::MFTC0:
5648 IsMFTR = true;
5649 [[fallthrough]];
5650 case Mips::MTTC0:
5651 u = 0;
5652 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5653 sel = Inst.getOperand(2).getImm();
5654 break;
5655 case Mips::MFTGPR:
5656 IsMFTR = true;
5657 [[fallthrough]];
5658 case Mips::MTTGPR:
5659 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5660 break;
5661 case Mips::MFTLO:
5662 case Mips::MFTHI:
5663 case Mips::MFTACX:
5664 case Mips::MFTDSP:
5665 IsMFTR = true;
5666 [[fallthrough]];
5667 case Mips::MTTLO:
5668 case Mips::MTTHI:
5669 case Mips::MTTACX:
5670 case Mips::MTTDSP:
5671 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5672 sel = 1;
5673 break;
5674 case Mips::MFTHC1:
5675 h = 1;
5676 [[fallthrough]];
5677 case Mips::MFTC1:
5678 IsMFTR = true;
5679 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5680 sel = 2;
5681 break;
5682 case Mips::MTTHC1:
5683 h = 1;
5684 [[fallthrough]];
5685 case Mips::MTTC1:
5686 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5687 sel = 2;
5688 break;
5689 case Mips::CFTC1:
5690 IsMFTR = true;
5691 [[fallthrough]];
5692 case Mips::CTTC1:
5693 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5694 sel = 3;
5695 break;
5696 }
5697 MCRegister Op0 = IsMFTR ? Inst.getOperand(0).getReg() : MCRegister(rd);
5698 MCRegister Op1 =
5699 IsMFTR ? MCRegister(rd)
5700 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5701 : Inst.getOperand(0).getReg());
5702
5703 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5704 STI);
5705 return false;
5706}
5707
5708bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5709 const MCSubtargetInfo *STI) {
5710 assert(Inst.getNumOperands() == 3 && "expected three operands");
5711 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5712 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5713
5714 warnIfNoMacro(IDLoc);
5715
5716 MipsTargetStreamer &TOut = getTargetStreamer();
5717 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5718 MCRegister RtReg = Inst.getOperand(0).getReg();
5719 MCRegister BaseReg = Inst.getOperand(1).getReg();
5720 const MCOperand &BaseOp = Inst.getOperand(2);
5721
5722 if (BaseOp.isImm()) {
5723 int64_t ImmValue = BaseOp.getImm();
5724 if (ImmValue == 0) {
5725 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5726 return false;
5727 }
5728 }
5729
5730 MCRegister ATReg = getATReg(IDLoc);
5731 if (!ATReg)
5732 return true;
5733
5734 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5735 return true;
5736
5737 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5738 return false;
5739}
5740
5741unsigned
5742MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5743 const OperandVector &Operands) {
5744 switch (Inst.getOpcode()) {
5745 default:
5746 return Match_Success;
5747 case Mips::DATI:
5748 case Mips::DAHI:
5749 if (static_cast<MipsOperand &>(*Operands[1])
5750 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5751 return Match_Success;
5752 return Match_RequiresSameSrcAndDst;
5753 }
5754}
5755
5756unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5757 switch (Inst.getOpcode()) {
5758 // As described by the MIPSR6 spec, daui must not use the zero operand for
5759 // its source operand.
5760 case Mips::DAUI:
5761 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5762 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5763 return Match_RequiresNoZeroRegister;
5764 return Match_Success;
5765 // As described by the Mips32r2 spec, the registers Rd and Rs for
5766 // jalr.hb must be different.
5767 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5768 // and registers Rd and Base for microMIPS lwp instruction
5769 case Mips::JALR_HB:
5770 case Mips::JALR_HB64:
5771 case Mips::JALRC_HB_MMR6:
5772 case Mips::JALRC_MMR6:
5773 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5774 return Match_RequiresDifferentSrcAndDst;
5775 return Match_Success;
5776 case Mips::LWP_MM:
5777 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5778 return Match_RequiresDifferentSrcAndDst;
5779 return Match_Success;
5780 case Mips::SYNC:
5781 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5782 return Match_NonZeroOperandForSync;
5783 return Match_Success;
5784 case Mips::MFC0:
5785 case Mips::MTC0:
5786 case Mips::MTC2:
5787 case Mips::MFC2:
5788 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5789 return Match_NonZeroOperandForMTCX;
5790 return Match_Success;
5791 // As described the MIPSR6 spec, the compact branches that compare registers
5792 // must:
5793 // a) Not use the zero register.
5794 // b) Not use the same register twice.
5795 // c) rs < rt for bnec, beqc.
5796 // NB: For this case, the encoding will swap the operands as their
5797 // ordering doesn't matter. GAS performs this transformation too.
5798 // Hence, that constraint does not have to be enforced.
5799 //
5800 // The compact branches that branch iff the signed addition of two registers
5801 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5802 // operand swapping. They do not have restriction of using the zero register.
5803 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5804 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5805 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5806 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5807 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5808 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5809 case Mips::BLEZC64:
5810 case Mips::BGEZC64:
5811 case Mips::BGTZC64:
5812 case Mips::BLTZC64:
5813 case Mips::BEQZC64:
5814 case Mips::BNEZC64:
5815 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5816 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5817 return Match_RequiresNoZeroRegister;
5818 return Match_Success;
5819 case Mips::BGEC: case Mips::BGEC_MMR6:
5820 case Mips::BLTC: case Mips::BLTC_MMR6:
5821 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5822 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5823 case Mips::BEQC: case Mips::BEQC_MMR6:
5824 case Mips::BNEC: case Mips::BNEC_MMR6:
5825 case Mips::BGEC64:
5826 case Mips::BLTC64:
5827 case Mips::BGEUC64:
5828 case Mips::BLTUC64:
5829 case Mips::BEQC64:
5830 case Mips::BNEC64:
5831 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5832 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5833 return Match_RequiresNoZeroRegister;
5834 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5835 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5836 return Match_RequiresNoZeroRegister;
5837 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5838 return Match_RequiresDifferentOperands;
5839 return Match_Success;
5840 case Mips::DINS: {
5841 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5842 "Operands must be immediates for dins!");
5843 const signed Pos = Inst.getOperand(2).getImm();
5844 const signed Size = Inst.getOperand(3).getImm();
5845 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5846 return Match_RequiresPosSizeRange0_32;
5847 return Match_Success;
5848 }
5849 case Mips::DINSM:
5850 case Mips::DINSU: {
5851 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5852 "Operands must be immediates for dinsm/dinsu!");
5853 const signed Pos = Inst.getOperand(2).getImm();
5854 const signed Size = Inst.getOperand(3).getImm();
5855 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5856 return Match_RequiresPosSizeRange33_64;
5857 return Match_Success;
5858 }
5859 case Mips::DEXT: {
5860 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5861 "Operands must be immediates for DEXTM!");
5862 const signed Pos = Inst.getOperand(2).getImm();
5863 const signed Size = Inst.getOperand(3).getImm();
5864 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5865 return Match_RequiresPosSizeUImm6;
5866 return Match_Success;
5867 }
5868 case Mips::DEXTM:
5869 case Mips::DEXTU: {
5870 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5871 "Operands must be immediates for dextm/dextu!");
5872 const signed Pos = Inst.getOperand(2).getImm();
5873 const signed Size = Inst.getOperand(3).getImm();
5874 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5875 return Match_RequiresPosSizeRange33_64;
5876 return Match_Success;
5877 }
5878 case Mips::CRC32B: case Mips::CRC32CB:
5879 case Mips::CRC32H: case Mips::CRC32CH:
5880 case Mips::CRC32W: case Mips::CRC32CW:
5881 case Mips::CRC32D: case Mips::CRC32CD:
5882 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5883 return Match_RequiresSameSrcAndDst;
5884 return Match_Success;
5885 }
5886
5887 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5888 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5889 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5890 return Match_NoFCCRegisterForCurrentISA;
5891
5892 return Match_Success;
5893
5894}
5895
5896static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5898 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5899 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5900 if (ErrorLoc == SMLoc())
5901 return Loc;
5902 return ErrorLoc;
5903 }
5904 return Loc;
5905}
5906
5907bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5908 OperandVector &Operands,
5909 MCStreamer &Out,
5910 uint64_t &ErrorInfo,
5911 bool MatchingInlineAsm) {
5912 MCInst Inst;
5913 unsigned MatchResult =
5914 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5915
5916 switch (MatchResult) {
5917 case Match_Success:
5918 if (processInstruction(Inst, IDLoc, Out, STI))
5919 return true;
5920 return false;
5921 case Match_MissingFeature:
5922 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5923 return true;
5924 case Match_InvalidTiedOperand:
5925 Error(IDLoc, "operand must match destination register");
5926 return true;
5927 case Match_InvalidOperand: {
5928 SMLoc ErrorLoc = IDLoc;
5929 if (ErrorInfo != ~0ULL) {
5930 if (ErrorInfo >= Operands.size())
5931 return Error(IDLoc, "too few operands for instruction");
5932
5933 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5934 if (ErrorLoc == SMLoc())
5935 ErrorLoc = IDLoc;
5936 }
5937
5938 return Error(ErrorLoc, "invalid operand for instruction");
5939 }
5940 case Match_NonZeroOperandForSync:
5941 return Error(IDLoc,
5942 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5943 case Match_NonZeroOperandForMTCX:
5944 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5945 case Match_MnemonicFail:
5946 return Error(IDLoc, "invalid instruction");
5947 case Match_RequiresDifferentSrcAndDst:
5948 return Error(IDLoc, "source and destination must be different");
5949 case Match_RequiresDifferentOperands:
5950 return Error(IDLoc, "registers must be different");
5951 case Match_RequiresNoZeroRegister:
5952 return Error(IDLoc, "invalid operand ($zero) for instruction");
5953 case Match_RequiresSameSrcAndDst:
5954 return Error(IDLoc, "source and destination must match");
5955 case Match_NoFCCRegisterForCurrentISA:
5956 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5957 "non-zero fcc register doesn't exist in current ISA level");
5958 case Match_Immz:
5959 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5960 case Match_UImm1_0:
5961 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5962 "expected 1-bit unsigned immediate");
5963 case Match_UImm2_0:
5964 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5965 "expected 2-bit unsigned immediate");
5966 case Match_UImm2_1:
5967 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5968 "expected immediate in range 1 .. 4");
5969 case Match_UImm3_0:
5970 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5971 "expected 3-bit unsigned immediate");
5972 case Match_UImm4_0:
5973 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5974 "expected 4-bit unsigned immediate");
5975 case Match_SImm4_0:
5976 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5977 "expected 4-bit signed immediate");
5978 case Match_UImm5_0:
5979 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5980 "expected 5-bit unsigned immediate");
5981 case Match_SImm5_0:
5982 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5983 "expected 5-bit signed immediate");
5984 case Match_UImm5_1:
5985 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5986 "expected immediate in range 1 .. 32");
5987 case Match_UImm5_32:
5988 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5989 "expected immediate in range 32 .. 63");
5990 case Match_UImm5_33:
5991 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5992 "expected immediate in range 33 .. 64");
5993 case Match_UImm5_0_Report_UImm6:
5994 // This is used on UImm5 operands that have a corresponding UImm5_32
5995 // operand to avoid confusing the user.
5996 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5997 "expected 6-bit unsigned immediate");
5998 case Match_UImm5_Lsl2:
5999 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6000 "expected both 7-bit unsigned immediate and multiple of 4");
6001 case Match_UImmRange2_64:
6002 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6003 "expected immediate in range 2 .. 64");
6004 case Match_UImm6_0:
6005 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6006 "expected 6-bit unsigned immediate");
6007 case Match_UImm6_Lsl2:
6008 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6009 "expected both 8-bit unsigned immediate and multiple of 4");
6010 case Match_SImm6_0:
6011 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6012 "expected 6-bit signed immediate");
6013 case Match_UImm7_0:
6014 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6015 "expected 7-bit unsigned immediate");
6016 case Match_UImm7_N1:
6017 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6018 "expected immediate in range -1 .. 126");
6019 case Match_SImm7_Lsl2:
6020 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6021 "expected both 9-bit signed immediate and multiple of 4");
6022 case Match_UImm8_0:
6023 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6024 "expected 8-bit unsigned immediate");
6025 case Match_UImm10_0:
6026 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6027 "expected 10-bit unsigned immediate");
6028 case Match_SImm10_0:
6029 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6030 "expected 10-bit signed immediate");
6031 case Match_SImm11_0:
6032 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6033 "expected 11-bit signed immediate");
6034 case Match_UImm16:
6035 case Match_UImm16_Relaxed:
6036 case Match_UImm16_AltRelaxed:
6037 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6038 "expected 16-bit unsigned immediate");
6039 case Match_SImm16:
6040 case Match_SImm16_Relaxed:
6041 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6042 "expected 16-bit signed immediate");
6043 case Match_SImm19_Lsl2:
6044 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6045 "expected both 19-bit signed immediate and multiple of 4");
6046 case Match_UImm20_0:
6047 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6048 "expected 20-bit unsigned immediate");
6049 case Match_UImm26_0:
6050 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6051 "expected 26-bit unsigned immediate");
6052 case Match_SImm32:
6053 case Match_SImm32_Relaxed:
6054 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6055 "expected 32-bit signed immediate");
6056 case Match_UImm32_Coerced:
6057 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6058 "expected 32-bit immediate");
6059 case Match_MemSImm9:
6060 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6061 "expected memory with 9-bit signed offset");
6062 case Match_MemSImm10:
6063 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6064 "expected memory with 10-bit signed offset");
6065 case Match_MemSImm10Lsl1:
6066 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6067 "expected memory with 11-bit signed offset and multiple of 2");
6068 case Match_MemSImm10Lsl2:
6069 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6070 "expected memory with 12-bit signed offset and multiple of 4");
6071 case Match_MemSImm10Lsl3:
6072 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6073 "expected memory with 13-bit signed offset and multiple of 8");
6074 case Match_MemSImm11:
6075 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6076 "expected memory with 11-bit signed offset");
6077 case Match_MemSImm12:
6078 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6079 "expected memory with 12-bit signed offset");
6080 case Match_MemSImm16:
6081 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6082 "expected memory with 16-bit signed offset");
6083 case Match_MemSImmPtr:
6084 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6085 "expected memory with 32-bit signed offset");
6086 case Match_RequiresPosSizeRange0_32: {
6087 SMLoc ErrorStart = Operands[3]->getStartLoc();
6088 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6089 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6090 SMRange(ErrorStart, ErrorEnd));
6091 }
6092 case Match_RequiresPosSizeUImm6: {
6093 SMLoc ErrorStart = Operands[3]->getStartLoc();
6094 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6095 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6096 SMRange(ErrorStart, ErrorEnd));
6097 }
6098 case Match_RequiresPosSizeRange33_64: {
6099 SMLoc ErrorStart = Operands[3]->getStartLoc();
6100 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6101 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6102 SMRange(ErrorStart, ErrorEnd));
6103 }
6104 }
6105
6106 llvm_unreachable("Implement any new match types added!");
6107}
6108
6109void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6110 if (RegIndex && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6111 Warning(Loc, "used $at (currently $" + Twine(RegIndex.id()) +
6112 ") without \".set noat\"");
6113}
6114
6115void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6116 if (!AssemblerOptions.back()->isMacro())
6117 Warning(Loc, "macro instruction expanded into multiple instructions");
6118}
6119
6120void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6121 const OperandVector &Operands) {
6122 assert(
6123 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
6124 "Unexpected instruction!");
6125 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6126 MCRegister NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6127 Inst.addOperand(MCOperand::createReg(NextReg));
6128 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6129}
6130
6131void
6132MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6133 SMRange Range, bool ShowColors) {
6134 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6135 Range, SMFixIt(Range, FixMsg),
6136 ShowColors);
6137}
6138
6139int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6140 int CC;
6141
6142 CC = StringSwitch<unsigned>(Name)
6143 .Case("zero", 0)
6144 .Cases({"at", "AT"}, 1)
6145 .Case("a0", 4)
6146 .Case("a1", 5)
6147 .Case("a2", 6)
6148 .Case("a3", 7)
6149 .Case("v0", 2)
6150 .Case("v1", 3)
6151 .Case("s0", 16)
6152 .Case("s1", 17)
6153 .Case("s2", 18)
6154 .Case("s3", 19)
6155 .Case("s4", 20)
6156 .Case("s5", 21)
6157 .Case("s6", 22)
6158 .Case("s7", 23)
6159 .Case("k0", 26)
6160 .Case("k1", 27)
6161 .Case("gp", 28)
6162 .Case("sp", 29)
6163 .Case("fp", 30)
6164 .Case("s8", 30)
6165 .Case("ra", 31)
6166 .Case("t0", 8)
6167 .Case("t1", 9)
6168 .Case("t2", 10)
6169 .Case("t3", 11)
6170 .Case("t4", 12)
6171 .Case("t5", 13)
6172 .Case("t6", 14)
6173 .Case("t7", 15)
6174 .Case("t8", 24)
6175 .Case("t9", 25)
6176 .Default(-1);
6177
6178 if (!(isABI_N32() || isABI_N64()))
6179 return CC;
6180
6181 if (12 <= CC && CC <= 15) {
6182 // Name is one of t4-t7
6183 AsmToken RegTok = getLexer().peekTok();
6184 SMRange RegRange = RegTok.getLocRange();
6185
6186 StringRef FixedName = StringSwitch<StringRef>(Name)
6187 .Case("t4", "t0")
6188 .Case("t5", "t1")
6189 .Case("t6", "t2")
6190 .Case("t7", "t3")
6191 .Default("");
6192 assert(FixedName != "" && "Register name is not one of t4-t7.");
6193
6194 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6195 "Did you mean $" + FixedName + "?", RegRange);
6196 }
6197
6198 // Although SGI documentation just cuts out t0-t3 for n32/n64,
6199 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
6200 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
6201 if (8 <= CC && CC <= 11)
6202 CC += 4;
6203
6204 if (CC == -1)
6205 CC = StringSwitch<unsigned>(Name)
6206 .Case("a4", 8)
6207 .Case("a5", 9)
6208 .Case("a6", 10)
6209 .Case("a7", 11)
6210 .Case("kt0", 26)
6211 .Case("kt1", 27)
6212 .Default(-1);
6213
6214 return CC;
6215}
6216
6217int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6218 int CC;
6219
6220 CC = StringSwitch<unsigned>(Name)
6221 .Case("hwr_cpunum", 0)
6222 .Case("hwr_synci_step", 1)
6223 .Case("hwr_cc", 2)
6224 .Case("hwr_ccres", 3)
6225 .Case("hwr_ulr", 29)
6226 .Default(-1);
6227
6228 return CC;
6229}
6230
6231int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6232 if (Name[0] == 'f') {
6233 StringRef NumString = Name.substr(1);
6234 unsigned IntVal;
6235 if (NumString.getAsInteger(10, IntVal))
6236 return -1; // This is not an integer.
6237 if (IntVal > 31) // Maximum index for fpu register.
6238 return -1;
6239 return IntVal;
6240 }
6241 return -1;
6242}
6243
6244int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6245 if (Name.starts_with("fcc")) {
6246 StringRef NumString = Name.substr(3);
6247 unsigned IntVal;
6248 if (NumString.getAsInteger(10, IntVal))
6249 return -1; // This is not an integer.
6250 if (IntVal > 7) // There are only 8 fcc registers.
6251 return -1;
6252 return IntVal;
6253 }
6254 return -1;
6255}
6256
6257int MipsAsmParser::matchACRegisterName(StringRef Name) {
6258 if (Name.starts_with("ac")) {
6259 StringRef NumString = Name.substr(2);
6260 unsigned IntVal;
6261 if (NumString.getAsInteger(10, IntVal))
6262 return -1; // This is not an integer.
6263 if (IntVal > 3) // There are only 3 acc registers.
6264 return -1;
6265 return IntVal;
6266 }
6267 return -1;
6268}
6269
6270int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6271 unsigned IntVal;
6272
6273 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6274 return -1;
6275
6276 if (IntVal > 31)
6277 return -1;
6278
6279 return IntVal;
6280}
6281
6282int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6283 int CC;
6284
6285 CC = StringSwitch<unsigned>(Name)
6286 .Case("msair", 0)
6287 .Case("msacsr", 1)
6288 .Case("msaaccess", 2)
6289 .Case("msasave", 3)
6290 .Case("msamodify", 4)
6291 .Case("msarequest", 5)
6292 .Case("msamap", 6)
6293 .Case("msaunmap", 7)
6294 .Default(-1);
6295
6296 return CC;
6297}
6298
6299bool MipsAsmParser::canUseATReg() {
6300 return AssemblerOptions.back()->getATRegIndex() != 0;
6301}
6302
6303MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6304 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6305 if (ATIndex == 0) {
6306 reportParseError(Loc,
6307 "pseudo-instruction requires $at, which is not available");
6308 return 0;
6309 }
6310 MCRegister AT = getReg(
6311 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6312 return AT;
6313}
6314
6315MCRegister MipsAsmParser::getReg(int RC, int RegNo) {
6316 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6317}
6318
6319// Parse an expression with optional relocation operator prefixes (e.g. %lo).
6320// Some weird expressions allowed by gas are not supported for simplicity,
6321// e.g. "%lo foo", "(%lo(foo))", "%lo(foo)+1".
6322const MCExpr *MipsAsmParser::parseRelocExpr() {
6323 auto getOp = [](StringRef Op) {
6324 return StringSwitch<Mips::Specifier>(Op)
6325 .Case("call16", Mips::S_GOT_CALL)
6326 .Case("call_hi", Mips::S_CALL_HI16)
6327 .Case("call_lo", Mips::S_CALL_LO16)
6328 .Case("dtprel_hi", Mips::S_DTPREL_HI)
6329 .Case("dtprel_lo", Mips::S_DTPREL_LO)
6330 .Case("got", Mips::S_GOT)
6331 .Case("got_disp", Mips::S_GOT_DISP)
6332 .Case("got_hi", Mips::S_GOT_HI16)
6333 .Case("got_lo", Mips::S_GOT_LO16)
6334 .Case("got_ofst", Mips::S_GOT_OFST)
6335 .Case("got_page", Mips::S_GOT_PAGE)
6336 .Case("gottprel", Mips::S_GOTTPREL)
6337 .Case("gp_rel", Mips::S_GPREL)
6338 .Case("hi", Mips::S_HI)
6339 .Case("higher", Mips::S_HIGHER)
6340 .Case("highest", Mips::S_HIGHEST)
6341 .Case("lo", Mips::S_LO)
6342 .Case("neg", Mips::S_NEG)
6343 .Case("pcrel_hi", Mips::S_PCREL_HI16)
6344 .Case("pcrel_lo", Mips::S_PCREL_LO16)
6345 .Case("tlsgd", Mips::S_TLSGD)
6346 .Case("tlsldm", Mips::S_TLSLDM)
6347 .Case("tprel_hi", Mips::S_TPREL_HI)
6348 .Case("tprel_lo", Mips::S_TPREL_LO)
6349 .Default(Mips::S_None);
6350 };
6351
6352 MCAsmParser &Parser = getParser();
6353 StringRef Name;
6354 const MCExpr *Res = nullptr;
6356 while (parseOptionalToken(AsmToken::Percent)) {
6357 if (Parser.parseIdentifier(Name) ||
6358 Parser.parseToken(AsmToken::LParen, "expected '('"))
6359 return nullptr;
6360 auto Op = getOp(Name);
6361 if (Op == Mips::S_None) {
6362 Error(Parser.getTok().getLoc(), "invalid relocation operator");
6363 return nullptr;
6364 }
6365 Ops.push_back(Op);
6366 }
6367 if (Parser.parseExpression(Res))
6368 return nullptr;
6369 while (Ops.size()) {
6370 if (Parser.parseToken(AsmToken::RParen, "expected ')'"))
6371 return nullptr;
6372 Res = MCSpecifierExpr::create(Res, Ops.pop_back_val(), getContext());
6373 }
6374 return Res;
6375}
6376
6377bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6378 MCAsmParser &Parser = getParser();
6379 LLVM_DEBUG(dbgs() << "parseOperand\n");
6380
6381 // Check if the current operand has a custom associated parser, if so, try to
6382 // custom parse the operand, or fallback to the general approach.
6383 // Setting the third parameter to true tells the parser to keep parsing even
6384 // if the operands are not supported with the current feature set. In this
6385 // case, the instruction matcher will output a "instruction requires a CPU
6386 // feature not currently enabled" error. If this were false, the parser would
6387 // stop here and output a less useful "invalid operand" error.
6388 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic, true);
6389 if (Res.isSuccess())
6390 return false;
6391 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6392 // there was a match, but an error occurred, in which case, just return that
6393 // the operand parsing failed.
6394 if (Res.isFailure())
6395 return true;
6396
6397 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6398
6399 switch (getLexer().getKind()) {
6400 case AsmToken::Dollar: {
6401 // Parse the register.
6402 SMLoc S = Parser.getTok().getLoc();
6403
6404 // Almost all registers have been parsed by custom parsers. There is only
6405 // one exception to this. $zero (and it's alias $0) will reach this point
6406 // for div, divu, and similar instructions because it is not an operand
6407 // to the instruction definition but an explicit register. Special case
6408 // this situation for now.
6409 if (!parseAnyRegister(Operands).isNoMatch())
6410 return false;
6411
6412 // Maybe it is a symbol reference.
6413 StringRef Identifier;
6414 if (Parser.parseIdentifier(Identifier))
6415 return true;
6416
6417 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6418 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
6419 // Otherwise create a symbol reference.
6420 const MCExpr *SymRef = MCSymbolRefExpr::create(Sym, getContext());
6421
6422 Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this));
6423 return false;
6424 }
6425 default: {
6426 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6427 const MCExpr *Expr = parseRelocExpr();
6428 if (!Expr)
6429 return true;
6430 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6431 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6432 return false;
6433 }
6434 } // switch(getLexer().getKind())
6435 return true;
6436}
6437
6438bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
6439 SMLoc &EndLoc) {
6440 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6441}
6442
6443ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6444 SMLoc &EndLoc) {
6446 ParseStatus Res = parseAnyRegister(Operands);
6447 if (Res.isSuccess()) {
6448 assert(Operands.size() == 1);
6449 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6450 StartLoc = Operand.getStartLoc();
6451 EndLoc = Operand.getEndLoc();
6452
6453 // AFAIK, we only support numeric registers and named GPR's in CFI
6454 // directives.
6455 // Don't worry about eating tokens before failing. Using an unrecognised
6456 // register is a parse error.
6457 if (Operand.isGPRAsmReg()) {
6458 // Resolve to GPR32 or GPR64 appropriately.
6459 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6460 }
6461
6462 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6463 }
6464
6465 assert(Operands.size() == 0);
6466 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6467}
6468
6469ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6470 MCAsmParser &Parser = getParser();
6471 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6472 const MCExpr *IdVal = nullptr;
6473 SMLoc S;
6474 bool isParenExpr = false;
6475 ParseStatus Res = ParseStatus::NoMatch;
6476 // First operand is the offset.
6477 S = Parser.getTok().getLoc();
6478
6479 if (getLexer().getKind() == AsmToken::LParen) {
6480 Parser.Lex();
6481 isParenExpr = true;
6482 }
6483
6484 if (getLexer().getKind() != AsmToken::Dollar) {
6485 IdVal = parseRelocExpr();
6486 if (!IdVal)
6487 return ParseStatus::Failure;
6488 if (isParenExpr && Parser.parseRParen())
6489 return ParseStatus::Failure;
6490
6491 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6492 if (Tok.isNot(AsmToken::LParen)) {
6493 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6494 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6495 SMLoc E =
6497 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6498 return ParseStatus::Success;
6499 }
6500 if (Tok.is(AsmToken::EndOfStatement)) {
6501 SMLoc E =
6503
6504 // Zero register assumed, add a memory operand with ZERO as its base.
6505 // "Base" will be managed by k_Memory.
6506 auto Base = MipsOperand::createGPRReg(
6507 0, "0", getContext().getRegisterInfo(), S, E, *this);
6508 Operands.push_back(
6509 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6510 return ParseStatus::Success;
6511 }
6512 MCBinaryExpr::Opcode Opcode;
6513 // GAS and LLVM treat comparison operators different. GAS will generate -1
6514 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6515 // highly unlikely to be found in a memory offset expression, we don't
6516 // handle them.
6517 switch (Tok.getKind()) {
6518 case AsmToken::Plus:
6519 Opcode = MCBinaryExpr::Add;
6520 Parser.Lex();
6521 break;
6522 case AsmToken::Minus:
6523 Opcode = MCBinaryExpr::Sub;
6524 Parser.Lex();
6525 break;
6526 case AsmToken::Star:
6527 Opcode = MCBinaryExpr::Mul;
6528 Parser.Lex();
6529 break;
6530 case AsmToken::Pipe:
6531 Opcode = MCBinaryExpr::Or;
6532 Parser.Lex();
6533 break;
6534 case AsmToken::Amp:
6535 Opcode = MCBinaryExpr::And;
6536 Parser.Lex();
6537 break;
6538 case AsmToken::LessLess:
6539 Opcode = MCBinaryExpr::Shl;
6540 Parser.Lex();
6541 break;
6543 Opcode = MCBinaryExpr::LShr;
6544 Parser.Lex();
6545 break;
6546 case AsmToken::Caret:
6547 Opcode = MCBinaryExpr::Xor;
6548 Parser.Lex();
6549 break;
6550 case AsmToken::Slash:
6551 Opcode = MCBinaryExpr::Div;
6552 Parser.Lex();
6553 break;
6554 case AsmToken::Percent:
6555 Opcode = MCBinaryExpr::Mod;
6556 Parser.Lex();
6557 break;
6558 default:
6559 return Error(Parser.getTok().getLoc(), "'(' or expression expected");
6560 }
6561 const MCExpr * NextExpr;
6562 if (getParser().parseExpression(NextExpr))
6563 return ParseStatus::Failure;
6564 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6565 }
6566
6567 Parser.Lex(); // Eat the '(' token.
6568 }
6569
6570 Res = parseAnyRegister(Operands);
6571 if (!Res.isSuccess())
6572 return Res;
6573
6574 if (Parser.getTok().isNot(AsmToken::RParen))
6575 return Error(Parser.getTok().getLoc(), "')' expected");
6576
6577 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6578
6579 Parser.Lex(); // Eat the ')' token.
6580
6581 if (!IdVal)
6582 IdVal = MCConstantExpr::create(0, getContext());
6583
6584 // Replace the register operand with the memory operand.
6585 std::unique_ptr<MipsOperand> op(
6586 static_cast<MipsOperand *>(Operands.back().release()));
6587 // Remove the register from the operands.
6588 // "op" will be managed by k_Memory.
6589 Operands.pop_back();
6590 // Add the memory operand.
6591 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6592 int64_t Imm;
6593 if (IdVal->evaluateAsAbsolute(Imm))
6594 IdVal = MCConstantExpr::create(Imm, getContext());
6595 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6596 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6597 getContext());
6598 }
6599
6600 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6601 return ParseStatus::Success;
6602}
6603
6604bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6605 MCAsmParser &Parser = getParser();
6606 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6607 if (!Sym)
6608 return false;
6609
6610 SMLoc S = Parser.getTok().getLoc();
6611 if (Sym->isVariable()) {
6612 const MCExpr *Expr = Sym->getVariableValue();
6613 if (Expr->getKind() == MCExpr::SymbolRef) {
6614 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6615 StringRef DefSymbol = Ref->getSymbol().getName();
6616 if (DefSymbol.starts_with("$")) {
6617 ParseStatus Res =
6618 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6619 if (Res.isSuccess()) {
6620 Parser.Lex();
6621 return true;
6622 }
6623 if (Res.isFailure())
6624 llvm_unreachable("Should never fail");
6625 }
6626 }
6627 } else if (Sym->isUndefined()) {
6628 // If symbol is unset, it might be created in the `parseSetAssignment`
6629 // routine as an alias for a numeric register name.
6630 // Lookup in the aliases list.
6631 auto Entry = RegisterSets.find(Sym->getName());
6632 if (Entry != RegisterSets.end()) {
6633 ParseStatus Res =
6634 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6635 if (Res.isSuccess()) {
6636 Parser.Lex();
6637 return true;
6638 }
6639 }
6640 }
6641
6642 return false;
6643}
6644
6645ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6646 OperandVector &Operands, StringRef Identifier, SMLoc S) {
6647 int Index = matchCPURegisterName(Identifier);
6648 if (Index != -1) {
6649 Operands.push_back(MipsOperand::createGPRReg(
6650 Index, Identifier, getContext().getRegisterInfo(), S,
6651 getLexer().getLoc(), *this));
6652 return ParseStatus::Success;
6653 }
6654
6655 Index = matchHWRegsRegisterName(Identifier);
6656 if (Index != -1) {
6657 Operands.push_back(MipsOperand::createHWRegsReg(
6658 Index, Identifier, getContext().getRegisterInfo(), S,
6659 getLexer().getLoc(), *this));
6660 return ParseStatus::Success;
6661 }
6662
6663 Index = matchFPURegisterName(Identifier);
6664 if (Index != -1) {
6665 Operands.push_back(MipsOperand::createFGRReg(
6666 Index, Identifier, getContext().getRegisterInfo(), S,
6667 getLexer().getLoc(), *this));
6668 return ParseStatus::Success;
6669 }
6670
6671 Index = matchFCCRegisterName(Identifier);
6672 if (Index != -1) {
6673 Operands.push_back(MipsOperand::createFCCReg(
6674 Index, Identifier, getContext().getRegisterInfo(), S,
6675 getLexer().getLoc(), *this));
6676 return ParseStatus::Success;
6677 }
6678
6679 Index = matchACRegisterName(Identifier);
6680 if (Index != -1) {
6681 Operands.push_back(MipsOperand::createACCReg(
6682 Index, Identifier, getContext().getRegisterInfo(), S,
6683 getLexer().getLoc(), *this));
6684 return ParseStatus::Success;
6685 }
6686
6687 Index = matchMSA128RegisterName(Identifier);
6688 if (Index != -1) {
6689 Operands.push_back(MipsOperand::createMSA128Reg(
6690 Index, Identifier, getContext().getRegisterInfo(), S,
6691 getLexer().getLoc(), *this));
6692 return ParseStatus::Success;
6693 }
6694
6695 Index = matchMSA128CtrlRegisterName(Identifier);
6696 if (Index != -1) {
6697 Operands.push_back(MipsOperand::createMSACtrlReg(
6698 Index, Identifier, getContext().getRegisterInfo(), S,
6699 getLexer().getLoc(), *this));
6700 return ParseStatus::Success;
6701 }
6702
6703 return ParseStatus::NoMatch;
6704}
6705
6706ParseStatus
6707MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6708 const AsmToken &Token, SMLoc S) {
6709 if (Token.is(AsmToken::Identifier)) {
6710 LLVM_DEBUG(dbgs() << ".. identifier\n");
6711 StringRef Identifier = Token.getIdentifier();
6712 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6713 }
6714 if (Token.is(AsmToken::Integer)) {
6715 LLVM_DEBUG(dbgs() << ".. integer\n");
6716 int64_t RegNum = Token.getIntVal();
6717 if (RegNum < 0 || RegNum > 31) {
6718 // Show the error, but treat invalid register
6719 // number as a normal one to continue parsing
6720 // and catch other possible errors.
6721 Error(getLexer().getLoc(), "invalid register number");
6722 }
6723 Operands.push_back(MipsOperand::createNumericReg(
6724 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6725 Token.getLoc(), *this));
6726 return ParseStatus::Success;
6727 }
6728
6729 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6730
6731 return ParseStatus::NoMatch;
6732}
6733
6734ParseStatus
6735MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6736 auto Token = getLexer().peekTok(false);
6737 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6738}
6739
6740ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6741 MCAsmParser &Parser = getParser();
6742 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6743
6744 auto Token = Parser.getTok();
6745
6746 SMLoc S = Token.getLoc();
6747
6748 if (Token.isNot(AsmToken::Dollar)) {
6749 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6750 if (Token.is(AsmToken::Identifier)) {
6751 if (searchSymbolAlias(Operands))
6752 return ParseStatus::Success;
6753 }
6754 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6755 return ParseStatus::NoMatch;
6756 }
6757 LLVM_DEBUG(dbgs() << ".. $\n");
6758
6759 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6760 if (Res.isSuccess()) {
6761 Parser.Lex(); // $
6762 Parser.Lex(); // identifier
6763 }
6764 return Res;
6765}
6766
6767ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6768 MCAsmParser &Parser = getParser();
6769 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6770
6771 SMLoc S = getLexer().getLoc();
6772
6773 // Registers are a valid target and have priority over symbols.
6774 ParseStatus Res = parseAnyRegister(Operands);
6775 if (!Res.isNoMatch())
6776 return Res;
6777
6778 // Integers and expressions are acceptable
6779 const MCExpr *Expr = nullptr;
6780 if (Parser.parseExpression(Expr)) {
6781 // We have no way of knowing if a symbol was consumed so we must ParseFail
6782 return ParseStatus::Failure;
6783 }
6784 Operands.push_back(
6785 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6786 return ParseStatus::Success;
6787}
6788
6789ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) {
6790 MCAsmParser &Parser = getParser();
6791 const MCExpr *IdVal;
6792 // If the first token is '$' we may have register operand. We have to reject
6793 // cases where it is not a register. Complicating the matter is that
6794 // register names are not reserved across all ABIs.
6795 // Peek past the dollar to see if it's a register name for this ABI.
6796 SMLoc S = Parser.getTok().getLoc();
6797 if (Parser.getTok().is(AsmToken::Dollar)) {
6798 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6801 }
6802 if (getParser().parseExpression(IdVal))
6803 return ParseStatus::Failure;
6804 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6805 if (!MCE)
6806 return ParseStatus::NoMatch;
6807 int64_t Val = MCE->getValue();
6808 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6809 Operands.push_back(MipsOperand::CreateImm(
6810 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6811 return ParseStatus::Success;
6812}
6813
6814ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6815 MCAsmParser &Parser = getParser();
6817 MCRegister Reg;
6818 MCRegister PrevReg;
6819 bool RegRange = false;
6821
6822 if (Parser.getTok().isNot(AsmToken::Dollar))
6823 return ParseStatus::Failure;
6824
6825 SMLoc S = Parser.getTok().getLoc();
6826 while (parseAnyRegister(TmpOperands).isSuccess()) {
6827 SMLoc E = getLexer().getLoc();
6828 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*TmpOperands.back());
6829 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6830 if (RegRange) {
6831 // Remove last register operand because registers from register range
6832 // should be inserted first.
6833 if ((isGP64bit() && Reg == Mips::RA_64) ||
6834 (!isGP64bit() && Reg == Mips::RA)) {
6835 Regs.push_back(Reg);
6836 } else {
6837 MCRegister TmpReg = PrevReg + 1;
6838 while (TmpReg <= Reg) {
6839 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6840 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6841 isGP64bit()))
6842 return Error(E, "invalid register operand");
6843
6844 PrevReg = TmpReg;
6845 Regs.push_back(TmpReg);
6846 TmpReg = TmpReg.id() + 1;
6847 }
6848 }
6849
6850 RegRange = false;
6851 } else {
6852 if (!PrevReg.isValid() &&
6853 ((isGP64bit() && (Reg != Mips::S0_64) && (Reg != Mips::RA_64)) ||
6854 (!isGP64bit() && (Reg != Mips::S0) && (Reg != Mips::RA))))
6855 return Error(E, "$16 or $31 expected");
6856 if (!(((Reg == Mips::FP || Reg == Mips::RA ||
6857 (Reg >= Mips::S0 && Reg <= Mips::S7)) &&
6858 !isGP64bit()) ||
6859 ((Reg == Mips::FP_64 || Reg == Mips::RA_64 ||
6860 (Reg >= Mips::S0_64 && Reg <= Mips::S7_64)) &&
6861 isGP64bit())))
6862 return Error(E, "invalid register operand");
6863 if (PrevReg.isValid() && (Reg != PrevReg + 1) &&
6864 ((Reg != Mips::FP && Reg != Mips::RA && !isGP64bit()) ||
6865 (Reg != Mips::FP_64 && Reg != Mips::RA_64 && isGP64bit())))
6866 return Error(E, "consecutive register numbers expected");
6867
6868 Regs.push_back(Reg);
6869 }
6870
6871 if (Parser.getTok().is(AsmToken::Minus))
6872 RegRange = true;
6873
6874 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6875 !Parser.getTok().isNot(AsmToken::Comma))
6876 return Error(E, "',' or '-' expected");
6877
6878 Lex(); // Consume comma or minus
6879 if (Parser.getTok().isNot(AsmToken::Dollar))
6880 break;
6881
6882 PrevReg = Reg;
6883 }
6884
6885 SMLoc E = Parser.getTok().getLoc();
6886 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6887 parseMemOperand(Operands);
6888 return ParseStatus::Success;
6889}
6890
6891/// Sometimes (i.e. load/stores) the operand may be followed immediately by
6892/// either this.
6893/// ::= '(', register, ')'
6894/// handle it before we iterate so we don't get tripped up by the lack of
6895/// a comma.
6896bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6897 MCAsmParser &Parser = getParser();
6898 if (getLexer().is(AsmToken::LParen)) {
6899 Operands.push_back(
6900 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6901 Parser.Lex();
6902 if (parseOperand(Operands, Name)) {
6903 SMLoc Loc = getLexer().getLoc();
6904 return Error(Loc, "unexpected token in argument list");
6905 }
6906 if (Parser.getTok().isNot(AsmToken::RParen)) {
6907 SMLoc Loc = getLexer().getLoc();
6908 return Error(Loc, "unexpected token, expected ')'");
6909 }
6910 Operands.push_back(
6911 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6912 Parser.Lex();
6913 }
6914 return false;
6915}
6916
6917/// Sometimes (i.e. in MSA) the operand may be followed immediately by
6918/// either one of these.
6919/// ::= '[', register, ']'
6920/// ::= '[', integer, ']'
6921/// handle it before we iterate so we don't get tripped up by the lack of
6922/// a comma.
6923bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6924 OperandVector &Operands) {
6925 MCAsmParser &Parser = getParser();
6926 if (getLexer().is(AsmToken::LBrac)) {
6927 Operands.push_back(
6928 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6929 Parser.Lex();
6930 if (parseOperand(Operands, Name)) {
6931 SMLoc Loc = getLexer().getLoc();
6932 return Error(Loc, "unexpected token in argument list");
6933 }
6934 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6935 SMLoc Loc = getLexer().getLoc();
6936 return Error(Loc, "unexpected token, expected ']'");
6937 }
6938 Operands.push_back(
6939 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6940 Parser.Lex();
6941 }
6942 return false;
6943}
6944
6945static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6946 unsigned VariantID = 0);
6947
6948bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6949 const MCParsedAsmOperand &Op2) const {
6950 // This target-overriden function exists to maintain current behaviour for
6951 // e.g.
6952 // dahi $3, $3, 0x5678
6953 // as tested in test/MC/Mips/mips64r6/valid.s.
6954 // FIXME: Should this test actually fail with an error? If so, then remove
6955 // this overloaded method.
6956 if (!Op1.isReg() || !Op2.isReg())
6957 return true;
6958 return Op1.getReg() == Op2.getReg();
6959}
6960
6961bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6962 SMLoc NameLoc, OperandVector &Operands) {
6963 MCAsmParser &Parser = getParser();
6964 LLVM_DEBUG(dbgs() << "parseInstruction\n");
6965
6966 // We have reached first instruction, module directive are now forbidden.
6967 getTargetStreamer().forbidModuleDirective();
6968
6969 // Check if we have valid mnemonic
6970 if (!mnemonicIsValid(Name, 0)) {
6971 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6972 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6973 return Error(NameLoc, "unknown instruction" + Suggestion);
6974 }
6975 // First operand in MCInst is instruction mnemonic.
6976 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6977
6978 // Read the remaining operands.
6979 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6980 // Read the first operand.
6981 if (parseOperand(Operands, Name)) {
6982 SMLoc Loc = getLexer().getLoc();
6983 return Error(Loc, "unexpected token in argument list");
6984 }
6985 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6986 return true;
6987 // AFAIK, parenthesis suffixes are never on the first operand
6988
6989 while (getLexer().is(AsmToken::Comma)) {
6990 Parser.Lex(); // Eat the comma.
6991 // Parse and remember the operand.
6992 if (parseOperand(Operands, Name)) {
6993 SMLoc Loc = getLexer().getLoc();
6994 return Error(Loc, "unexpected token in argument list");
6995 }
6996 // Parse bracket and parenthesis suffixes before we iterate
6997 if (getLexer().is(AsmToken::LBrac)) {
6998 if (parseBracketSuffix(Name, Operands))
6999 return true;
7000 } else if (getLexer().is(AsmToken::LParen) &&
7001 parseParenSuffix(Name, Operands))
7002 return true;
7003 }
7004 }
7005 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7006 SMLoc Loc = getLexer().getLoc();
7007 return Error(Loc, "unexpected token in argument list");
7008 }
7009 Parser.Lex(); // Consume the EndOfStatement.
7010 return false;
7011}
7012
7013// FIXME: Given that these have the same name, these should both be
7014// consistent on affecting the Parser.
7015bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
7016 SMLoc Loc = getLexer().getLoc();
7017 return Error(Loc, ErrorMsg);
7018}
7019
7020bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
7021 return Error(Loc, ErrorMsg);
7022}
7023
7024bool MipsAsmParser::parseSetNoAtDirective() {
7025 MCAsmParser &Parser = getParser();
7026 // Line should look like: ".set noat".
7027
7028 // Set the $at register to $0.
7029 AssemblerOptions.back()->setATRegIndex(0);
7030
7031 Parser.Lex(); // Eat "noat".
7032
7033 // If this is not the end of the statement, report an error.
7034 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7035 reportParseError("unexpected token, expected end of statement");
7036 return false;
7037 }
7038
7039 getTargetStreamer().emitDirectiveSetNoAt();
7040 Parser.Lex(); // Consume the EndOfStatement.
7041 return false;
7042}
7043
7044bool MipsAsmParser::parseSetAtDirective() {
7045 // Line can be: ".set at", which sets $at to $1
7046 // or ".set at=$reg", which sets $at to $reg.
7047 MCAsmParser &Parser = getParser();
7048 Parser.Lex(); // Eat "at".
7049
7050 if (getLexer().is(AsmToken::EndOfStatement)) {
7051 // No register was specified, so we set $at to $1.
7052 AssemblerOptions.back()->setATRegIndex(1);
7053
7054 getTargetStreamer().emitDirectiveSetAt();
7055 Parser.Lex(); // Consume the EndOfStatement.
7056 return false;
7057 }
7058
7059 if (getLexer().isNot(AsmToken::Equal)) {
7060 reportParseError("unexpected token, expected equals sign");
7061 return false;
7062 }
7063 Parser.Lex(); // Eat "=".
7064
7065 if (getLexer().isNot(AsmToken::Dollar)) {
7066 if (getLexer().is(AsmToken::EndOfStatement)) {
7067 reportParseError("no register specified");
7068 return false;
7069 } else {
7070 reportParseError("unexpected token, expected dollar sign '$'");
7071 return false;
7072 }
7073 }
7074 Parser.Lex(); // Eat "$".
7075
7076 // Find out what "reg" is.
7077 unsigned AtRegNo;
7078 const AsmToken &Reg = Parser.getTok();
7079 if (Reg.is(AsmToken::Identifier)) {
7080 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7081 } else if (Reg.is(AsmToken::Integer)) {
7082 AtRegNo = Reg.getIntVal();
7083 } else {
7084 reportParseError("unexpected token, expected identifier or integer");
7085 return false;
7086 }
7087
7088 // Check if $reg is a valid register. If it is, set $at to $reg.
7089 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7090 reportParseError("invalid register");
7091 return false;
7092 }
7093 Parser.Lex(); // Eat "reg".
7094
7095 // If this is not the end of the statement, report an error.
7096 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7097 reportParseError("unexpected token, expected end of statement");
7098 return false;
7099 }
7100
7101 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7102
7103 Parser.Lex(); // Consume the EndOfStatement.
7104 return false;
7105}
7106
7107bool MipsAsmParser::parseSetReorderDirective() {
7108 MCAsmParser &Parser = getParser();
7109 Parser.Lex();
7110 // If this is not the end of the statement, report an error.
7111 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7112 reportParseError("unexpected token, expected end of statement");
7113 return false;
7114 }
7115 AssemblerOptions.back()->setReorder();
7116 getTargetStreamer().emitDirectiveSetReorder();
7117 Parser.Lex(); // Consume the EndOfStatement.
7118 return false;
7119}
7120
7121bool MipsAsmParser::parseSetNoReorderDirective() {
7122 MCAsmParser &Parser = getParser();
7123 Parser.Lex();
7124 // If this is not the end of the statement, report an error.
7125 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7126 reportParseError("unexpected token, expected end of statement");
7127 return false;
7128 }
7129 AssemblerOptions.back()->setNoReorder();
7130 getTargetStreamer().emitDirectiveSetNoReorder();
7131 Parser.Lex(); // Consume the EndOfStatement.
7132 return false;
7133}
7134
7135bool MipsAsmParser::parseSetMacroDirective() {
7136 MCAsmParser &Parser = getParser();
7137 Parser.Lex();
7138 // If this is not the end of the statement, report an error.
7139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7140 reportParseError("unexpected token, expected end of statement");
7141 return false;
7142 }
7143 AssemblerOptions.back()->setMacro();
7144 getTargetStreamer().emitDirectiveSetMacro();
7145 Parser.Lex(); // Consume the EndOfStatement.
7146 return false;
7147}
7148
7149bool MipsAsmParser::parseSetNoMacroDirective() {
7150 MCAsmParser &Parser = getParser();
7151 Parser.Lex();
7152 // If this is not the end of the statement, report an error.
7153 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7154 reportParseError("unexpected token, expected end of statement");
7155 return false;
7156 }
7157 if (AssemblerOptions.back()->isReorder()) {
7158 reportParseError("`noreorder' must be set before `nomacro'");
7159 return false;
7160 }
7161 AssemblerOptions.back()->setNoMacro();
7162 getTargetStreamer().emitDirectiveSetNoMacro();
7163 Parser.Lex(); // Consume the EndOfStatement.
7164 return false;
7165}
7166
7167bool MipsAsmParser::parseSetMsaDirective() {
7168 MCAsmParser &Parser = getParser();
7169 Parser.Lex();
7170
7171 // If this is not the end of the statement, report an error.
7172 if (getLexer().isNot(AsmToken::EndOfStatement))
7173 return reportParseError("unexpected token, expected end of statement");
7174
7175 setFeatureBits(Mips::FeatureMSA, "msa");
7176 getTargetStreamer().emitDirectiveSetMsa();
7177 return false;
7178}
7179
7180bool MipsAsmParser::parseSetNoMsaDirective() {
7181 MCAsmParser &Parser = getParser();
7182 Parser.Lex();
7183
7184 // If this is not the end of the statement, report an error.
7185 if (getLexer().isNot(AsmToken::EndOfStatement))
7186 return reportParseError("unexpected token, expected end of statement");
7187
7188 clearFeatureBits(Mips::FeatureMSA, "msa");
7189 getTargetStreamer().emitDirectiveSetNoMsa();
7190 return false;
7191}
7192
7193bool MipsAsmParser::parseSetNoDspDirective() {
7194 MCAsmParser &Parser = getParser();
7195 Parser.Lex(); // Eat "nodsp".
7196
7197 // If this is not the end of the statement, report an error.
7198 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7199 reportParseError("unexpected token, expected end of statement");
7200 return false;
7201 }
7202
7203 clearFeatureBits(Mips::FeatureDSP, "dsp");
7204 getTargetStreamer().emitDirectiveSetNoDsp();
7205 return false;
7206}
7207
7208bool MipsAsmParser::parseSetNoMips3DDirective() {
7209 MCAsmParser &Parser = getParser();
7210 Parser.Lex(); // Eat "nomips3d".
7211
7212 // If this is not the end of the statement, report an error.
7213 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7214 reportParseError("unexpected token, expected end of statement");
7215 return false;
7216 }
7217
7218 clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7219 getTargetStreamer().emitDirectiveSetNoMips3D();
7220 return false;
7221}
7222
7223bool MipsAsmParser::parseSetMips16Directive() {
7224 MCAsmParser &Parser = getParser();
7225 Parser.Lex(); // Eat "mips16".
7226
7227 // If this is not the end of the statement, report an error.
7228 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7229 reportParseError("unexpected token, expected end of statement");
7230 return false;
7231 }
7232
7233 setFeatureBits(Mips::FeatureMips16, "mips16");
7234 getTargetStreamer().emitDirectiveSetMips16();
7235 Parser.Lex(); // Consume the EndOfStatement.
7236 return false;
7237}
7238
7239bool MipsAsmParser::parseSetNoMips16Directive() {
7240 MCAsmParser &Parser = getParser();
7241 Parser.Lex(); // Eat "nomips16".
7242
7243 // If this is not the end of the statement, report an error.
7244 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7245 reportParseError("unexpected token, expected end of statement");
7246 return false;
7247 }
7248
7249 clearFeatureBits(Mips::FeatureMips16, "mips16");
7250 getTargetStreamer().emitDirectiveSetNoMips16();
7251 Parser.Lex(); // Consume the EndOfStatement.
7252 return false;
7253}
7254
7255bool MipsAsmParser::parseSetFpDirective() {
7256 MCAsmParser &Parser = getParser();
7258 // Line can be: .set fp=32
7259 // .set fp=xx
7260 // .set fp=64
7261 Parser.Lex(); // Eat fp token
7262 AsmToken Tok = Parser.getTok();
7263 if (Tok.isNot(AsmToken::Equal)) {
7264 reportParseError("unexpected token, expected equals sign '='");
7265 return false;
7266 }
7267 Parser.Lex(); // Eat '=' token.
7268 Tok = Parser.getTok();
7269
7270 if (!parseFpABIValue(FpAbiVal, ".set"))
7271 return false;
7272
7273 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7274 reportParseError("unexpected token, expected end of statement");
7275 return false;
7276 }
7277 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7278 Parser.Lex(); // Consume the EndOfStatement.
7279 return false;
7280}
7281
7282bool MipsAsmParser::parseSetOddSPRegDirective() {
7283 MCAsmParser &Parser = getParser();
7284
7285 Parser.Lex(); // Eat "oddspreg".
7286 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7287 reportParseError("unexpected token, expected end of statement");
7288 return false;
7289 }
7290
7291 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7292 getTargetStreamer().emitDirectiveSetOddSPReg();
7293 return false;
7294}
7295
7296bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7297 MCAsmParser &Parser = getParser();
7298
7299 Parser.Lex(); // Eat "nooddspreg".
7300 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7301 reportParseError("unexpected token, expected end of statement");
7302 return false;
7303 }
7304
7305 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7306 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7307 return false;
7308}
7309
7310bool MipsAsmParser::parseSetMtDirective() {
7311 MCAsmParser &Parser = getParser();
7312 Parser.Lex(); // Eat "mt".
7313
7314 // If this is not the end of the statement, report an error.
7315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7316 reportParseError("unexpected token, expected end of statement");
7317 return false;
7318 }
7319
7320 setFeatureBits(Mips::FeatureMT, "mt");
7321 getTargetStreamer().emitDirectiveSetMt();
7322 Parser.Lex(); // Consume the EndOfStatement.
7323 return false;
7324}
7325
7326bool MipsAsmParser::parseSetNoMtDirective() {
7327 MCAsmParser &Parser = getParser();
7328 Parser.Lex(); // Eat "nomt".
7329
7330 // If this is not the end of the statement, report an error.
7331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7332 reportParseError("unexpected token, expected end of statement");
7333 return false;
7334 }
7335
7336 clearFeatureBits(Mips::FeatureMT, "mt");
7337
7338 getTargetStreamer().emitDirectiveSetNoMt();
7339 Parser.Lex(); // Consume the EndOfStatement.
7340 return false;
7341}
7342
7343bool MipsAsmParser::parseSetNoCRCDirective() {
7344 MCAsmParser &Parser = getParser();
7345 Parser.Lex(); // Eat "nocrc".
7346
7347 // If this is not the end of the statement, report an error.
7348 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7349 reportParseError("unexpected token, expected end of statement");
7350 return false;
7351 }
7352
7353 clearFeatureBits(Mips::FeatureCRC, "crc");
7354
7355 getTargetStreamer().emitDirectiveSetNoCRC();
7356 Parser.Lex(); // Consume the EndOfStatement.
7357 return false;
7358}
7359
7360bool MipsAsmParser::parseSetNoVirtDirective() {
7361 MCAsmParser &Parser = getParser();
7362 Parser.Lex(); // Eat "novirt".
7363
7364 // If this is not the end of the statement, report an error.
7365 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7366 reportParseError("unexpected token, expected end of statement");
7367 return false;
7368 }
7369
7370 clearFeatureBits(Mips::FeatureVirt, "virt");
7371
7372 getTargetStreamer().emitDirectiveSetNoVirt();
7373 Parser.Lex(); // Consume the EndOfStatement.
7374 return false;
7375}
7376
7377bool MipsAsmParser::parseSetNoGINVDirective() {
7378 MCAsmParser &Parser = getParser();
7379 Parser.Lex(); // Eat "noginv".
7380
7381 // If this is not the end of the statement, report an error.
7382 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7383 reportParseError("unexpected token, expected end of statement");
7384 return false;
7385 }
7386
7387 clearFeatureBits(Mips::FeatureGINV, "ginv");
7388
7389 getTargetStreamer().emitDirectiveSetNoGINV();
7390 Parser.Lex(); // Consume the EndOfStatement.
7391 return false;
7392}
7393
7394bool MipsAsmParser::parseSetPopDirective() {
7395 MCAsmParser &Parser = getParser();
7396 SMLoc Loc = getLexer().getLoc();
7397
7398 Parser.Lex();
7399 if (getLexer().isNot(AsmToken::EndOfStatement))
7400 return reportParseError("unexpected token, expected end of statement");
7401
7402 // Always keep an element on the options "stack" to prevent the user
7403 // from changing the initial options. This is how we remember them.
7404 if (AssemblerOptions.size() == 2)
7405 return reportParseError(Loc, ".set pop with no .set push");
7406
7407 MCSubtargetInfo &STI = copySTI();
7408 AssemblerOptions.pop_back();
7409 setAvailableFeatures(
7410 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7411 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7412
7413 getTargetStreamer().emitDirectiveSetPop();
7414 return false;
7415}
7416
7417bool MipsAsmParser::parseSetPushDirective() {
7418 MCAsmParser &Parser = getParser();
7419 Parser.Lex();
7420 if (getLexer().isNot(AsmToken::EndOfStatement))
7421 return reportParseError("unexpected token, expected end of statement");
7422
7423 // Create a copy of the current assembler options environment and push it.
7424 AssemblerOptions.push_back(
7425 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7426
7427 getTargetStreamer().emitDirectiveSetPush();
7428 return false;
7429}
7430
7431bool MipsAsmParser::parseSetSoftFloatDirective() {
7432 MCAsmParser &Parser = getParser();
7433 Parser.Lex();
7434 if (getLexer().isNot(AsmToken::EndOfStatement))
7435 return reportParseError("unexpected token, expected end of statement");
7436
7437 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7438 getTargetStreamer().emitDirectiveSetSoftFloat();
7439 return false;
7440}
7441
7442bool MipsAsmParser::parseSetHardFloatDirective() {
7443 MCAsmParser &Parser = getParser();
7444 Parser.Lex();
7445 if (getLexer().isNot(AsmToken::EndOfStatement))
7446 return reportParseError("unexpected token, expected end of statement");
7447
7448 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7449 getTargetStreamer().emitDirectiveSetHardFloat();
7450 return false;
7451}
7452
7453bool MipsAsmParser::parseSetAssignment() {
7454 StringRef Name;
7455 MCAsmParser &Parser = getParser();
7456
7457 if (Parser.parseIdentifier(Name))
7458 return reportParseError("expected identifier after .set");
7459
7460 if (getLexer().isNot(AsmToken::Comma))
7461 return reportParseError("unexpected token, expected comma");
7462 Lex(); // Eat comma
7463
7464 if (getLexer().is(AsmToken::Dollar) &&
7465 getLexer().peekTok().is(AsmToken::Integer)) {
7466 // Parse assignment of a numeric register:
7467 // .set r1,$1
7468 Parser.Lex(); // Eat $.
7469 RegisterSets[Name] = Parser.getTok();
7470 Parser.Lex(); // Eat identifier.
7471 getContext().getOrCreateSymbol(Name);
7472 return false;
7473 }
7474
7475 MCSymbol *Sym;
7476 const MCExpr *Value;
7477 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7478 Parser, Sym, Value))
7479 return true;
7480 getStreamer().emitAssignment(Sym, Value);
7481
7482 return false;
7483}
7484
7485bool MipsAsmParser::parseSetMips0Directive() {
7486 MCAsmParser &Parser = getParser();
7487 Parser.Lex();
7488 if (getLexer().isNot(AsmToken::EndOfStatement))
7489 return reportParseError("unexpected token, expected end of statement");
7490
7491 // Reset assembler options to their initial values.
7492 MCSubtargetInfo &STI = copySTI();
7493 setAvailableFeatures(
7494 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7495 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7496 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7497
7498 getTargetStreamer().emitDirectiveSetMips0();
7499 return false;
7500}
7501
7502bool MipsAsmParser::parseSetArchDirective() {
7503 MCAsmParser &Parser = getParser();
7504 Parser.Lex();
7505 if (getLexer().isNot(AsmToken::Equal))
7506 return reportParseError("unexpected token, expected equals sign");
7507
7508 Parser.Lex();
7509 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7510 if (Arch.empty())
7511 return reportParseError("expected arch identifier");
7512
7513 StringRef ArchFeatureName =
7514 StringSwitch<StringRef>(Arch)
7515 .Case("mips1", "mips1")
7516 .Case("mips2", "mips2")
7517 .Case("mips3", "mips3")
7518 .Case("mips4", "mips4")
7519 .Case("mips5", "mips5")
7520 .Case("mips32", "mips32")
7521 .Case("mips32r2", "mips32r2")
7522 .Case("mips32r3", "mips32r3")
7523 .Case("mips32r5", "mips32r5")
7524 .Case("mips32r6", "mips32r6")
7525 .Case("mips64", "mips64")
7526 .Case("mips64r2", "mips64r2")
7527 .Case("mips64r3", "mips64r3")
7528 .Case("mips64r5", "mips64r5")
7529 .Case("mips64r6", "mips64r6")
7530 .Case("octeon", "cnmips")
7531 .Case("octeon+", "cnmipsp")
7532 .Case("r4000", "mips3") // This is an implementation of Mips3.
7533 .Default("");
7534
7535 if (ArchFeatureName.empty())
7536 return reportParseError("unsupported architecture");
7537
7538 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7539 return reportParseError("mips64r6 does not support microMIPS");
7540
7541 selectArch(ArchFeatureName);
7542 getTargetStreamer().emitDirectiveSetArch(Arch);
7543 return false;
7544}
7545
7546bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7547 MCAsmParser &Parser = getParser();
7548 Parser.Lex();
7549 if (getLexer().isNot(AsmToken::EndOfStatement))
7550 return reportParseError("unexpected token, expected end of statement");
7551
7552 switch (Feature) {
7553 default:
7554 llvm_unreachable("Unimplemented feature");
7555 case Mips::FeatureMips3D:
7556 setFeatureBits(Mips::FeatureMips3D, "mips3d");
7557 getTargetStreamer().emitDirectiveSetMips3D();
7558 break;
7559 case Mips::FeatureDSP:
7560 setFeatureBits(Mips::FeatureDSP, "dsp");
7561 getTargetStreamer().emitDirectiveSetDsp();
7562 break;
7563 case Mips::FeatureDSPR2:
7564 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7565 getTargetStreamer().emitDirectiveSetDspr2();
7566 break;
7567 case Mips::FeatureMicroMips:
7568 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7569 getTargetStreamer().emitDirectiveSetMicroMips();
7570 break;
7571 case Mips::FeatureMips1:
7572 selectArch("mips1");
7573 getTargetStreamer().emitDirectiveSetMips1();
7574 break;
7575 case Mips::FeatureMips2:
7576 selectArch("mips2");
7577 getTargetStreamer().emitDirectiveSetMips2();
7578 break;
7579 case Mips::FeatureMips3:
7580 selectArch("mips3");
7581 getTargetStreamer().emitDirectiveSetMips3();
7582 break;
7583 case Mips::FeatureMips4:
7584 selectArch("mips4");
7585 getTargetStreamer().emitDirectiveSetMips4();
7586 break;
7587 case Mips::FeatureMips5:
7588 selectArch("mips5");
7589 getTargetStreamer().emitDirectiveSetMips5();
7590 break;
7591 case Mips::FeatureMips32:
7592 selectArch("mips32");
7593 getTargetStreamer().emitDirectiveSetMips32();
7594 break;
7595 case Mips::FeatureMips32r2:
7596 selectArch("mips32r2");
7597 getTargetStreamer().emitDirectiveSetMips32R2();
7598 break;
7599 case Mips::FeatureMips32r3:
7600 selectArch("mips32r3");
7601 getTargetStreamer().emitDirectiveSetMips32R3();
7602 break;
7603 case Mips::FeatureMips32r5:
7604 selectArch("mips32r5");
7605 getTargetStreamer().emitDirectiveSetMips32R5();
7606 break;
7607 case Mips::FeatureMips32r6:
7608 selectArch("mips32r6");
7609 getTargetStreamer().emitDirectiveSetMips32R6();
7610 break;
7611 case Mips::FeatureMips64:
7612 selectArch("mips64");
7613 getTargetStreamer().emitDirectiveSetMips64();
7614 break;
7615 case Mips::FeatureMips64r2:
7616 selectArch("mips64r2");
7617 getTargetStreamer().emitDirectiveSetMips64R2();
7618 break;
7619 case Mips::FeatureMips64r3:
7620 selectArch("mips64r3");
7621 getTargetStreamer().emitDirectiveSetMips64R3();
7622 break;
7623 case Mips::FeatureMips64r5:
7624 selectArch("mips64r5");
7625 getTargetStreamer().emitDirectiveSetMips64R5();
7626 break;
7627 case Mips::FeatureMips64r6:
7628 selectArch("mips64r6");
7629 getTargetStreamer().emitDirectiveSetMips64R6();
7630 break;
7631 case Mips::FeatureCRC:
7632 setFeatureBits(Mips::FeatureCRC, "crc");
7633 getTargetStreamer().emitDirectiveSetCRC();
7634 break;
7635 case Mips::FeatureVirt:
7636 setFeatureBits(Mips::FeatureVirt, "virt");
7637 getTargetStreamer().emitDirectiveSetVirt();
7638 break;
7639 case Mips::FeatureGINV:
7640 setFeatureBits(Mips::FeatureGINV, "ginv");
7641 getTargetStreamer().emitDirectiveSetGINV();
7642 break;
7643 }
7644 return false;
7645}
7646
7647bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7648 MCAsmParser &Parser = getParser();
7649 if (getLexer().isNot(AsmToken::Comma)) {
7650 SMLoc Loc = getLexer().getLoc();
7651 return Error(Loc, ErrorStr);
7652 }
7653
7654 Parser.Lex(); // Eat the comma.
7655 return true;
7656}
7657
7658// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7659// In this class, it is only used for .cprestore.
7660// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7661// MipsTargetELFStreamer and MipsAsmParser.
7662bool MipsAsmParser::isPicAndNotNxxAbi() {
7663 return inPicMode() && !(isABI_N32() || isABI_N64());
7664}
7665
7666bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7668 ParseStatus Res = parseAnyRegister(Reg);
7669 if (Res.isNoMatch() || Res.isFailure()) {
7670 reportParseError("expected register");
7671 return false;
7672 }
7673
7674 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7675 if (!RegOpnd.isGPRAsmReg()) {
7676 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7677 return false;
7678 }
7679
7680 // If this is not the end of the statement, report an error.
7681 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7682 reportParseError("unexpected token, expected end of statement");
7683 return false;
7684 }
7685 getParser().Lex(); // Consume the EndOfStatement.
7686
7687 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7688 return false;
7689}
7690
7691bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7692 if (AssemblerOptions.back()->isReorder())
7693 Warning(Loc, ".cpload should be inside a noreorder section");
7694
7695 if (inMips16Mode()) {
7696 reportParseError(".cpload is not supported in Mips16 mode");
7697 return false;
7698 }
7699
7701 ParseStatus Res = parseAnyRegister(Reg);
7702 if (Res.isNoMatch() || Res.isFailure()) {
7703 reportParseError("expected register containing function address");
7704 return false;
7705 }
7706
7707 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7708 if (!RegOpnd.isGPRAsmReg()) {
7709 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7710 return false;
7711 }
7712
7713 // If this is not the end of the statement, report an error.
7714 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7715 reportParseError("unexpected token, expected end of statement");
7716 return false;
7717 }
7718
7719 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7720 return false;
7721}
7722
7723bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7724 if (!isABI_N32() && !isABI_N64()) {
7725 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7726 return false;
7727 }
7728
7730 ParseStatus Res = parseAnyRegister(Reg);
7731 if (Res.isNoMatch() || Res.isFailure()) {
7732 reportParseError("expected register containing global pointer");
7733 return false;
7734 }
7735
7736 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7737 if (!RegOpnd.isGPRAsmReg()) {
7738 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7739 return false;
7740 }
7741
7742 // If this is not the end of the statement, report an error.
7743 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7744 reportParseError("unexpected token, expected end of statement");
7745 return false;
7746 }
7747 getParser().Lex(); // Consume the EndOfStatement.
7748
7749 MCRegister NewReg = RegOpnd.getGPR32Reg();
7750 if (IsPicEnabled)
7751 GPReg = NewReg;
7752
7753 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7754 return false;
7755}
7756
7757bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7758 MCAsmParser &Parser = getParser();
7759
7760 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7761 // is used in non-PIC mode.
7762
7763 if (inMips16Mode()) {
7764 reportParseError(".cprestore is not supported in Mips16 mode");
7765 return false;
7766 }
7767
7768 // Get the stack offset value.
7769 const MCExpr *StackOffset;
7770 int64_t StackOffsetVal;
7771 if (Parser.parseExpression(StackOffset)) {
7772 reportParseError("expected stack offset value");
7773 return false;
7774 }
7775
7776 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7777 reportParseError("stack offset is not an absolute expression");
7778 return false;
7779 }
7780
7781 if (StackOffsetVal < 0) {
7782 Warning(Loc, ".cprestore with negative stack offset has no effect");
7783 IsCpRestoreSet = false;
7784 } else {
7785 IsCpRestoreSet = true;
7786 CpRestoreOffset = StackOffsetVal;
7787 }
7788
7789 // If this is not the end of the statement, report an error.
7790 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7791 reportParseError("unexpected token, expected end of statement");
7792 return false;
7793 }
7794
7795 if (!getTargetStreamer().emitDirectiveCpRestore(
7796 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7797 return true;
7798 Parser.Lex(); // Consume the EndOfStatement.
7799 return false;
7800}
7801
7802bool MipsAsmParser::parseDirectiveCPSetup() {
7803 MCAsmParser &Parser = getParser();
7804 unsigned Save;
7805 bool SaveIsReg = true;
7806
7808 ParseStatus Res = parseAnyRegister(TmpReg);
7809 if (Res.isNoMatch()) {
7810 reportParseError("expected register containing function address");
7811 return false;
7812 }
7813
7814 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7815 if (!FuncRegOpnd.isGPRAsmReg()) {
7816 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7817 return false;
7818 }
7819
7820 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7821 TmpReg.clear();
7822
7823 if (!eatComma("unexpected token, expected comma"))
7824 return true;
7825
7826 Res = parseAnyRegister(TmpReg);
7827 if (Res.isNoMatch()) {
7828 const MCExpr *OffsetExpr;
7829 int64_t OffsetVal;
7830 SMLoc ExprLoc = getLexer().getLoc();
7831
7832 if (Parser.parseExpression(OffsetExpr) ||
7833 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7834 reportParseError(ExprLoc, "expected save register or stack offset");
7835 return false;
7836 }
7837
7838 Save = OffsetVal;
7839 SaveIsReg = false;
7840 } else {
7841 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7842 if (!SaveOpnd.isGPRAsmReg()) {
7843 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7844 return false;
7845 }
7846 Save = SaveOpnd.getGPR32Reg().id();
7847 }
7848
7849 if (!eatComma("unexpected token, expected comma"))
7850 return true;
7851
7852 const MCExpr *Expr;
7853 if (Parser.parseExpression(Expr)) {
7854 reportParseError("expected expression");
7855 return false;
7856 }
7857
7858 if (Expr->getKind() != MCExpr::SymbolRef) {
7859 reportParseError("expected symbol");
7860 return false;
7861 }
7862 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7863
7864 CpSaveLocation = Save;
7865 CpSaveLocationIsRegister = SaveIsReg;
7866
7867 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7868 SaveIsReg);
7869 return false;
7870}
7871
7872bool MipsAsmParser::parseDirectiveCPReturn() {
7873 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7874 CpSaveLocationIsRegister);
7875 return false;
7876}
7877
7878bool MipsAsmParser::parseDirectiveNaN() {
7879 MCAsmParser &Parser = getParser();
7880 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7881 const AsmToken &Tok = Parser.getTok();
7882
7883 if (Tok.getString() == "2008") {
7884 Parser.Lex();
7885 getTargetStreamer().emitDirectiveNaN2008();
7886 return false;
7887 } else if (Tok.getString() == "legacy") {
7888 Parser.Lex();
7889 getTargetStreamer().emitDirectiveNaNLegacy();
7890 return false;
7891 }
7892 }
7893 // If we don't recognize the option passed to the .nan
7894 // directive (e.g. no option or unknown option), emit an error.
7895 reportParseError("invalid option in .nan directive");
7896 return false;
7897}
7898
7899bool MipsAsmParser::parseDirectiveSet() {
7900 const AsmToken &Tok = getParser().getTok();
7901 StringRef IdVal = Tok.getString();
7902 SMLoc Loc = Tok.getLoc();
7903
7904 if (IdVal == "noat")
7905 return parseSetNoAtDirective();
7906 if (IdVal == "at")
7907 return parseSetAtDirective();
7908 if (IdVal == "arch")
7909 return parseSetArchDirective();
7910 if (IdVal == "bopt") {
7911 Warning(Loc, "'bopt' feature is unsupported");
7912 getParser().Lex();
7913 return false;
7914 }
7915 if (IdVal == "nobopt") {
7916 // We're already running in nobopt mode, so nothing to do.
7917 getParser().Lex();
7918 return false;
7919 }
7920 if (IdVal == "fp")
7921 return parseSetFpDirective();
7922 if (IdVal == "oddspreg")
7923 return parseSetOddSPRegDirective();
7924 if (IdVal == "nooddspreg")
7925 return parseSetNoOddSPRegDirective();
7926 if (IdVal == "pop")
7927 return parseSetPopDirective();
7928 if (IdVal == "push")
7929 return parseSetPushDirective();
7930 if (IdVal == "reorder")
7931 return parseSetReorderDirective();
7932 if (IdVal == "noreorder")
7933 return parseSetNoReorderDirective();
7934 if (IdVal == "macro")
7935 return parseSetMacroDirective();
7936 if (IdVal == "nomacro")
7937 return parseSetNoMacroDirective();
7938 if (IdVal == "mips16")
7939 return parseSetMips16Directive();
7940 if (IdVal == "nomips16")
7941 return parseSetNoMips16Directive();
7942 if (IdVal == "nomicromips") {
7943 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7944 getTargetStreamer().emitDirectiveSetNoMicroMips();
7945 getParser().eatToEndOfStatement();
7946 return false;
7947 }
7948 if (IdVal == "micromips") {
7949 if (hasMips64r6()) {
7950 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7951 return false;
7952 }
7953 return parseSetFeature(Mips::FeatureMicroMips);
7954 }
7955 if (IdVal == "mips0")
7956 return parseSetMips0Directive();
7957 if (IdVal == "mips1")
7958 return parseSetFeature(Mips::FeatureMips1);
7959 if (IdVal == "mips2")
7960 return parseSetFeature(Mips::FeatureMips2);
7961 if (IdVal == "mips3")
7962 return parseSetFeature(Mips::FeatureMips3);
7963 if (IdVal == "mips4")
7964 return parseSetFeature(Mips::FeatureMips4);
7965 if (IdVal == "mips5")
7966 return parseSetFeature(Mips::FeatureMips5);
7967 if (IdVal == "mips32")
7968 return parseSetFeature(Mips::FeatureMips32);
7969 if (IdVal == "mips32r2")
7970 return parseSetFeature(Mips::FeatureMips32r2);
7971 if (IdVal == "mips32r3")
7972 return parseSetFeature(Mips::FeatureMips32r3);
7973 if (IdVal == "mips32r5")
7974 return parseSetFeature(Mips::FeatureMips32r5);
7975 if (IdVal == "mips32r6")
7976 return parseSetFeature(Mips::FeatureMips32r6);
7977 if (IdVal == "mips64")
7978 return parseSetFeature(Mips::FeatureMips64);
7979 if (IdVal == "mips64r2")
7980 return parseSetFeature(Mips::FeatureMips64r2);
7981 if (IdVal == "mips64r3")
7982 return parseSetFeature(Mips::FeatureMips64r3);
7983 if (IdVal == "mips64r5")
7984 return parseSetFeature(Mips::FeatureMips64r5);
7985 if (IdVal == "mips64r6") {
7986 if (inMicroMipsMode()) {
7987 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7988 return false;
7989 }
7990 return parseSetFeature(Mips::FeatureMips64r6);
7991 }
7992 if (IdVal == "dsp")
7993 return parseSetFeature(Mips::FeatureDSP);
7994 if (IdVal == "dspr2")
7995 return parseSetFeature(Mips::FeatureDSPR2);
7996 if (IdVal == "nodsp")
7997 return parseSetNoDspDirective();
7998 if (IdVal == "mips3d")
7999 return parseSetFeature(Mips::FeatureMips3D);
8000 if (IdVal == "nomips3d")
8001 return parseSetNoMips3DDirective();
8002 if (IdVal == "msa")
8003 return parseSetMsaDirective();
8004 if (IdVal == "nomsa")
8005 return parseSetNoMsaDirective();
8006 if (IdVal == "mt")
8007 return parseSetMtDirective();
8008 if (IdVal == "nomt")
8009 return parseSetNoMtDirective();
8010 if (IdVal == "softfloat")
8011 return parseSetSoftFloatDirective();
8012 if (IdVal == "hardfloat")
8013 return parseSetHardFloatDirective();
8014 if (IdVal == "crc")
8015 return parseSetFeature(Mips::FeatureCRC);
8016 if (IdVal == "nocrc")
8017 return parseSetNoCRCDirective();
8018 if (IdVal == "virt")
8019 return parseSetFeature(Mips::FeatureVirt);
8020 if (IdVal == "novirt")
8021 return parseSetNoVirtDirective();
8022 if (IdVal == "ginv")
8023 return parseSetFeature(Mips::FeatureGINV);
8024 if (IdVal == "noginv")
8025 return parseSetNoGINVDirective();
8026
8027 // It is just an identifier, look for an assignment.
8028 return parseSetAssignment();
8029}
8030
8031/// parseDirectiveGpWord
8032/// ::= .gpword local_sym
8033bool MipsAsmParser::parseDirectiveGpWord() {
8034 const MCExpr *Value;
8035 if (getParser().parseExpression(Value))
8036 return true;
8037 getTargetStreamer().emitGPRel32Value(Value);
8038 return parseEOL();
8039}
8040
8041/// parseDirectiveGpDWord
8042/// ::= .gpdword local_sym
8043bool MipsAsmParser::parseDirectiveGpDWord() {
8044 const MCExpr *Value;
8045 if (getParser().parseExpression(Value))
8046 return true;
8047 getTargetStreamer().emitGPRel64Value(Value);
8048 return parseEOL();
8049}
8050
8051/// parseDirectiveDtpRelWord
8052/// ::= .dtprelword tls_sym
8053bool MipsAsmParser::parseDirectiveDtpRelWord() {
8054 const MCExpr *Value;
8055 if (getParser().parseExpression(Value))
8056 return true;
8057 getTargetStreamer().emitDTPRel32Value(Value);
8058 return parseEOL();
8059}
8060
8061/// parseDirectiveDtpRelDWord
8062/// ::= .dtpreldword tls_sym
8063bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8064 const MCExpr *Value;
8065 if (getParser().parseExpression(Value))
8066 return true;
8067 getTargetStreamer().emitDTPRel64Value(Value);
8068 return parseEOL();
8069}
8070
8071/// parseDirectiveTpRelWord
8072/// ::= .tprelword tls_sym
8073bool MipsAsmParser::parseDirectiveTpRelWord() {
8074 const MCExpr *Value;
8075 if (getParser().parseExpression(Value))
8076 return true;
8077 getTargetStreamer().emitTPRel32Value(Value);
8078 return parseEOL();
8079}
8080
8081/// parseDirectiveTpRelDWord
8082/// ::= .tpreldword tls_sym
8083bool MipsAsmParser::parseDirectiveTpRelDWord() {
8084 const MCExpr *Value;
8085 if (getParser().parseExpression(Value))
8086 return true;
8087 getTargetStreamer().emitTPRel64Value(Value);
8088 return parseEOL();
8089}
8090
8091bool MipsAsmParser::parseDirectiveOption() {
8092 MCAsmParser &Parser = getParser();
8093 // Get the option token.
8094 AsmToken Tok = Parser.getTok();
8095 // At the moment only identifiers are supported.
8096 if (Tok.isNot(AsmToken::Identifier)) {
8097 return Error(Parser.getTok().getLoc(),
8098 "unexpected token, expected identifier");
8099 }
8100
8101 StringRef Option = Tok.getIdentifier();
8102
8103 if (Option == "pic0") {
8104 // MipsAsmParser needs to know if the current PIC mode changes.
8105 IsPicEnabled = false;
8106
8107 getTargetStreamer().emitDirectiveOptionPic0();
8108 Parser.Lex();
8109 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8110 return Error(Parser.getTok().getLoc(),
8111 "unexpected token, expected end of statement");
8112 }
8113 return false;
8114 }
8115
8116 if (Option == "pic2") {
8117 // MipsAsmParser needs to know if the current PIC mode changes.
8118 IsPicEnabled = true;
8119
8120 getTargetStreamer().emitDirectiveOptionPic2();
8121 Parser.Lex();
8122 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8123 return Error(Parser.getTok().getLoc(),
8124 "unexpected token, expected end of statement");
8125 }
8126 return false;
8127 }
8128
8129 // Unknown option.
8130 Warning(Parser.getTok().getLoc(),
8131 "unknown option, expected 'pic0' or 'pic2'");
8132 Parser.eatToEndOfStatement();
8133 return false;
8134}
8135
8136/// parseInsnDirective
8137/// ::= .insn
8138bool MipsAsmParser::parseInsnDirective() {
8139 // If this is not the end of the statement, report an error.
8140 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8141 reportParseError("unexpected token, expected end of statement");
8142 return false;
8143 }
8144
8145 // The actual label marking happens in
8146 // MipsELFStreamer::createPendingLabelRelocs().
8147 getTargetStreamer().emitDirectiveInsn();
8148
8149 getParser().Lex(); // Eat EndOfStatement token.
8150 return false;
8151}
8152
8153/// parseRSectionDirective
8154/// ::= .rdata
8155bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8156 // If this is not the end of the statement, report an error.
8157 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8158 reportParseError("unexpected token, expected end of statement");
8159 return false;
8160 }
8161
8162 MCSection *ELFSection = getContext().getELFSection(
8164 getParser().getStreamer().switchSection(ELFSection);
8165
8166 getParser().Lex(); // Eat EndOfStatement token.
8167 return false;
8168}
8169
8170/// parseSSectionDirective
8171/// ::= .sbss
8172/// ::= .sdata
8173bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8174 // If this is not the end of the statement, report an error.
8175 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8176 reportParseError("unexpected token, expected end of statement");
8177 return false;
8178 }
8179
8180 MCSection *ELFSection = getContext().getELFSection(
8182 getParser().getStreamer().switchSection(ELFSection);
8183
8184 getParser().Lex(); // Eat EndOfStatement token.
8185 return false;
8186}
8187
8188/// parseDirectiveModule
8189/// ::= .module oddspreg
8190/// ::= .module nooddspreg
8191/// ::= .module fp=value
8192/// ::= .module softfloat
8193/// ::= .module hardfloat
8194/// ::= .module mt
8195/// ::= .module crc
8196/// ::= .module nocrc
8197/// ::= .module virt
8198/// ::= .module novirt
8199/// ::= .module ginv
8200/// ::= .module noginv
8201bool MipsAsmParser::parseDirectiveModule() {
8202 MCAsmParser &Parser = getParser();
8203 AsmLexer &Lexer = getLexer();
8204 SMLoc L = Lexer.getLoc();
8205
8206 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8207 // TODO : get a better message.
8208 reportParseError(".module directive must appear before any code");
8209 return false;
8210 }
8211
8212 StringRef Option;
8213 if (Parser.parseIdentifier(Option)) {
8214 reportParseError("expected .module option identifier");
8215 return false;
8216 }
8217
8218 if (Option == "oddspreg") {
8219 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8220
8221 // Synchronize the abiflags information with the FeatureBits information we
8222 // changed above.
8223 getTargetStreamer().updateABIInfo(*this);
8224
8225 // If printing assembly, use the recently updated abiflags information.
8226 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8227 // emitted at the end).
8228 getTargetStreamer().emitDirectiveModuleOddSPReg();
8229
8230 // If this is not the end of the statement, report an error.
8231 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8232 reportParseError("unexpected token, expected end of statement");
8233 return false;
8234 }
8235
8236 return false; // parseDirectiveModule has finished successfully.
8237 } else if (Option == "nooddspreg") {
8238 if (!isABI_O32()) {
8239 return Error(L, "'.module nooddspreg' requires the O32 ABI");
8240 }
8241
8242 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8243
8244 // Synchronize the abiflags information with the FeatureBits information we
8245 // changed above.
8246 getTargetStreamer().updateABIInfo(*this);
8247
8248 // If printing assembly, use the recently updated abiflags information.
8249 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8250 // emitted at the end).
8251 getTargetStreamer().emitDirectiveModuleOddSPReg();
8252
8253 // If this is not the end of the statement, report an error.
8254 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8255 reportParseError("unexpected token, expected end of statement");
8256 return false;
8257 }
8258
8259 return false; // parseDirectiveModule has finished successfully.
8260 } else if (Option == "fp") {
8261 return parseDirectiveModuleFP();
8262 } else if (Option == "softfloat") {
8263 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8264
8265 // Synchronize the ABI Flags information with the FeatureBits information we
8266 // updated above.
8267 getTargetStreamer().updateABIInfo(*this);
8268
8269 // If printing assembly, use the recently updated ABI Flags information.
8270 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8271 // emitted later).
8272 getTargetStreamer().emitDirectiveModuleSoftFloat();
8273
8274 // If this is not the end of the statement, report an error.
8275 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8276 reportParseError("unexpected token, expected end of statement");
8277 return false;
8278 }
8279
8280 return false; // parseDirectiveModule has finished successfully.
8281 } else if (Option == "hardfloat") {
8282 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8283
8284 // Synchronize the ABI Flags information with the FeatureBits information we
8285 // updated above.
8286 getTargetStreamer().updateABIInfo(*this);
8287
8288 // If printing assembly, use the recently updated ABI Flags information.
8289 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8290 // emitted later).
8291 getTargetStreamer().emitDirectiveModuleHardFloat();
8292
8293 // If this is not the end of the statement, report an error.
8294 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8295 reportParseError("unexpected token, expected end of statement");
8296 return false;
8297 }
8298
8299 return false; // parseDirectiveModule has finished successfully.
8300 } else if (Option == "mt") {
8301 setModuleFeatureBits(Mips::FeatureMT, "mt");
8302
8303 // Synchronize the ABI Flags information with the FeatureBits information we
8304 // updated above.
8305 getTargetStreamer().updateABIInfo(*this);
8306
8307 // If printing assembly, use the recently updated ABI Flags information.
8308 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8309 // emitted later).
8310 getTargetStreamer().emitDirectiveModuleMT();
8311
8312 // If this is not the end of the statement, report an error.
8313 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8314 reportParseError("unexpected token, expected end of statement");
8315 return false;
8316 }
8317
8318 return false; // parseDirectiveModule has finished successfully.
8319 } else if (Option == "crc") {
8320 setModuleFeatureBits(Mips::FeatureCRC, "crc");
8321
8322 // Synchronize the ABI Flags information with the FeatureBits information we
8323 // updated above.
8324 getTargetStreamer().updateABIInfo(*this);
8325
8326 // If printing assembly, use the recently updated ABI Flags information.
8327 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8328 // emitted later).
8329 getTargetStreamer().emitDirectiveModuleCRC();
8330
8331 // If this is not the end of the statement, report an error.
8332 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8333 reportParseError("unexpected token, expected end of statement");
8334 return false;
8335 }
8336
8337 return false; // parseDirectiveModule has finished successfully.
8338 } else if (Option == "nocrc") {
8339 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8340
8341 // Synchronize the ABI Flags information with the FeatureBits information we
8342 // updated above.
8343 getTargetStreamer().updateABIInfo(*this);
8344
8345 // If printing assembly, use the recently updated ABI Flags information.
8346 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8347 // emitted later).
8348 getTargetStreamer().emitDirectiveModuleNoCRC();
8349
8350 // If this is not the end of the statement, report an error.
8351 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8352 reportParseError("unexpected token, expected end of statement");
8353 return false;
8354 }
8355
8356 return false; // parseDirectiveModule has finished successfully.
8357 } else if (Option == "virt") {
8358 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8359
8360 // Synchronize the ABI Flags information with the FeatureBits information we
8361 // updated above.
8362 getTargetStreamer().updateABIInfo(*this);
8363
8364 // If printing assembly, use the recently updated ABI Flags information.
8365 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8366 // emitted later).
8367 getTargetStreamer().emitDirectiveModuleVirt();
8368
8369 // If this is not the end of the statement, report an error.
8370 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8371 reportParseError("unexpected token, expected end of statement");
8372 return false;
8373 }
8374
8375 return false; // parseDirectiveModule has finished successfully.
8376 } else if (Option == "novirt") {
8377 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8378
8379 // Synchronize the ABI Flags information with the FeatureBits information we
8380 // updated above.
8381 getTargetStreamer().updateABIInfo(*this);
8382
8383 // If printing assembly, use the recently updated ABI Flags information.
8384 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8385 // emitted later).
8386 getTargetStreamer().emitDirectiveModuleNoVirt();
8387
8388 // If this is not the end of the statement, report an error.
8389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8390 reportParseError("unexpected token, expected end of statement");
8391 return false;
8392 }
8393
8394 return false; // parseDirectiveModule has finished successfully.
8395 } else if (Option == "ginv") {
8396 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8397
8398 // Synchronize the ABI Flags information with the FeatureBits information we
8399 // updated above.
8400 getTargetStreamer().updateABIInfo(*this);
8401
8402 // If printing assembly, use the recently updated ABI Flags information.
8403 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8404 // emitted later).
8405 getTargetStreamer().emitDirectiveModuleGINV();
8406
8407 // If this is not the end of the statement, report an error.
8408 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8409 reportParseError("unexpected token, expected end of statement");
8410 return false;
8411 }
8412
8413 return false; // parseDirectiveModule has finished successfully.
8414 } else if (Option == "noginv") {
8415 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8416
8417 // Synchronize the ABI Flags information with the FeatureBits information we
8418 // updated above.
8419 getTargetStreamer().updateABIInfo(*this);
8420
8421 // If printing assembly, use the recently updated ABI Flags information.
8422 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8423 // emitted later).
8424 getTargetStreamer().emitDirectiveModuleNoGINV();
8425
8426 // If this is not the end of the statement, report an error.
8427 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8428 reportParseError("unexpected token, expected end of statement");
8429 return false;
8430 }
8431
8432 return false; // parseDirectiveModule has finished successfully.
8433 } else {
8434 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8435 }
8436}
8437
8438/// parseDirectiveModuleFP
8439/// ::= =32
8440/// ::= =xx
8441/// ::= =64
8442bool MipsAsmParser::parseDirectiveModuleFP() {
8443 MCAsmParser &Parser = getParser();
8444 AsmLexer &Lexer = getLexer();
8445
8446 if (Lexer.isNot(AsmToken::Equal)) {
8447 reportParseError("unexpected token, expected equals sign '='");
8448 return false;
8449 }
8450 Parser.Lex(); // Eat '=' token.
8451
8453 if (!parseFpABIValue(FpABI, ".module"))
8454 return false;
8455
8456 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8457 reportParseError("unexpected token, expected end of statement");
8458 return false;
8459 }
8460
8461 // Synchronize the abiflags information with the FeatureBits information we
8462 // changed above.
8463 getTargetStreamer().updateABIInfo(*this);
8464
8465 // If printing assembly, use the recently updated abiflags information.
8466 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8467 // emitted at the end).
8468 getTargetStreamer().emitDirectiveModuleFP();
8469
8470 Parser.Lex(); // Consume the EndOfStatement.
8471 return false;
8472}
8473
8474bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8475 StringRef Directive) {
8476 MCAsmParser &Parser = getParser();
8477 AsmLexer &Lexer = getLexer();
8478 bool ModuleLevelOptions = Directive == ".module";
8479
8480 if (Lexer.is(AsmToken::Identifier)) {
8481 StringRef Value = Parser.getTok().getString();
8482 Parser.Lex();
8483
8484 if (Value != "xx") {
8485 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8486 return false;
8487 }
8488
8489 if (!isABI_O32()) {
8490 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8491 return false;
8492 }
8493
8494 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8495 if (ModuleLevelOptions) {
8496 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8497 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8498 } else {
8499 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8500 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8501 }
8502 return true;
8503 }
8504
8505 if (Lexer.is(AsmToken::Integer)) {
8506 unsigned Value = Parser.getTok().getIntVal();
8507 Parser.Lex();
8508
8509 if (Value != 32 && Value != 64) {
8510 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8511 return false;
8512 }
8513
8514 if (Value == 32) {
8515 if (!isABI_O32()) {
8516 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8517 return false;
8518 }
8519
8520 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8521 if (ModuleLevelOptions) {
8522 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8523 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8524 } else {
8525 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8526 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8527 }
8528 } else {
8529 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8530 if (ModuleLevelOptions) {
8531 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8532 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8533 } else {
8534 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8535 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8536 }
8537 }
8538
8539 return true;
8540 }
8541
8542 return false;
8543}
8544
8545bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8546 // This returns false if this function recognizes the directive
8547 // regardless of whether it is successfully handles or reports an
8548 // error. Otherwise it returns true to give the generic parser a
8549 // chance at recognizing it.
8550
8551 MCAsmParser &Parser = getParser();
8552 StringRef IDVal = DirectiveID.getString();
8553
8554 if (IDVal == ".cpadd") {
8555 parseDirectiveCpAdd(DirectiveID.getLoc());
8556 return false;
8557 }
8558 if (IDVal == ".cpload") {
8559 parseDirectiveCpLoad(DirectiveID.getLoc());
8560 return false;
8561 }
8562 if (IDVal == ".cprestore") {
8563 parseDirectiveCpRestore(DirectiveID.getLoc());
8564 return false;
8565 }
8566 if (IDVal == ".cplocal") {
8567 parseDirectiveCpLocal(DirectiveID.getLoc());
8568 return false;
8569 }
8570 if (IDVal == ".ent") {
8571 StringRef SymbolName;
8572
8573 if (Parser.parseIdentifier(SymbolName)) {
8574 reportParseError("expected identifier after .ent");
8575 return false;
8576 }
8577
8578 // There's an undocumented extension that allows an integer to
8579 // follow the name of the procedure which AFAICS is ignored by GAS.
8580 // Example: .ent foo,2
8581 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8582 if (getLexer().isNot(AsmToken::Comma)) {
8583 // Even though we accept this undocumented extension for compatibility
8584 // reasons, the additional integer argument does not actually change
8585 // the behaviour of the '.ent' directive, so we would like to discourage
8586 // its use. We do this by not referring to the extended version in
8587 // error messages which are not directly related to its use.
8588 reportParseError("unexpected token, expected end of statement");
8589 return false;
8590 }
8591 Parser.Lex(); // Eat the comma.
8592 const MCExpr *DummyNumber;
8593 int64_t DummyNumberVal;
8594 // If the user was explicitly trying to use the extended version,
8595 // we still give helpful extension-related error messages.
8596 if (Parser.parseExpression(DummyNumber)) {
8597 reportParseError("expected number after comma");
8598 return false;
8599 }
8600 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8601 reportParseError("expected an absolute expression after comma");
8602 return false;
8603 }
8604 }
8605
8606 // If this is not the end of the statement, report an error.
8607 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8608 reportParseError("unexpected token, expected end of statement");
8609 return false;
8610 }
8611
8612 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8613
8614 getTargetStreamer().emitDirectiveEnt(*Sym);
8615 CurrentFn = Sym;
8616 IsCpRestoreSet = false;
8617 return false;
8618 }
8619
8620 if (IDVal == ".end") {
8621 StringRef SymbolName;
8622
8623 if (Parser.parseIdentifier(SymbolName)) {
8624 reportParseError("expected identifier after .end");
8625 return false;
8626 }
8627
8628 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8629 reportParseError("unexpected token, expected end of statement");
8630 return false;
8631 }
8632
8633 if (CurrentFn == nullptr) {
8634 reportParseError(".end used without .ent");
8635 return false;
8636 }
8637
8638 if ((SymbolName != CurrentFn->getName())) {
8639 reportParseError(".end symbol does not match .ent symbol");
8640 return false;
8641 }
8642
8643 getTargetStreamer().emitDirectiveEnd(SymbolName);
8644 CurrentFn = nullptr;
8645 IsCpRestoreSet = false;
8646 return false;
8647 }
8648
8649 if (IDVal == ".frame") {
8650 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8652 ParseStatus Res = parseAnyRegister(TmpReg);
8653 if (Res.isNoMatch() || Res.isFailure()) {
8654 reportParseError("expected stack register");
8655 return false;
8656 }
8657
8658 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8659 if (!StackRegOpnd.isGPRAsmReg()) {
8660 reportParseError(StackRegOpnd.getStartLoc(),
8661 "expected general purpose register");
8662 return false;
8663 }
8664 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8665
8666 if (Parser.getTok().is(AsmToken::Comma))
8667 Parser.Lex();
8668 else {
8669 reportParseError("unexpected token, expected comma");
8670 return false;
8671 }
8672
8673 // Parse the frame size.
8674 const MCExpr *FrameSize;
8675 int64_t FrameSizeVal;
8676
8677 if (Parser.parseExpression(FrameSize)) {
8678 reportParseError("expected frame size value");
8679 return false;
8680 }
8681
8682 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8683 reportParseError("frame size not an absolute expression");
8684 return false;
8685 }
8686
8687 if (Parser.getTok().is(AsmToken::Comma))
8688 Parser.Lex();
8689 else {
8690 reportParseError("unexpected token, expected comma");
8691 return false;
8692 }
8693
8694 // Parse the return register.
8695 TmpReg.clear();
8696 Res = parseAnyRegister(TmpReg);
8697 if (Res.isNoMatch() || Res.isFailure()) {
8698 reportParseError("expected return register");
8699 return false;
8700 }
8701
8702 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8703 if (!ReturnRegOpnd.isGPRAsmReg()) {
8704 reportParseError(ReturnRegOpnd.getStartLoc(),
8705 "expected general purpose register");
8706 return false;
8707 }
8708
8709 // If this is not the end of the statement, report an error.
8710 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8711 reportParseError("unexpected token, expected end of statement");
8712 return false;
8713 }
8714
8715 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8716 ReturnRegOpnd.getGPR32Reg());
8717 IsCpRestoreSet = false;
8718 return false;
8719 }
8720
8721 if (IDVal == ".set") {
8722 parseDirectiveSet();
8723 return false;
8724 }
8725
8726 if (IDVal == ".mask" || IDVal == ".fmask") {
8727 // .mask bitmask, frame_offset
8728 // bitmask: One bit for each register used.
8729 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8730 // first register is expected to be saved.
8731 // Examples:
8732 // .mask 0x80000000, -4
8733 // .fmask 0x80000000, -4
8734 //
8735
8736 // Parse the bitmask
8737 const MCExpr *BitMask;
8738 int64_t BitMaskVal;
8739
8740 if (Parser.parseExpression(BitMask)) {
8741 reportParseError("expected bitmask value");
8742 return false;
8743 }
8744
8745 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8746 reportParseError("bitmask not an absolute expression");
8747 return false;
8748 }
8749
8750 if (Parser.getTok().is(AsmToken::Comma))
8751 Parser.Lex();
8752 else {
8753 reportParseError("unexpected token, expected comma");
8754 return false;
8755 }
8756
8757 // Parse the frame_offset
8758 const MCExpr *FrameOffset;
8759 int64_t FrameOffsetVal;
8760
8761 if (Parser.parseExpression(FrameOffset)) {
8762 reportParseError("expected frame offset value");
8763 return false;
8764 }
8765
8766 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8767 reportParseError("frame offset not an absolute expression");
8768 return false;
8769 }
8770
8771 // If this is not the end of the statement, report an error.
8772 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8773 reportParseError("unexpected token, expected end of statement");
8774 return false;
8775 }
8776
8777 if (IDVal == ".mask")
8778 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8779 else
8780 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8781 return false;
8782 }
8783
8784 if (IDVal == ".nan")
8785 return parseDirectiveNaN();
8786
8787 if (IDVal == ".gpword") {
8788 parseDirectiveGpWord();
8789 return false;
8790 }
8791
8792 if (IDVal == ".gpdword") {
8793 parseDirectiveGpDWord();
8794 return false;
8795 }
8796
8797 if (IDVal == ".dtprelword") {
8798 parseDirectiveDtpRelWord();
8799 return false;
8800 }
8801
8802 if (IDVal == ".dtpreldword") {
8803 parseDirectiveDtpRelDWord();
8804 return false;
8805 }
8806
8807 if (IDVal == ".tprelword") {
8808 parseDirectiveTpRelWord();
8809 return false;
8810 }
8811
8812 if (IDVal == ".tpreldword") {
8813 parseDirectiveTpRelDWord();
8814 return false;
8815 }
8816
8817 if (IDVal == ".option") {
8818 parseDirectiveOption();
8819 return false;
8820 }
8821
8822 if (IDVal == ".abicalls") {
8823 getTargetStreamer().emitDirectiveAbiCalls();
8824 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8825 Error(Parser.getTok().getLoc(),
8826 "unexpected token, expected end of statement");
8827 }
8828 return false;
8829 }
8830
8831 if (IDVal == ".cpsetup") {
8832 parseDirectiveCPSetup();
8833 return false;
8834 }
8835 if (IDVal == ".cpreturn") {
8836 parseDirectiveCPReturn();
8837 return false;
8838 }
8839 if (IDVal == ".module") {
8840 parseDirectiveModule();
8841 return false;
8842 }
8843 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8844 parseInternalDirectiveReallowModule();
8845 return false;
8846 }
8847 if (IDVal == ".insn") {
8848 parseInsnDirective();
8849 return false;
8850 }
8851 if (IDVal == ".rdata") {
8852 parseRSectionDirective(".rodata");
8853 return false;
8854 }
8855 if (IDVal == ".sbss") {
8856 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8857 return false;
8858 }
8859 if (IDVal == ".sdata") {
8860 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8861 return false;
8862 }
8863
8864 return true;
8865}
8866
8867bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8868 // If this is not the end of the statement, report an error.
8869 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8870 reportParseError("unexpected token, expected end of statement");
8871 return false;
8872 }
8873
8874 getTargetStreamer().reallowModuleDirective();
8875
8876 getParser().Lex(); // Eat EndOfStatement token.
8877 return false;
8878}
8879
8880extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
8887
8888#define GET_REGISTER_MATCHER
8889#define GET_MATCHER_IMPLEMENTATION
8890#define GET_MNEMONIC_SPELL_CHECKER
8891#include "MipsGenAsmMatcher.inc"
8892
8893bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8894 // Find the appropriate table for this asm variant.
8895 const MatchEntry *Start, *End;
8896 switch (VariantID) {
8897 default: llvm_unreachable("invalid variant!");
8898 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8899 }
8900 // Search the table.
8901 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8902 return MnemonicRange.first != MnemonicRange.second;
8903}
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.
@ 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,...