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