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