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