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