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