LLVM 20.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
14#include "MipsTargetStreamer.h"
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
71
72namespace {
73
74class MipsAssemblerOptions {
75public:
76 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
77
78 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
83 }
84
85 unsigned getATRegIndex() const { return ATReg; }
86 bool setATRegIndex(unsigned Reg) {
87 if (Reg > 31)
88 return false;
89
90 ATReg = Reg;
91 return true;
92 }
93
94 bool isReorder() const { return Reorder; }
95 void setReorder() { Reorder = true; }
96 void setNoReorder() { Reorder = false; }
97
98 bool isMacro() const { return Macro; }
99 void setMacro() { Macro = true; }
100 void setNoMacro() { Macro = false; }
101
102 const FeatureBitset &getFeatures() const { return Features; }
103 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
104
105 // Set of features that are either architecture features or referenced
106 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
107 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
108 // The reason we need this mask is explained in the selectArch function.
109 // FIXME: Ideally we would like TableGen to generate this information.
110 static const FeatureBitset AllArchRelatedMask;
111
112private:
113 unsigned ATReg = 1;
114 bool Reorder = true;
115 bool Macro = true;
116 FeatureBitset Features;
117};
118
119} // end anonymous namespace
120
121const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
130 Mips::FeatureNaN2008
131};
132
133namespace {
134
135class MipsAsmParser : public MCTargetAsmParser {
136 MipsTargetStreamer &getTargetStreamer() {
137 assert(getParser().getStreamer().getTargetStreamer() &&
138 "do not have a target streamer");
140 return static_cast<MipsTargetStreamer &>(TS);
141 }
142
145 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
146 // nullptr, which indicates that no function is currently
147 // selected. This usually happens after an '.end func'
148 // directive.
149 bool IsLittleEndian;
150 bool IsPicEnabled;
151 bool IsCpRestoreSet;
152 bool CurForbiddenSlotAttr;
153 int CpRestoreOffset;
154 unsigned GPReg;
155 unsigned CpSaveLocation;
156 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
157 bool CpSaveLocationIsRegister;
158
159 // Map of register aliases created via the .set directive.
160 StringMap<AsmToken> RegisterSets;
161
162 // Print a warning along with its fix-it message at the given range.
163 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
164 SMRange Range, bool ShowColors = true);
165
166 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
167
168#define GET_ASSEMBLER_HEADER
169#include "MipsGenAsmMatcher.inc"
170
171 unsigned
173 const OperandVector &Operands) override;
174 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
175
176 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
179 bool MatchingInlineAsm) override;
180
181 /// Parse a register as used in CFI directives
182 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
184 SMLoc &EndLoc) override;
185
186 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
187
188 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
189
190 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
191
193 SMLoc NameLoc, OperandVector &Operands) override;
194
195 bool ParseDirective(AsmToken DirectiveID) override;
196
197 ParseStatus parseMemOperand(OperandVector &Operands);
198 ParseStatus matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
199 StringRef Identifier, SMLoc S);
200 ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands,
201 const AsmToken &Token, SMLoc S);
202 ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
203 ParseStatus parseAnyRegister(OperandVector &Operands);
205 ParseStatus parseJumpTarget(OperandVector &Operands);
206 ParseStatus parseInvNum(OperandVector &Operands);
207 ParseStatus parseRegisterList(OperandVector &Operands);
208
209 bool searchSymbolAlias(OperandVector &Operands);
210
211 bool parseOperand(OperandVector &, StringRef Mnemonic);
212
213 enum MacroExpanderResultTy {
214 MER_NotAMacro,
215 MER_Success,
216 MER_Fail,
217 };
218
219 // Expands assembly pseudo instructions.
220 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
221 MCStreamer &Out,
222 const MCSubtargetInfo *STI);
223
224 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
225 const MCSubtargetInfo *STI);
226
227 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
228 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
229 MCStreamer &Out, const MCSubtargetInfo *STI);
230
231 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
232 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
233 MCStreamer &Out, const MCSubtargetInfo *STI);
234
235 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
236
237 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
238 MCStreamer &Out, const MCSubtargetInfo *STI);
239
240 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI);
242 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
243 const MCSubtargetInfo *STI);
244 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
245 const MCSubtargetInfo *STI);
246 bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
247 MCStreamer &Out, const MCSubtargetInfo *STI);
248
249 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
250 const MCOperand &Offset, bool Is32BitAddress,
251 SMLoc IDLoc, MCStreamer &Out,
252 const MCSubtargetInfo *STI);
253
254 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI);
256
257 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI, bool IsLoad);
259 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
260 const MCSubtargetInfo *STI, bool IsLoad);
261
262 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
263 const MCSubtargetInfo *STI);
264
265 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
267
268 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
270
271 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
273
274 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI, const bool IsMips64,
276 const bool Signed);
277
278 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
279 MCStreamer &Out, const MCSubtargetInfo *STI);
280
281 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
282 const MCSubtargetInfo *STI);
283
284 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
285 const MCSubtargetInfo *STI);
286
287 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
288 const MCSubtargetInfo *STI);
289
290 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291 const MCSubtargetInfo *STI);
292
293 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
294 const MCSubtargetInfo *STI);
295
296 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
298
299 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
300 const MCSubtargetInfo *STI);
301
302 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
303 const MCSubtargetInfo *STI);
304
305 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
306 MCStreamer &Out, const MCSubtargetInfo *STI);
307 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308 const MCSubtargetInfo *STI);
309 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310 const MCSubtargetInfo *STI);
311 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
312 const MCSubtargetInfo *STI);
313
314 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
315 const MCSubtargetInfo *STI);
316
317 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
318 const MCSubtargetInfo *STI);
319
320 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
321 const MCSubtargetInfo *STI);
322
323 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
324 const MCSubtargetInfo *STI);
325
326 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
327 const MCSubtargetInfo *STI);
328
329 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
330 const MCSubtargetInfo *STI, bool IsLoad);
331
332 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
333 const MCSubtargetInfo *STI);
334
335 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
336 const MCSubtargetInfo *STI);
337
338 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
339 const MCSubtargetInfo *STI);
340
341 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
342 const MCSubtargetInfo *STI);
343
344 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
345 const MCSubtargetInfo *STI);
346
347 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
348 const MCSubtargetInfo *STI);
349
350 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
351 const MCSubtargetInfo *STI);
352
353 bool reportParseError(const Twine &ErrorMsg);
354 bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
355
356 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
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,
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 unsigned 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 unsigned 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);
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();
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();
493 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
494 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
495 }
496 }
497
498 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
499 setFeatureBits(Feature, FeatureString);
500 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
501 }
502
503 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
504 clearFeatureBits(Feature, FeatureString);
505 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
506 }
507
508public:
509 enum MipsMatchResultTy {
510 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
511 Match_RequiresDifferentOperands,
512 Match_RequiresNoZeroRegister,
513 Match_RequiresSameSrcAndDst,
514 Match_NoFCCRegisterForCurrentISA,
515 Match_NonZeroOperandForSync,
516 Match_NonZeroOperandForMTCX,
517 Match_RequiresPosSizeRange0_32,
518 Match_RequiresPosSizeRange33_64,
519 Match_RequiresPosSizeUImm6,
520#define GET_OPERAND_DIAGNOSTIC_TYPES
521#include "MipsGenAsmMatcher.inc"
522#undef GET_OPERAND_DIAGNOSTIC_TYPES
523 };
524
525 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
526 const MCInstrInfo &MII, const MCTargetOptions &Options)
527 : MCTargetAsmParser(Options, sti, MII),
528 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
529 sti.getCPU(), Options)) {
531
532 parser.addAliasForDirective(".asciiz", ".asciz");
533 parser.addAliasForDirective(".hword", ".2byte");
534 parser.addAliasForDirective(".word", ".4byte");
535 parser.addAliasForDirective(".dword", ".8byte");
536
537 // Initialize the set of available features.
538 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
539
540 // Remember the initial assembler options. The user can not modify these.
541 AssemblerOptions.push_back(
542 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
543
544 // Create an assembler options environment for the user to modify.
545 AssemblerOptions.push_back(
546 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
547
548 getTargetStreamer().updateABIInfo(*this);
549
550 if (!isABI_O32() && !useOddSPReg() != 0)
551 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
552
553 CurrentFn = nullptr;
554
555 CurForbiddenSlotAttr = false;
557
558 IsCpRestoreSet = false;
559 CpRestoreOffset = -1;
560 GPReg = ABI.GetGlobalPtr();
561
562 const Triple &TheTriple = sti.getTargetTriple();
563 IsLittleEndian = TheTriple.isLittleEndian();
564
565 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
566 report_fatal_error("microMIPS64R6 is not supported", false);
567
568 if (!isABI_O32() && inMicroMipsMode())
569 report_fatal_error("microMIPS64 is not supported", false);
570 }
571
572 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
573 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
574
575 bool isGP64bit() const {
576 return getSTI().hasFeature(Mips::FeatureGP64Bit);
577 }
578
579 bool isFP64bit() const {
580 return getSTI().hasFeature(Mips::FeatureFP64Bit);
581 }
582
583 bool isJalrRelocAvailable(const MCExpr *JalExpr) {
584 if (!EmitJalrReloc)
585 return false;
586 MCValue Res;
587 if (!JalExpr->evaluateAsRelocatable(Res, nullptr, nullptr))
588 return false;
589 if (Res.getSymB() != nullptr)
590 return false;
591 if (Res.getConstant() != 0)
592 return ABI.IsN32() || ABI.IsN64();
593 return true;
594 }
595
596 const MipsABIInfo &getABI() const { return ABI; }
597 bool isABI_N32() const { return ABI.IsN32(); }
598 bool isABI_N64() const { return ABI.IsN64(); }
599 bool isABI_O32() const { return ABI.IsO32(); }
600 bool isABI_FPXX() const {
601 return getSTI().hasFeature(Mips::FeatureFPXX);
602 }
603
604 bool useOddSPReg() const {
605 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
606 }
607
608 bool inMicroMipsMode() const {
609 return getSTI().hasFeature(Mips::FeatureMicroMips);
610 }
611
612 bool hasMips1() const {
613 return getSTI().hasFeature(Mips::FeatureMips1);
614 }
615
616 bool hasMips2() const {
617 return getSTI().hasFeature(Mips::FeatureMips2);
618 }
619
620 bool hasMips3() const {
621 return getSTI().hasFeature(Mips::FeatureMips3);
622 }
623
624 bool hasMips4() const {
625 return getSTI().hasFeature(Mips::FeatureMips4);
626 }
627
628 bool hasMips5() const {
629 return getSTI().hasFeature(Mips::FeatureMips5);
630 }
631
632 bool hasMips32() const {
633 return getSTI().hasFeature(Mips::FeatureMips32);
634 }
635
636 bool hasMips64() const {
637 return getSTI().hasFeature(Mips::FeatureMips64);
638 }
639
640 bool hasMips32r2() const {
641 return getSTI().hasFeature(Mips::FeatureMips32r2);
642 }
643
644 bool hasMips64r2() const {
645 return getSTI().hasFeature(Mips::FeatureMips64r2);
646 }
647
648 bool hasMips32r3() const {
649 return (getSTI().hasFeature(Mips::FeatureMips32r3));
650 }
651
652 bool hasMips64r3() const {
653 return (getSTI().hasFeature(Mips::FeatureMips64r3));
654 }
655
656 bool hasMips32r5() const {
657 return (getSTI().hasFeature(Mips::FeatureMips32r5));
658 }
659
660 bool hasMips64r5() const {
661 return (getSTI().hasFeature(Mips::FeatureMips64r5));
662 }
663
664 bool hasMips32r6() const {
665 return getSTI().hasFeature(Mips::FeatureMips32r6);
666 }
667
668 bool hasMips64r6() const {
669 return getSTI().hasFeature(Mips::FeatureMips64r6);
670 }
671
672 bool hasDSP() const {
673 return getSTI().hasFeature(Mips::FeatureDSP);
674 }
675
676 bool hasDSPR2() const {
677 return getSTI().hasFeature(Mips::FeatureDSPR2);
678 }
679
680 bool hasDSPR3() const {
681 return getSTI().hasFeature(Mips::FeatureDSPR3);
682 }
683
684 bool hasMSA() const {
685 return getSTI().hasFeature(Mips::FeatureMSA);
686 }
687
688 bool hasCnMips() const {
689 return (getSTI().hasFeature(Mips::FeatureCnMips));
690 }
691
692 bool hasCnMipsP() const {
693 return (getSTI().hasFeature(Mips::FeatureCnMipsP));
694 }
695
696 bool inPicMode() {
697 return IsPicEnabled;
698 }
699
700 bool inMips16Mode() const {
701 return getSTI().hasFeature(Mips::FeatureMips16);
702 }
703
704 bool useTraps() const {
705 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
706 }
707
708 bool useSoftFloat() const {
709 return getSTI().hasFeature(Mips::FeatureSoftFloat);
710 }
711 bool hasMT() const {
712 return getSTI().hasFeature(Mips::FeatureMT);
713 }
714
715 bool hasCRC() const {
716 return getSTI().hasFeature(Mips::FeatureCRC);
717 }
718
719 bool hasVirt() const {
720 return getSTI().hasFeature(Mips::FeatureVirt);
721 }
722
723 bool hasGINV() const {
724 return getSTI().hasFeature(Mips::FeatureGINV);
725 }
726
727 bool hasForbiddenSlot(const MCInstrDesc &MCID) const {
728 return !inMicroMipsMode() && (MCID.TSFlags & MipsII::HasForbiddenSlot);
729 }
730
731 bool SafeInForbiddenSlot(const MCInstrDesc &MCID) const {
732 return !(MCID.TSFlags & MipsII::IsCTI);
733 }
734
735 void onEndOfFile() override;
736
737 /// Warn if RegIndex is the same as the current AT.
738 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
739
740 void warnIfNoMacro(SMLoc Loc);
741
742 bool isLittle() const { return IsLittleEndian; }
743
744 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
745 AsmToken::TokenKind OperatorToken,
746 MCContext &Ctx) override {
747 switch(OperatorToken) {
748 default:
749 llvm_unreachable("Unknown token");
750 return nullptr;
799 }
800 }
801
802 bool areEqualRegs(const MCParsedAsmOperand &Op1,
803 const MCParsedAsmOperand &Op2) const override;
804};
805
806/// MipsOperand - Instances of this class represent a parsed Mips machine
807/// instruction.
808class MipsOperand : public MCParsedAsmOperand {
809public:
810 /// Broad categories of register classes
811 /// The exact class is finalized by the render method.
812 enum RegKind {
813 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
814 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
815 /// isFP64bit())
816 RegKind_FCC = 4, /// FCC
817 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
818 RegKind_MSACtrl = 16, /// MSA control registers
819 RegKind_COP2 = 32, /// COP2
820 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
821 /// context).
822 RegKind_CCR = 128, /// CCR
823 RegKind_HWRegs = 256, /// HWRegs
824 RegKind_COP3 = 512, /// COP3
825 RegKind_COP0 = 1024, /// COP0
826 /// Potentially any (e.g. $1)
827 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
828 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
829 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
830 };
831
832private:
833 enum KindTy {
834 k_Immediate, /// An immediate (possibly involving symbol references)
835 k_Memory, /// Base + Offset Memory Address
836 k_RegisterIndex, /// A register index in one or more RegKind.
837 k_Token, /// A simple token
838 k_RegList, /// A physical register list
839 } Kind;
840
841public:
842 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(K), AsmParser(Parser) {}
843
844 ~MipsOperand() override {
845 switch (Kind) {
846 case k_Memory:
847 delete Mem.Base;
848 break;
849 case k_RegList:
850 delete RegList.List;
851 break;
852 case k_Immediate:
853 case k_RegisterIndex:
854 case k_Token:
855 break;
856 }
857 }
858
859private:
860 /// For diagnostics, and checking the assembler temporary
861 MipsAsmParser &AsmParser;
862
863 struct Token {
864 const char *Data;
865 unsigned Length;
866 };
867
868 struct RegIdxOp {
869 unsigned Index; /// Index into the register class
870 RegKind Kind; /// Bitfield of the kinds it could possibly be
871 struct Token Tok; /// The input token this operand originated from.
872 const MCRegisterInfo *RegInfo;
873 };
874
875 struct ImmOp {
876 const MCExpr *Val;
877 };
878
879 struct MemOp {
880 MipsOperand *Base;
881 const MCExpr *Off;
882 };
883
884 struct RegListOp {
886 };
887
888 union {
889 struct Token Tok;
890 struct RegIdxOp RegIdx;
891 struct ImmOp Imm;
892 struct MemOp Mem;
893 struct RegListOp RegList;
894 };
895
896 SMLoc StartLoc, EndLoc;
897
898 /// Internal constructor for register kinds
899 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
900 RegKind RegKind,
901 const MCRegisterInfo *RegInfo,
902 SMLoc S, SMLoc E,
903 MipsAsmParser &Parser) {
904 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
905 Op->RegIdx.Index = Index;
906 Op->RegIdx.RegInfo = RegInfo;
907 Op->RegIdx.Kind = RegKind;
908 Op->RegIdx.Tok.Data = Str.data();
909 Op->RegIdx.Tok.Length = Str.size();
910 Op->StartLoc = S;
911 Op->EndLoc = E;
912 return Op;
913 }
914
915public:
916 /// Coerce the register to GPR32 and return the real register for the current
917 /// target.
918 unsigned getGPR32Reg() const {
919 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
920 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
921 unsigned ClassID = Mips::GPR32RegClassID;
922 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
923 }
924
925 /// Coerce the register to GPR32 and return the real register for the current
926 /// target.
927 unsigned getGPRMM16Reg() const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
929 unsigned ClassID = Mips::GPR32RegClassID;
930 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
931 }
932
933 /// Coerce the register to GPR64 and return the real register for the current
934 /// target.
935 unsigned getGPR64Reg() const {
936 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
937 unsigned ClassID = Mips::GPR64RegClassID;
938 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
939 }
940
941private:
942 /// Coerce the register to AFGR64 and return the real register for the current
943 /// target.
944 unsigned getAFGR64Reg() const {
945 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
946 if (RegIdx.Index % 2 != 0)
947 AsmParser.Warning(StartLoc, "Float register should be even.");
948 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
949 .getRegister(RegIdx.Index / 2);
950 }
951
952 /// Coerce the register to FGR64 and return the real register for the current
953 /// target.
954 unsigned getFGR64Reg() const {
955 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
956 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
957 .getRegister(RegIdx.Index);
958 }
959
960 /// Coerce the register to FGR32 and return the real register for the current
961 /// target.
962 unsigned getFGR32Reg() const {
963 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
964 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
965 .getRegister(RegIdx.Index);
966 }
967
968 /// Coerce the register to FCC and return the real register for the current
969 /// target.
970 unsigned getFCCReg() const {
971 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
972 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
973 .getRegister(RegIdx.Index);
974 }
975
976 /// Coerce the register to MSA128 and return the real register for the current
977 /// target.
978 unsigned getMSA128Reg() const {
979 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
980 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
981 // identical
982 unsigned ClassID = Mips::MSA128BRegClassID;
983 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
984 }
985
986 /// Coerce the register to MSACtrl and return the real register for the
987 /// current target.
988 unsigned getMSACtrlReg() const {
989 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
990 unsigned ClassID = Mips::MSACtrlRegClassID;
991 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
992 }
993
994 /// Coerce the register to COP0 and return the real register for the
995 /// current target.
996 unsigned getCOP0Reg() const {
997 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
998 unsigned ClassID = Mips::COP0RegClassID;
999 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1000 }
1001
1002 /// Coerce the register to COP2 and return the real register for the
1003 /// current target.
1004 unsigned getCOP2Reg() const {
1005 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
1006 unsigned ClassID = Mips::COP2RegClassID;
1007 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1008 }
1009
1010 /// Coerce the register to COP3 and return the real register for the
1011 /// current target.
1012 unsigned getCOP3Reg() const {
1013 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
1014 unsigned ClassID = Mips::COP3RegClassID;
1015 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1016 }
1017
1018 /// Coerce the register to ACC64DSP and return the real register for the
1019 /// current target.
1020 unsigned getACC64DSPReg() const {
1021 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1022 unsigned ClassID = Mips::ACC64DSPRegClassID;
1023 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1024 }
1025
1026 /// Coerce the register to HI32DSP and return the real register for the
1027 /// current target.
1028 unsigned getHI32DSPReg() const {
1029 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1030 unsigned ClassID = Mips::HI32DSPRegClassID;
1031 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1032 }
1033
1034 /// Coerce the register to LO32DSP and return the real register for the
1035 /// current target.
1036 unsigned getLO32DSPReg() const {
1037 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1038 unsigned ClassID = Mips::LO32DSPRegClassID;
1039 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1040 }
1041
1042 /// Coerce the register to CCR and return the real register for the
1043 /// current target.
1044 unsigned getCCRReg() const {
1045 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
1046 unsigned ClassID = Mips::CCRRegClassID;
1047 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1048 }
1049
1050 /// Coerce the register to HWRegs and return the real register for the
1051 /// current target.
1052 unsigned getHWRegsReg() const {
1053 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
1054 unsigned ClassID = Mips::HWRegsRegClassID;
1055 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1056 }
1057
1058public:
1059 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1060 // Add as immediate when possible. Null MCExpr = 0.
1061 if (!Expr)
1063 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1064 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1065 else
1067 }
1068
1069 void addRegOperands(MCInst &Inst, unsigned N) const {
1070 llvm_unreachable("Use a custom parser instead");
1071 }
1072
1073 /// Render the operand to an MCInst as a GPR32
1074 /// Asserts if the wrong number of operands are requested, or the operand
1075 /// is not a k_RegisterIndex compatible with RegKind_GPR
1076 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1077 assert(N == 1 && "Invalid number of operands!");
1078 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1079 }
1080
1081 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1082 assert(N == 1 && "Invalid number of operands!");
1083 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1084 }
1085
1086 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1087 assert(N == 1 && "Invalid number of operands!");
1088 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1089 }
1090
1091 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1092 assert(N == 1 && "Invalid number of operands!");
1093 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1094 }
1095
1096 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1097 assert(N == 1 && "Invalid number of operands!");
1098 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1099 }
1100
1101 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1102 assert(N == 1 && "Invalid number of operands!");
1103 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1104 }
1105
1106 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1107 assert(N == 1 && "Invalid number of operands!");
1108 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1109 }
1110
1111 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1112 unsigned N) const {
1113 assert(N == 1 && "Invalid number of operands!");
1114 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1115 }
1116
1117 /// Render the operand to an MCInst as a GPR64
1118 /// Asserts if the wrong number of operands are requested, or the operand
1119 /// is not a k_RegisterIndex compatible with RegKind_GPR
1120 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1121 assert(N == 1 && "Invalid number of operands!");
1122 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1123 }
1124
1125 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1126 assert(N == 1 && "Invalid number of operands!");
1127 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1128 }
1129
1130 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1131 assert(N == 1 && "Invalid number of operands!");
1132 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1133 }
1134
1135 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1136 assert(N == 1 && "Invalid number of operands!");
1137 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1138 }
1139
1140 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1141 assert(N == 1 && "Invalid number of operands!");
1142 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1143 }
1144
1145 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1146 assert(N == 1 && "Invalid number of operands!");
1147 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1148 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1149 // FIXME: This should propagate failure up to parseStatement.
1150 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1151 AsmParser.getParser().printError(
1152 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1153 "registers");
1154 }
1155
1156 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1157 assert(N == 1 && "Invalid number of operands!");
1158 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1159 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1160 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1161 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1162 "registers");
1163 }
1164
1165 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1166 assert(N == 1 && "Invalid number of operands!");
1167 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1168 }
1169
1170 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1171 assert(N == 1 && "Invalid number of operands!");
1172 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1173 }
1174
1175 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1176 assert(N == 1 && "Invalid number of operands!");
1177 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1178 }
1179
1180 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1181 assert(N == 1 && "Invalid number of operands!");
1182 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1183 }
1184
1185 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1186 assert(N == 1 && "Invalid number of operands!");
1187 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1188 }
1189
1190 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1191 assert(N == 1 && "Invalid number of operands!");
1192 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1193 }
1194
1195 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1196 assert(N == 1 && "Invalid number of operands!");
1197 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1198 }
1199
1200 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1201 assert(N == 1 && "Invalid number of operands!");
1202 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1203 }
1204
1205 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1206 assert(N == 1 && "Invalid number of operands!");
1207 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1208 }
1209
1210 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1211 assert(N == 1 && "Invalid number of operands!");
1212 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1213 }
1214
1215 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1216 assert(N == 1 && "Invalid number of operands!");
1217 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1218 }
1219
1220 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1221 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1222 assert(N == 1 && "Invalid number of operands!");
1223 uint64_t Imm = getConstantImm() - Offset;
1224 Imm &= (1ULL << Bits) - 1;
1225 Imm += Offset;
1226 Imm += AdjustOffset;
1228 }
1229
1230 template <unsigned Bits>
1231 void addSImmOperands(MCInst &Inst, unsigned N) const {
1232 if (isImm() && !isConstantImm()) {
1233 addExpr(Inst, getImm());
1234 return;
1235 }
1236 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1237 }
1238
1239 template <unsigned Bits>
1240 void addUImmOperands(MCInst &Inst, unsigned N) const {
1241 if (isImm() && !isConstantImm()) {
1242 addExpr(Inst, getImm());
1243 return;
1244 }
1245 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1246 }
1247
1248 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1249 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1250 assert(N == 1 && "Invalid number of operands!");
1251 int64_t Imm = getConstantImm() - Offset;
1252 Imm = SignExtend64<Bits>(Imm);
1253 Imm += Offset;
1254 Imm += AdjustOffset;
1256 }
1257
1258 void addImmOperands(MCInst &Inst, unsigned N) const {
1259 assert(N == 1 && "Invalid number of operands!");
1260 const MCExpr *Expr = getImm();
1261 addExpr(Inst, Expr);
1262 }
1263
1264 void addMemOperands(MCInst &Inst, unsigned N) const {
1265 assert(N == 2 && "Invalid number of operands!");
1266
1267 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1268 ? getMemBase()->getGPR64Reg()
1269 : getMemBase()->getGPR32Reg()));
1270
1271 const MCExpr *Expr = getMemOff();
1272 addExpr(Inst, Expr);
1273 }
1274
1275 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1276 assert(N == 2 && "Invalid number of operands!");
1277
1278 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1279
1280 const MCExpr *Expr = getMemOff();
1281 addExpr(Inst, Expr);
1282 }
1283
1284 void addRegListOperands(MCInst &Inst, unsigned N) const {
1285 assert(N == 1 && "Invalid number of operands!");
1286
1287 for (auto RegNo : getRegList())
1288 Inst.addOperand(MCOperand::createReg(RegNo));
1289 }
1290
1291 bool isReg() const override {
1292 // As a special case until we sort out the definition of div/divu, accept
1293 // $0/$zero here so that MCK_ZERO works correctly.
1294 return isGPRAsmReg() && RegIdx.Index == 0;
1295 }
1296
1297 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1298 bool isImm() const override { return Kind == k_Immediate; }
1299
1300 bool isConstantImm() const {
1301 int64_t Res;
1302 return isImm() && getImm()->evaluateAsAbsolute(Res);
1303 }
1304
1305 bool isConstantImmz() const {
1306 return isConstantImm() && getConstantImm() == 0;
1307 }
1308
1309 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1310 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1311 }
1312
1313 template <unsigned Bits> bool isSImm() const {
1314 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1315 }
1316
1317 template <unsigned Bits> bool isUImm() const {
1318 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1319 }
1320
1321 template <unsigned Bits> bool isAnyImm() const {
1322 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1323 isUInt<Bits>(getConstantImm()))
1324 : isImm();
1325 }
1326
1327 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1328 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1329 }
1330
1331 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1332 return isConstantImm() && getConstantImm() >= Bottom &&
1333 getConstantImm() <= Top;
1334 }
1335
1336 bool isToken() const override {
1337 // Note: It's not possible to pretend that other operand kinds are tokens.
1338 // The matcher emitter checks tokens first.
1339 return Kind == k_Token;
1340 }
1341
1342 bool isMem() const override { return Kind == k_Memory; }
1343
1344 bool isConstantMemOff() const {
1345 return isMem() && isa<MCConstantExpr>(getMemOff());
1346 }
1347
1348 // Allow relocation operators.
1349 template <unsigned Bits, unsigned ShiftAmount = 0>
1350 bool isMemWithSimmOffset() const {
1351 if (!isMem())
1352 return false;
1353 if (!getMemBase()->isGPRAsmReg())
1354 return false;
1355 if (isa<MCTargetExpr>(getMemOff()) ||
1356 (isConstantMemOff() &&
1357 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1358 return true;
1359 MCValue Res;
1360 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1361 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1362 }
1363
1364 bool isMemWithPtrSizeOffset() const {
1365 if (!isMem())
1366 return false;
1367 if (!getMemBase()->isGPRAsmReg())
1368 return false;
1369 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1370 if (isa<MCTargetExpr>(getMemOff()) ||
1371 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1372 return true;
1373 MCValue Res;
1374 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1375 return IsReloc && isIntN(PtrBits, Res.getConstant());
1376 }
1377
1378 bool isMemWithGRPMM16Base() const {
1379 return isMem() && getMemBase()->isMM16AsmReg();
1380 }
1381
1382 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1383 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1384 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1385 }
1386
1387 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1388 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1389 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1390 && (getMemBase()->getGPR32Reg() == Mips::SP);
1391 }
1392
1393 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1394 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1395 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1396 && (getMemBase()->getGPR32Reg() == Mips::GP);
1397 }
1398
1399 template <unsigned Bits, unsigned ShiftLeftAmount>
1400 bool isScaledUImm() const {
1401 return isConstantImm() &&
1402 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1403 }
1404
1405 template <unsigned Bits, unsigned ShiftLeftAmount>
1406 bool isScaledSImm() const {
1407 if (isConstantImm() &&
1408 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1409 return true;
1410 // Operand can also be a symbol or symbol plus
1411 // offset in case of relocations.
1412 if (Kind != k_Immediate)
1413 return false;
1414 MCValue Res;
1415 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1416 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1417 }
1418
1419 bool isRegList16() const {
1420 if (!isRegList())
1421 return false;
1422
1423 int Size = RegList.List->size();
1424 if (Size < 2 || Size > 5)
1425 return false;
1426
1427 unsigned R0 = RegList.List->front();
1428 unsigned R1 = RegList.List->back();
1429 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1430 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1431 return false;
1432
1433 int PrevReg = *RegList.List->begin();
1434 for (int i = 1; i < Size - 1; i++) {
1435 int Reg = (*(RegList.List))[i];
1436 if ( Reg != PrevReg + 1)
1437 return false;
1438 PrevReg = Reg;
1439 }
1440
1441 return true;
1442 }
1443
1444 bool isInvNum() const { return Kind == k_Immediate; }
1445
1446 bool isLSAImm() const {
1447 if (!isConstantImm())
1448 return false;
1449 int64_t Val = getConstantImm();
1450 return 1 <= Val && Val <= 4;
1451 }
1452
1453 bool isRegList() const { return Kind == k_RegList; }
1454
1455 StringRef getToken() const {
1456 assert(Kind == k_Token && "Invalid access!");
1457 return StringRef(Tok.Data, Tok.Length);
1458 }
1459
1460 MCRegister getReg() const override {
1461 // As a special case until we sort out the definition of div/divu, accept
1462 // $0/$zero here so that MCK_ZERO works correctly.
1463 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1464 RegIdx.Kind & RegKind_GPR)
1465 return getGPR32Reg(); // FIXME: GPR64 too
1466
1467 llvm_unreachable("Invalid access!");
1468 return 0;
1469 }
1470
1471 const MCExpr *getImm() const {
1472 assert((Kind == k_Immediate) && "Invalid access!");
1473 return Imm.Val;
1474 }
1475
1476 int64_t getConstantImm() const {
1477 const MCExpr *Val = getImm();
1478 int64_t Value = 0;
1479 (void)Val->evaluateAsAbsolute(Value);
1480 return Value;
1481 }
1482
1483 MipsOperand *getMemBase() const {
1484 assert((Kind == k_Memory) && "Invalid access!");
1485 return Mem.Base;
1486 }
1487
1488 const MCExpr *getMemOff() const {
1489 assert((Kind == k_Memory) && "Invalid access!");
1490 return Mem.Off;
1491 }
1492
1493 int64_t getConstantMemOff() const {
1494 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1495 }
1496
1497 const SmallVectorImpl<unsigned> &getRegList() const {
1498 assert((Kind == k_RegList) && "Invalid access!");
1499 return *(RegList.List);
1500 }
1501
1502 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1503 MipsAsmParser &Parser) {
1504 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1505 Op->Tok.Data = Str.data();
1506 Op->Tok.Length = Str.size();
1507 Op->StartLoc = S;
1508 Op->EndLoc = S;
1509 return Op;
1510 }
1511
1512 /// Create a numeric register (e.g. $1). The exact register remains
1513 /// unresolved until an instruction successfully matches
1514 static std::unique_ptr<MipsOperand>
1515 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1516 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1517 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1518 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1519 }
1520
1521 /// Create a register that is definitely a GPR.
1522 /// This is typically only used for named registers such as $gp.
1523 static std::unique_ptr<MipsOperand>
1524 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1525 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1526 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1527 }
1528
1529 /// Create a register that is definitely a FGR.
1530 /// This is typically only used for named registers such as $f0.
1531 static std::unique_ptr<MipsOperand>
1532 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1533 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1534 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1535 }
1536
1537 /// Create a register that is definitely a HWReg.
1538 /// This is typically only used for named registers such as $hwr_cpunum.
1539 static std::unique_ptr<MipsOperand>
1540 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1541 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1542 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1543 }
1544
1545 /// Create a register that is definitely an FCC.
1546 /// This is typically only used for named registers such as $fcc0.
1547 static std::unique_ptr<MipsOperand>
1548 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1549 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1550 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1551 }
1552
1553 /// Create a register that is definitely an ACC.
1554 /// This is typically only used for named registers such as $ac0.
1555 static std::unique_ptr<MipsOperand>
1556 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1557 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1558 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1559 }
1560
1561 /// Create a register that is definitely an MSA128.
1562 /// This is typically only used for named registers such as $w0.
1563 static std::unique_ptr<MipsOperand>
1564 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1565 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1566 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1567 }
1568
1569 /// Create a register that is definitely an MSACtrl.
1570 /// This is typically only used for named registers such as $msaaccess.
1571 static std::unique_ptr<MipsOperand>
1572 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1573 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1574 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1575 }
1576
1577 static std::unique_ptr<MipsOperand>
1578 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1579 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1580 Op->Imm.Val = Val;
1581 Op->StartLoc = S;
1582 Op->EndLoc = E;
1583 return Op;
1584 }
1585
1586 static std::unique_ptr<MipsOperand>
1587 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1588 SMLoc E, MipsAsmParser &Parser) {
1589 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1590 Op->Mem.Base = Base.release();
1591 Op->Mem.Off = Off;
1592 Op->StartLoc = S;
1593 Op->EndLoc = E;
1594 return Op;
1595 }
1596
1597 static std::unique_ptr<MipsOperand>
1598 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1599 MipsAsmParser &Parser) {
1600 assert(Regs.size() > 0 && "Empty list not allowed");
1601
1602 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1603 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1604 Op->StartLoc = StartLoc;
1605 Op->EndLoc = EndLoc;
1606 return Op;
1607 }
1608
1609 bool isGPRZeroAsmReg() const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1611 }
1612
1613 bool isGPRNonZeroAsmReg() const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1615 RegIdx.Index <= 31;
1616 }
1617
1618 bool isGPRAsmReg() const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1620 }
1621
1622 bool isMM16AsmReg() const {
1623 if (!(isRegIdx() && RegIdx.Kind))
1624 return false;
1625 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1626 || RegIdx.Index == 16 || RegIdx.Index == 17);
1627
1628 }
1629 bool isMM16AsmRegZero() const {
1630 if (!(isRegIdx() && RegIdx.Kind))
1631 return false;
1632 return (RegIdx.Index == 0 ||
1633 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1634 RegIdx.Index == 17);
1635 }
1636
1637 bool isMM16AsmRegMoveP() const {
1638 if (!(isRegIdx() && RegIdx.Kind))
1639 return false;
1640 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1641 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1642 }
1643
1644 bool isMM16AsmRegMovePPairFirst() const {
1645 if (!(isRegIdx() && RegIdx.Kind))
1646 return false;
1647 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1648 }
1649
1650 bool isMM16AsmRegMovePPairSecond() const {
1651 if (!(isRegIdx() && RegIdx.Kind))
1652 return false;
1653 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1654 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1655 }
1656
1657 bool isFGRAsmReg() const {
1658 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1659 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1660 }
1661
1662 bool isStrictlyFGRAsmReg() const {
1663 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1664 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1665 }
1666
1667 bool isHWRegsAsmReg() const {
1668 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1669 }
1670
1671 bool isCCRAsmReg() const {
1672 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1673 }
1674
1675 bool isFCCAsmReg() const {
1676 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1677 return false;
1678 return RegIdx.Index <= 7;
1679 }
1680
1681 bool isACCAsmReg() const {
1682 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1683 }
1684
1685 bool isCOP0AsmReg() const {
1686 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1687 }
1688
1689 bool isCOP2AsmReg() const {
1690 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1691 }
1692
1693 bool isCOP3AsmReg() const {
1694 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1695 }
1696
1697 bool isMSA128AsmReg() const {
1698 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1699 }
1700
1701 bool isMSACtrlAsmReg() const {
1702 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1703 }
1704
1705 /// getStartLoc - Get the location of the first token of this operand.
1706 SMLoc getStartLoc() const override { return StartLoc; }
1707 /// getEndLoc - Get the location of the last token of this operand.
1708 SMLoc getEndLoc() const override { return EndLoc; }
1709
1710 void print(raw_ostream &OS) const override {
1711 switch (Kind) {
1712 case k_Immediate:
1713 OS << "Imm<";
1714 OS << *Imm.Val;
1715 OS << ">";
1716 break;
1717 case k_Memory:
1718 OS << "Mem<";
1719 Mem.Base->print(OS);
1720 OS << ", ";
1721 OS << *Mem.Off;
1722 OS << ">";
1723 break;
1724 case k_RegisterIndex:
1725 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1726 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1727 break;
1728 case k_Token:
1729 OS << getToken();
1730 break;
1731 case k_RegList:
1732 OS << "RegList< ";
1733 for (auto Reg : (*RegList.List))
1734 OS << Reg << " ";
1735 OS << ">";
1736 break;
1737 }
1738 }
1739
1740 bool isValidForTie(const MipsOperand &Other) const {
1741 if (Kind != Other.Kind)
1742 return false;
1743
1744 switch (Kind) {
1745 default:
1746 llvm_unreachable("Unexpected kind");
1747 return false;
1748 case k_RegisterIndex: {
1749 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1750 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1751 return Token == OtherToken;
1752 }
1753 }
1754 }
1755}; // class MipsOperand
1756
1757} // end anonymous namespace
1758
1759static bool hasShortDelaySlot(MCInst &Inst) {
1760 switch (Inst.getOpcode()) {
1761 case Mips::BEQ_MM:
1762 case Mips::BNE_MM:
1763 case Mips::BLTZ_MM:
1764 case Mips::BGEZ_MM:
1765 case Mips::BLEZ_MM:
1766 case Mips::BGTZ_MM:
1767 case Mips::JRC16_MM:
1768 case Mips::JALS_MM:
1769 case Mips::JALRS_MM:
1770 case Mips::JALRS16_MM:
1771 case Mips::BGEZALS_MM:
1772 case Mips::BLTZALS_MM:
1773 return true;
1774 case Mips::J_MM:
1775 return !Inst.getOperand(0).isReg();
1776 default:
1777 return false;
1778 }
1779}
1780
1781static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1782 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1783 return &SRExpr->getSymbol();
1784 }
1785
1786 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1787 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1788 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1789
1790 if (LHSSym)
1791 return LHSSym;
1792
1793 if (RHSSym)
1794 return RHSSym;
1795
1796 return nullptr;
1797 }
1798
1799 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1800 return getSingleMCSymbol(UExpr->getSubExpr());
1801
1802 return nullptr;
1803}
1804
1805static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1806 if (isa<MCSymbolRefExpr>(Expr))
1807 return 1;
1808
1809 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1810 return countMCSymbolRefExpr(BExpr->getLHS()) +
1811 countMCSymbolRefExpr(BExpr->getRHS());
1812
1813 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1814 return countMCSymbolRefExpr(UExpr->getSubExpr());
1815
1816 return 0;
1817}
1818
1819static bool isEvaluated(const MCExpr *Expr) {
1820 switch (Expr->getKind()) {
1821 case MCExpr::Constant:
1822 return true;
1823 case MCExpr::SymbolRef:
1824 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1825 case MCExpr::Binary: {
1826 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1827 if (!isEvaluated(BE->getLHS()))
1828 return false;
1829 return isEvaluated(BE->getRHS());
1830 }
1831 case MCExpr::Unary:
1832 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1833 case MCExpr::Target:
1834 return true;
1835 }
1836 return false;
1837}
1838
1839static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID) {
1840 unsigned NumOp = MCID.getNumOperands();
1841 if (NumOp != 3 && NumOp != 4)
1842 return false;
1843
1844 const MCOperandInfo &OpInfo = MCID.operands()[NumOp - 1];
1845 if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
1848 return false;
1849
1850 MCOperand &Op = Inst.getOperand(NumOp - 1);
1851 if (Op.isImm()) {
1853 return !isInt<9>(Op.getImm());
1854 // Offset can't exceed 16bit value.
1855 return !isInt<16>(Op.getImm());
1856 }
1857
1858 if (Op.isExpr()) {
1859 const MCExpr *Expr = Op.getExpr();
1860 if (Expr->getKind() != MCExpr::SymbolRef)
1861 return !isEvaluated(Expr);
1862
1863 // Expand symbol.
1864 const MCSymbolRefExpr *SR = static_cast<const MCSymbolRefExpr *>(Expr);
1865 return SR->getKind() == MCSymbolRefExpr::VK_None;
1866 }
1867
1868 return false;
1869}
1870
1871bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1872 MCStreamer &Out,
1873 const MCSubtargetInfo *STI) {
1874 MipsTargetStreamer &TOut = getTargetStreamer();
1875 const unsigned Opcode = Inst.getOpcode();
1876 const MCInstrDesc &MCID = MII.get(Opcode);
1877 bool ExpandedJalSym = false;
1878
1879 Inst.setLoc(IDLoc);
1880
1881 if (MCID.isBranch() || MCID.isCall()) {
1883
1884 switch (Opcode) {
1885 default:
1886 break;
1887 case Mips::BBIT0:
1888 case Mips::BBIT032:
1889 case Mips::BBIT1:
1890 case Mips::BBIT132:
1891 assert(hasCnMips() && "instruction only valid for octeon cpus");
1892 [[fallthrough]];
1893
1894 case Mips::BEQ:
1895 case Mips::BNE:
1896 case Mips::BEQ_MM:
1897 case Mips::BNE_MM:
1898 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1899 Offset = Inst.getOperand(2);
1900 if (!Offset.isImm())
1901 break; // We'll deal with this situation later on when applying fixups.
1902 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1903 return Error(IDLoc, "branch target out of range");
1904 if (offsetToAlignment(Offset.getImm(),
1905 (inMicroMipsMode() ? Align(2) : Align(4))))
1906 return Error(IDLoc, "branch to misaligned address");
1907 break;
1908 case Mips::BGEZ:
1909 case Mips::BGTZ:
1910 case Mips::BLEZ:
1911 case Mips::BLTZ:
1912 case Mips::BGEZAL:
1913 case Mips::BLTZAL:
1914 case Mips::BC1F:
1915 case Mips::BC1T:
1916 case Mips::BGEZ_MM:
1917 case Mips::BGTZ_MM:
1918 case Mips::BLEZ_MM:
1919 case Mips::BLTZ_MM:
1920 case Mips::BGEZAL_MM:
1921 case Mips::BLTZAL_MM:
1922 case Mips::BC1F_MM:
1923 case Mips::BC1T_MM:
1924 case Mips::BC1EQZC_MMR6:
1925 case Mips::BC1NEZC_MMR6:
1926 case Mips::BC2EQZC_MMR6:
1927 case Mips::BC2NEZC_MMR6:
1928 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1929 Offset = Inst.getOperand(1);
1930 if (!Offset.isImm())
1931 break; // We'll deal with this situation later on when applying fixups.
1932 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1933 return Error(IDLoc, "branch target out of range");
1934 if (offsetToAlignment(Offset.getImm(),
1935 (inMicroMipsMode() ? Align(2) : Align(4))))
1936 return Error(IDLoc, "branch to misaligned address");
1937 break;
1938 case Mips::BGEC: case Mips::BGEC_MMR6:
1939 case Mips::BLTC: case Mips::BLTC_MMR6:
1940 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1941 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1942 case Mips::BEQC: case Mips::BEQC_MMR6:
1943 case Mips::BNEC: case Mips::BNEC_MMR6:
1944 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1945 Offset = Inst.getOperand(2);
1946 if (!Offset.isImm())
1947 break; // We'll deal with this situation later on when applying fixups.
1948 if (!isIntN(18, Offset.getImm()))
1949 return Error(IDLoc, "branch target out of range");
1950 if (offsetToAlignment(Offset.getImm(), Align(4)))
1951 return Error(IDLoc, "branch to misaligned address");
1952 break;
1953 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1954 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1955 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1956 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1957 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1958 Offset = Inst.getOperand(1);
1959 if (!Offset.isImm())
1960 break; // We'll deal with this situation later on when applying fixups.
1961 if (!isIntN(18, Offset.getImm()))
1962 return Error(IDLoc, "branch target out of range");
1963 if (offsetToAlignment(Offset.getImm(), Align(4)))
1964 return Error(IDLoc, "branch to misaligned address");
1965 break;
1966 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1967 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1968 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1969 Offset = Inst.getOperand(1);
1970 if (!Offset.isImm())
1971 break; // We'll deal with this situation later on when applying fixups.
1972 if (!isIntN(23, Offset.getImm()))
1973 return Error(IDLoc, "branch target out of range");
1974 if (offsetToAlignment(Offset.getImm(), Align(4)))
1975 return Error(IDLoc, "branch to misaligned address");
1976 break;
1977 case Mips::BEQZ16_MM:
1978 case Mips::BEQZC16_MMR6:
1979 case Mips::BNEZ16_MM:
1980 case Mips::BNEZC16_MMR6:
1981 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1982 Offset = Inst.getOperand(1);
1983 if (!Offset.isImm())
1984 break; // We'll deal with this situation later on when applying fixups.
1985 if (!isInt<8>(Offset.getImm()))
1986 return Error(IDLoc, "branch target out of range");
1987 if (offsetToAlignment(Offset.getImm(), Align(2)))
1988 return Error(IDLoc, "branch to misaligned address");
1989 break;
1990 }
1991 }
1992
1993 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1994 // We still accept it but it is a normal nop.
1995 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1996 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1997 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1998 "nop instruction");
1999 }
2000
2001 if (hasCnMips()) {
2002 MCOperand Opnd;
2003 int Imm;
2004
2005 switch (Opcode) {
2006 default:
2007 break;
2008
2009 case Mips::BBIT0:
2010 case Mips::BBIT032:
2011 case Mips::BBIT1:
2012 case Mips::BBIT132:
2013 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2014 // The offset is handled above
2015 Opnd = Inst.getOperand(1);
2016 if (!Opnd.isImm())
2017 return Error(IDLoc, "expected immediate operand kind");
2018 Imm = Opnd.getImm();
2019 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2020 Opcode == Mips::BBIT1 ? 63 : 31))
2021 return Error(IDLoc, "immediate operand value out of range");
2022 if (Imm > 31) {
2023 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2024 : Mips::BBIT132);
2025 Inst.getOperand(1).setImm(Imm - 32);
2026 }
2027 break;
2028
2029 case Mips::SEQi:
2030 case Mips::SNEi:
2031 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2032 Opnd = Inst.getOperand(2);
2033 if (!Opnd.isImm())
2034 return Error(IDLoc, "expected immediate operand kind");
2035 Imm = Opnd.getImm();
2036 if (!isInt<10>(Imm))
2037 return Error(IDLoc, "immediate operand value out of range");
2038 break;
2039 }
2040 }
2041
2042 // Warn on division by zero. We're checking here as all instructions get
2043 // processed here, not just the macros that need expansion.
2044 //
2045 // The MIPS backend models most of the divison instructions and macros as
2046 // three operand instructions. The pre-R6 divide instructions however have
2047 // two operands and explicitly define HI/LO as part of the instruction,
2048 // not in the operands.
2049 unsigned FirstOp = 1;
2050 unsigned SecondOp = 2;
2051 switch (Opcode) {
2052 default:
2053 break;
2054 case Mips::SDivIMacro:
2055 case Mips::UDivIMacro:
2056 case Mips::DSDivIMacro:
2057 case Mips::DUDivIMacro:
2058 if (Inst.getOperand(2).getImm() == 0) {
2059 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
2060 Inst.getOperand(1).getReg() == Mips::ZERO_64)
2061 Warning(IDLoc, "dividing zero by zero");
2062 else
2063 Warning(IDLoc, "division by zero");
2064 }
2065 break;
2066 case Mips::DSDIV:
2067 case Mips::SDIV:
2068 case Mips::UDIV:
2069 case Mips::DUDIV:
2070 case Mips::UDIV_MM:
2071 case Mips::SDIV_MM:
2072 FirstOp = 0;
2073 SecondOp = 1;
2074 [[fallthrough]];
2075 case Mips::SDivMacro:
2076 case Mips::DSDivMacro:
2077 case Mips::UDivMacro:
2078 case Mips::DUDivMacro:
2079 case Mips::DIV:
2080 case Mips::DIVU:
2081 case Mips::DDIV:
2082 case Mips::DDIVU:
2083 case Mips::DIVU_MMR6:
2084 case Mips::DIV_MMR6:
2085 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2086 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2087 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2088 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2089 Warning(IDLoc, "dividing zero by zero");
2090 else
2091 Warning(IDLoc, "division by zero");
2092 }
2093 break;
2094 }
2095
2096 // For PIC code convert unconditional jump to unconditional branch.
2097 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2098 MCInst BInst;
2099 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2100 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2101 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2102 BInst.addOperand(Inst.getOperand(0));
2103 Inst = BInst;
2104 }
2105
2106 // This expansion is not in a function called by tryExpandInstruction()
2107 // because the pseudo-instruction doesn't have a distinct opcode.
2108 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2109 warnIfNoMacro(IDLoc);
2110
2111 if (!Inst.getOperand(0).isExpr()) {
2112 return Error(IDLoc, "unsupported constant in relocation");
2113 }
2114
2115 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2116
2117 // We can do this expansion if there's only 1 symbol in the argument
2118 // expression.
2119 if (countMCSymbolRefExpr(JalExpr) > 1)
2120 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2121
2122 // FIXME: This is checking the expression can be handled by the later stages
2123 // of the assembler. We ought to leave it to those later stages.
2124 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2125
2126 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.getOperand(0),
2127 !isGP64bit(), IDLoc, Out, STI))
2128 return true;
2129
2130 MCInst JalrInst;
2131 if (inMicroMipsMode())
2132 JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2133 else
2134 JalrInst.setOpcode(Mips::JALR);
2135 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2136 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2137
2138 if (isJalrRelocAvailable(JalExpr)) {
2139 // As an optimization hint for the linker, before the JALR we add:
2140 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2141 // tmplabel:
2142 MCSymbol *TmpLabel = getContext().createTempSymbol();
2143 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2144 const MCExpr *RelocJalrExpr =
2146 getContext(), IDLoc);
2147
2149 *TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2150 RelocJalrExpr, IDLoc, *STI);
2151 TOut.getStreamer().emitLabel(TmpLabel);
2152 }
2153
2154 Inst = JalrInst;
2155 ExpandedJalSym = true;
2156 }
2157
2158 if (MCID.mayLoad() || MCID.mayStore()) {
2159 // Check the offset of memory operand, if it is a symbol
2160 // reference or immediate we may have to expand instructions.
2161 if (needsExpandMemInst(Inst, MCID)) {
2162 switch (MCID.operands()[MCID.getNumOperands() - 1].OperandType) {
2164 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2165 break;
2166 default:
2167 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2168 break;
2169 }
2170 return getParser().hasPendingError();
2171 }
2172 }
2173
2174 if (inMicroMipsMode()) {
2175 if (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
2176 // Try to create 16-bit GP relative load instruction.
2177 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2178 const MCOperandInfo &OpInfo = MCID.operands()[i];
2179 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2180 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2181 MCOperand &Op = Inst.getOperand(i);
2182 if (Op.isImm()) {
2183 int MemOffset = Op.getImm();
2184 MCOperand &DstReg = Inst.getOperand(0);
2185 MCOperand &BaseReg = Inst.getOperand(1);
2186 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2187 getContext().getRegisterInfo()->getRegClass(
2188 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2189 (BaseReg.getReg() == Mips::GP ||
2190 BaseReg.getReg() == Mips::GP_64)) {
2191
2192 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2193 IDLoc, STI);
2194 return false;
2195 }
2196 }
2197 }
2198 } // for
2199 } // if load
2200
2201 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2202
2203 MCOperand Opnd;
2204 int Imm;
2205
2206 switch (Opcode) {
2207 default:
2208 break;
2209 case Mips::ADDIUSP_MM:
2210 Opnd = Inst.getOperand(0);
2211 if (!Opnd.isImm())
2212 return Error(IDLoc, "expected immediate operand kind");
2213 Imm = Opnd.getImm();
2214 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2215 Imm % 4 != 0)
2216 return Error(IDLoc, "immediate operand value out of range");
2217 break;
2218 case Mips::SLL16_MM:
2219 case Mips::SRL16_MM:
2220 Opnd = Inst.getOperand(2);
2221 if (!Opnd.isImm())
2222 return Error(IDLoc, "expected immediate operand kind");
2223 Imm = Opnd.getImm();
2224 if (Imm < 1 || Imm > 8)
2225 return Error(IDLoc, "immediate operand value out of range");
2226 break;
2227 case Mips::LI16_MM:
2228 Opnd = Inst.getOperand(1);
2229 if (!Opnd.isImm())
2230 return Error(IDLoc, "expected immediate operand kind");
2231 Imm = Opnd.getImm();
2232 if (Imm < -1 || Imm > 126)
2233 return Error(IDLoc, "immediate operand value out of range");
2234 break;
2235 case Mips::ADDIUR2_MM:
2236 Opnd = Inst.getOperand(2);
2237 if (!Opnd.isImm())
2238 return Error(IDLoc, "expected immediate operand kind");
2239 Imm = Opnd.getImm();
2240 if (!(Imm == 1 || Imm == -1 ||
2241 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2242 return Error(IDLoc, "immediate operand value out of range");
2243 break;
2244 case Mips::ANDI16_MM:
2245 Opnd = Inst.getOperand(2);
2246 if (!Opnd.isImm())
2247 return Error(IDLoc, "expected immediate operand kind");
2248 Imm = Opnd.getImm();
2249 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2250 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2251 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2252 return Error(IDLoc, "immediate operand value out of range");
2253 break;
2254 case Mips::LBU16_MM:
2255 Opnd = Inst.getOperand(2);
2256 if (!Opnd.isImm())
2257 return Error(IDLoc, "expected immediate operand kind");
2258 Imm = Opnd.getImm();
2259 if (Imm < -1 || Imm > 14)
2260 return Error(IDLoc, "immediate operand value out of range");
2261 break;
2262 case Mips::SB16_MM:
2263 case Mips::SB16_MMR6:
2264 Opnd = Inst.getOperand(2);
2265 if (!Opnd.isImm())
2266 return Error(IDLoc, "expected immediate operand kind");
2267 Imm = Opnd.getImm();
2268 if (Imm < 0 || Imm > 15)
2269 return Error(IDLoc, "immediate operand value out of range");
2270 break;
2271 case Mips::LHU16_MM:
2272 case Mips::SH16_MM:
2273 case Mips::SH16_MMR6:
2274 Opnd = Inst.getOperand(2);
2275 if (!Opnd.isImm())
2276 return Error(IDLoc, "expected immediate operand kind");
2277 Imm = Opnd.getImm();
2278 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2279 return Error(IDLoc, "immediate operand value out of range");
2280 break;
2281 case Mips::LW16_MM:
2282 case Mips::SW16_MM:
2283 case Mips::SW16_MMR6:
2284 Opnd = Inst.getOperand(2);
2285 if (!Opnd.isImm())
2286 return Error(IDLoc, "expected immediate operand kind");
2287 Imm = Opnd.getImm();
2288 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2289 return Error(IDLoc, "immediate operand value out of range");
2290 break;
2291 case Mips::ADDIUPC_MM:
2292 Opnd = Inst.getOperand(1);
2293 if (!Opnd.isImm())
2294 return Error(IDLoc, "expected immediate operand kind");
2295 Imm = Opnd.getImm();
2296 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2297 return Error(IDLoc, "immediate operand value out of range");
2298 break;
2299 case Mips::LWP_MM:
2300 case Mips::SWP_MM:
2301 if (Inst.getOperand(0).getReg() == Mips::RA)
2302 return Error(IDLoc, "invalid operand for instruction");
2303 break;
2304 case Mips::MOVEP_MM:
2305 case Mips::MOVEP_MMR6: {
2306 unsigned R0 = Inst.getOperand(0).getReg();
2307 unsigned R1 = Inst.getOperand(1).getReg();
2308 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2309 (R0 == Mips::A1 && R1 == Mips::A3) ||
2310 (R0 == Mips::A2 && R1 == Mips::A3) ||
2311 (R0 == Mips::A0 && R1 == Mips::S5) ||
2312 (R0 == Mips::A0 && R1 == Mips::S6) ||
2313 (R0 == Mips::A0 && R1 == Mips::A1) ||
2314 (R0 == Mips::A0 && R1 == Mips::A2) ||
2315 (R0 == Mips::A0 && R1 == Mips::A3));
2316 if (!RegPair)
2317 return Error(IDLoc, "invalid operand for instruction");
2318 break;
2319 }
2320 }
2321 }
2322
2323 bool FillDelaySlot =
2324 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2325
2326 // Get previous instruction`s forbidden slot attribute and
2327 // whether set reorder.
2328 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2329
2330 // Flag represents we set reorder after nop.
2331 bool SetReorderAfterNop = false;
2332
2333 // If previous instruction has forbidden slot and .set reorder
2334 // is active and current instruction is CTI.
2335 // Then emit a NOP after it.
2336 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2337 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2338 // When 'FillDelaySlot' is true, the existing logic will add
2339 // noreorder before instruction and reorder after it. So there
2340 // need exclude this case avoiding two '.set reorder'.
2341 // The format of the first case is:
2342 // .set noreorder
2343 // bnezc
2344 // nop
2345 // .set reorder
2346 if (AssemblerOptions.back()->isReorder() && !FillDelaySlot) {
2347 SetReorderAfterNop = true;
2349 }
2350 }
2351
2352 // Save current instruction`s forbidden slot and whether set reorder.
2353 // This is the judgment condition for whether to add nop.
2354 // We would add a couple of '.set noreorder' and '.set reorder' to
2355 // wrap the current instruction and the next instruction.
2356 CurForbiddenSlotAttr =
2357 hasForbiddenSlot(MCID) && AssemblerOptions.back()->isReorder();
2358
2359 if (FillDelaySlot || CurForbiddenSlotAttr)
2361
2362 MacroExpanderResultTy ExpandResult =
2363 tryExpandInstruction(Inst, IDLoc, Out, STI);
2364 switch (ExpandResult) {
2365 case MER_NotAMacro:
2366 Out.emitInstruction(Inst, *STI);
2367 break;
2368 case MER_Success:
2369 break;
2370 case MER_Fail:
2371 return true;
2372 }
2373
2374 // When current instruction was not CTI, recover reorder state.
2375 // The format of the second case is:
2376 // .set noreoder
2377 // bnezc
2378 // add
2379 // .set reorder
2380 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2381 AssemblerOptions.back()->isReorder()) {
2383 }
2384
2385 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2386 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2387 if (inMicroMipsMode()) {
2388 TOut.setUsesMicroMips();
2389 TOut.updateABIInfo(*this);
2390 }
2391
2392 // If this instruction has a delay slot and .set reorder is active,
2393 // emit a NOP after it.
2394 // The format of the third case is:
2395 // .set noreorder
2396 // bnezc
2397 // nop
2398 // .set noreorder
2399 // j
2400 // nop
2401 // .set reorder
2402 if (FillDelaySlot) {
2403 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2405 }
2406
2407 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2408 ExpandedJalSym) &&
2409 isPicAndNotNxxAbi()) {
2410 if (IsCpRestoreSet) {
2411 // We need a NOP between the JALR and the LW:
2412 // If .set reorder has been used, we've already emitted a NOP.
2413 // If .set noreorder has been used, we need to emit a NOP at this point.
2414 if (!AssemblerOptions.back()->isReorder())
2415 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2416 STI);
2417
2418 // Load the $gp from the stack.
2419 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2420 } else
2421 Warning(IDLoc, "no .cprestore used in PIC mode");
2422 }
2423
2424 return false;
2425}
2426
2427void MipsAsmParser::onEndOfFile() {
2428 MipsTargetStreamer &TOut = getTargetStreamer();
2429 SMLoc IDLoc = SMLoc();
2430 // If has pending forbidden slot, fill nop and recover reorder.
2431 if (CurForbiddenSlotAttr) {
2432 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2433 if (AssemblerOptions.back()->isReorder())
2435 }
2436}
2437
2438MipsAsmParser::MacroExpanderResultTy
2439MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2440 const MCSubtargetInfo *STI) {
2441 switch (Inst.getOpcode()) {
2442 default:
2443 return MER_NotAMacro;
2444 case Mips::LoadImm32:
2445 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2446 case Mips::LoadImm64:
2447 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::LoadAddrImm32:
2449 case Mips::LoadAddrImm64:
2450 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2451 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2452 "expected immediate operand kind");
2453
2454 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2455 Inst.getOperand(1),
2456 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2457 Out, STI)
2458 ? MER_Fail
2459 : MER_Success;
2460 case Mips::LoadAddrReg32:
2461 case Mips::LoadAddrReg64:
2462 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2463 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2464 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2465 "expected immediate operand kind");
2466
2467 return expandLoadAddress(Inst.getOperand(0).getReg(),
2468 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2469 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2470 Out, STI)
2471 ? MER_Fail
2472 : MER_Success;
2473 case Mips::B_MM_Pseudo:
2474 case Mips::B_MMR6_Pseudo:
2475 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2476 : MER_Success;
2477 case Mips::SWM_MM:
2478 case Mips::LWM_MM:
2479 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2480 : MER_Success;
2481 case Mips::JalOneReg:
2482 case Mips::JalTwoReg:
2483 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 case Mips::BneImm:
2485 case Mips::BeqImm:
2486 case Mips::BEQLImmMacro:
2487 case Mips::BNELImmMacro:
2488 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2489 case Mips::BLT:
2490 case Mips::BLE:
2491 case Mips::BGE:
2492 case Mips::BGT:
2493 case Mips::BLTU:
2494 case Mips::BLEU:
2495 case Mips::BGEU:
2496 case Mips::BGTU:
2497 case Mips::BLTL:
2498 case Mips::BLEL:
2499 case Mips::BGEL:
2500 case Mips::BGTL:
2501 case Mips::BLTUL:
2502 case Mips::BLEUL:
2503 case Mips::BGEUL:
2504 case Mips::BGTUL:
2505 case Mips::BLTImmMacro:
2506 case Mips::BLEImmMacro:
2507 case Mips::BGEImmMacro:
2508 case Mips::BGTImmMacro:
2509 case Mips::BLTUImmMacro:
2510 case Mips::BLEUImmMacro:
2511 case Mips::BGEUImmMacro:
2512 case Mips::BGTUImmMacro:
2513 case Mips::BLTLImmMacro:
2514 case Mips::BLELImmMacro:
2515 case Mips::BGELImmMacro:
2516 case Mips::BGTLImmMacro:
2517 case Mips::BLTULImmMacro:
2518 case Mips::BLEULImmMacro:
2519 case Mips::BGEULImmMacro:
2520 case Mips::BGTULImmMacro:
2521 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2522 case Mips::SDivMacro:
2523 case Mips::SDivIMacro:
2524 case Mips::SRemMacro:
2525 case Mips::SRemIMacro:
2526 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2527 : MER_Success;
2528 case Mips::DSDivMacro:
2529 case Mips::DSDivIMacro:
2530 case Mips::DSRemMacro:
2531 case Mips::DSRemIMacro:
2532 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2533 : MER_Success;
2534 case Mips::UDivMacro:
2535 case Mips::UDivIMacro:
2536 case Mips::URemMacro:
2537 case Mips::URemIMacro:
2538 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2539 : MER_Success;
2540 case Mips::DUDivMacro:
2541 case Mips::DUDivIMacro:
2542 case Mips::DURemMacro:
2543 case Mips::DURemIMacro:
2544 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2545 : MER_Success;
2546 case Mips::PseudoTRUNC_W_S:
2547 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2548 : MER_Success;
2549 case Mips::PseudoTRUNC_W_D32:
2550 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2551 : MER_Success;
2552 case Mips::PseudoTRUNC_W_D:
2553 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2554 : MER_Success;
2555
2556 case Mips::LoadImmSingleGPR:
2557 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2558 : MER_Success;
2559 case Mips::LoadImmSingleFGR:
2560 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2561 : MER_Success;
2562 case Mips::LoadImmDoubleGPR:
2563 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2564 : MER_Success;
2565 case Mips::LoadImmDoubleFGR:
2566 return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2567 : MER_Success;
2568 case Mips::LoadImmDoubleFGR_32:
2569 return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2570 : MER_Success;
2571
2572 case Mips::Ulh:
2573 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 case Mips::Ulhu:
2575 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2576 case Mips::Ush:
2577 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2578 case Mips::Ulw:
2579 case Mips::Usw:
2580 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2581 case Mips::NORImm:
2582 case Mips::NORImm64:
2583 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2584 case Mips::SGE:
2585 case Mips::SGEU:
2586 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2587 case Mips::SGEImm:
2588 case Mips::SGEUImm:
2589 case Mips::SGEImm64:
2590 case Mips::SGEUImm64:
2591 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2592 case Mips::SGTImm:
2593 case Mips::SGTUImm:
2594 case Mips::SGTImm64:
2595 case Mips::SGTUImm64:
2596 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2597 case Mips::SLE:
2598 case Mips::SLEU:
2599 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2600 case Mips::SLEImm:
2601 case Mips::SLEUImm:
2602 case Mips::SLEImm64:
2603 case Mips::SLEUImm64:
2604 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2605 case Mips::SLTImm64:
2606 if (isInt<16>(Inst.getOperand(2).getImm())) {
2607 Inst.setOpcode(Mips::SLTi64);
2608 return MER_NotAMacro;
2609 }
2610 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 case Mips::SLTUImm64:
2612 if (isInt<16>(Inst.getOperand(2).getImm())) {
2613 Inst.setOpcode(Mips::SLTiu64);
2614 return MER_NotAMacro;
2615 }
2616 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::ADDi: case Mips::ADDi_MM:
2618 case Mips::ADDiu: case Mips::ADDiu_MM:
2619 case Mips::SLTi: case Mips::SLTi_MM:
2620 case Mips::SLTiu: case Mips::SLTiu_MM:
2621 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2622 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2623 int64_t ImmValue = Inst.getOperand(2).getImm();
2624 if (isInt<16>(ImmValue))
2625 return MER_NotAMacro;
2626 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2627 : MER_Success;
2628 }
2629 return MER_NotAMacro;
2630 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2631 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2632 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2633 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2634 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2635 int64_t ImmValue = Inst.getOperand(2).getImm();
2636 if (isUInt<16>(ImmValue))
2637 return MER_NotAMacro;
2638 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2639 : MER_Success;
2640 }
2641 return MER_NotAMacro;
2642 case Mips::ROL:
2643 case Mips::ROR:
2644 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2645 case Mips::ROLImm:
2646 case Mips::RORImm:
2647 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2648 case Mips::DROL:
2649 case Mips::DROR:
2650 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651 case Mips::DROLImm:
2652 case Mips::DRORImm:
2653 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2654 case Mips::ABSMacro:
2655 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656 case Mips::MULImmMacro:
2657 case Mips::DMULImmMacro:
2658 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659 case Mips::MULOMacro:
2660 case Mips::DMULOMacro:
2661 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662 case Mips::MULOUMacro:
2663 case Mips::DMULOUMacro:
2664 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2665 case Mips::DMULMacro:
2666 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2667 case Mips::LDMacro:
2668 case Mips::SDMacro:
2669 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2670 Inst.getOpcode() == Mips::LDMacro)
2671 ? MER_Fail
2672 : MER_Success;
2673 case Mips::SDC1_M1:
2674 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2675 ? MER_Fail
2676 : MER_Success;
2677 case Mips::SEQMacro:
2678 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2679 case Mips::SEQIMacro:
2680 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2681 case Mips::SNEMacro:
2682 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2683 case Mips::SNEIMacro:
2684 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2685 case Mips::MFTC0: case Mips::MTTC0:
2686 case Mips::MFTGPR: case Mips::MTTGPR:
2687 case Mips::MFTLO: case Mips::MTTLO:
2688 case Mips::MFTHI: case Mips::MTTHI:
2689 case Mips::MFTACX: case Mips::MTTACX:
2690 case Mips::MFTDSP: case Mips::MTTDSP:
2691 case Mips::MFTC1: case Mips::MTTC1:
2692 case Mips::MFTHC1: case Mips::MTTHC1:
2693 case Mips::CFTC1: case Mips::CTTC1:
2694 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2695 case Mips::SaaAddr:
2696 case Mips::SaadAddr:
2697 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2698 }
2699}
2700
2701bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2702 MCStreamer &Out,
2703 const MCSubtargetInfo *STI) {
2704 MipsTargetStreamer &TOut = getTargetStreamer();
2705
2706 // Create a JALR instruction which is going to replace the pseudo-JAL.
2707 MCInst JalrInst;
2708 JalrInst.setLoc(IDLoc);
2709 const MCOperand FirstRegOp = Inst.getOperand(0);
2710 const unsigned Opcode = Inst.getOpcode();
2711
2712 if (Opcode == Mips::JalOneReg) {
2713 // jal $rs => jalr $rs
2714 if (IsCpRestoreSet && inMicroMipsMode()) {
2715 JalrInst.setOpcode(Mips::JALRS16_MM);
2716 JalrInst.addOperand(FirstRegOp);
2717 } else if (inMicroMipsMode()) {
2718 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2719 JalrInst.addOperand(FirstRegOp);
2720 } else {
2721 JalrInst.setOpcode(Mips::JALR);
2722 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2723 JalrInst.addOperand(FirstRegOp);
2724 }
2725 } else if (Opcode == Mips::JalTwoReg) {
2726 // jal $rd, $rs => jalr $rd, $rs
2727 if (IsCpRestoreSet && inMicroMipsMode())
2728 JalrInst.setOpcode(Mips::JALRS_MM);
2729 else
2730 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2731 JalrInst.addOperand(FirstRegOp);
2732 const MCOperand SecondRegOp = Inst.getOperand(1);
2733 JalrInst.addOperand(SecondRegOp);
2734 }
2735 Out.emitInstruction(JalrInst, *STI);
2736
2737 // If .set reorder is active and branch instruction has a delay slot,
2738 // emit a NOP after it.
2739 const MCInstrDesc &MCID = MII.get(JalrInst.getOpcode());
2740 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2741 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2742 STI);
2743
2744 return false;
2745}
2746
2747/// Can the value be represented by a unsigned N-bit value and a shift left?
2748template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2749 return x && isUInt<N>(x >> llvm::countr_zero(x));
2750}
2751
2752/// Load (or add) an immediate into a register.
2753///
2754/// @param ImmValue The immediate to load.
2755/// @param DstReg The register that will hold the immediate.
2756/// @param SrcReg A register to add to the immediate or Mips::NoRegister
2757/// for a simple initialization.
2758/// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2759/// @param IsAddress True if the immediate represents an address. False if it
2760/// is an integer.
2761/// @param IDLoc Location of the immediate in the source file.
2762bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2763 unsigned SrcReg, bool Is32BitImm,
2764 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2765 const MCSubtargetInfo *STI) {
2766 MipsTargetStreamer &TOut = getTargetStreamer();
2767
2768 if (!Is32BitImm && !isGP64bit()) {
2769 Error(IDLoc, "instruction requires a 64-bit architecture");
2770 return true;
2771 }
2772
2773 if (Is32BitImm) {
2774 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2775 // Sign extend up to 64-bit so that the predicates match the hardware
2776 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2777 // true.
2778 ImmValue = SignExtend64<32>(ImmValue);
2779 } else {
2780 Error(IDLoc, "instruction requires a 32-bit immediate");
2781 return true;
2782 }
2783 }
2784
2785 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2786 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2787
2788 bool UseSrcReg = false;
2789 if (SrcReg != Mips::NoRegister)
2790 UseSrcReg = true;
2791
2792 unsigned TmpReg = DstReg;
2793 if (UseSrcReg &&
2794 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2795 // At this point we need AT to perform the expansions and we exit if it is
2796 // not available.
2797 unsigned ATReg = getATReg(IDLoc);
2798 if (!ATReg)
2799 return true;
2800 TmpReg = ATReg;
2801 }
2802
2803 if (isInt<16>(ImmValue)) {
2804 if (!UseSrcReg)
2805 SrcReg = ZeroReg;
2806
2807 // This doesn't quite follow the usual ABI expectations for N32 but matches
2808 // traditional assembler behaviour. N32 would normally use addiu for both
2809 // integers and addresses.
2810 if (IsAddress && !Is32BitImm) {
2811 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2812 return false;
2813 }
2814
2815 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2816 return false;
2817 }
2818
2819 if (isUInt<16>(ImmValue)) {
2820 unsigned TmpReg = DstReg;
2821 if (SrcReg == DstReg) {
2822 TmpReg = getATReg(IDLoc);
2823 if (!TmpReg)
2824 return true;
2825 }
2826
2827 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2828 if (UseSrcReg)
2829 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2830 return false;
2831 }
2832
2833 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2834 warnIfNoMacro(IDLoc);
2835
2836 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2837 uint16_t Bits15To0 = ImmValue & 0xffff;
2838 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2839 // Traditional behaviour seems to special case this particular value. It's
2840 // not clear why other masks are handled differently.
2841 if (ImmValue == 0xffffffff) {
2842 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2843 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2844 if (UseSrcReg)
2845 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2846 return false;
2847 }
2848
2849 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2850 // upper 32 bits.
2851 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2852 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2853 if (Bits15To0)
2854 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2855 if (UseSrcReg)
2856 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2857 return false;
2858 }
2859
2860 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2861 if (Bits15To0)
2862 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2863 if (UseSrcReg)
2864 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2865 return false;
2866 }
2867
2868 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2869 if (Is32BitImm) {
2870 Error(IDLoc, "instruction requires a 32-bit immediate");
2871 return true;
2872 }
2873
2874 // We've processed ImmValue satisfying isUInt<16> above, so ImmValue must be
2875 // at least 17-bit wide here.
2876 unsigned BitWidth = llvm::bit_width((uint64_t)ImmValue);
2877 assert(BitWidth >= 17 && "ImmValue must be at least 17-bit wide");
2878
2879 // Traditionally, these immediates are shifted as little as possible and as
2880 // such we align the most significant bit to bit 15 of our temporary.
2881 unsigned ShiftAmount = BitWidth - 16;
2882 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2883 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2884 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2885
2886 if (UseSrcReg)
2887 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2888
2889 return false;
2890 }
2891
2892 warnIfNoMacro(IDLoc);
2893
2894 // The remaining case is packed with a sequence of dsll and ori with zeros
2895 // being omitted and any neighbouring dsll's being coalesced.
2896 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2897
2898 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2899 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2900 IDLoc, Out, STI))
2901 return false;
2902
2903 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2904 // skip it and defer the shift to the next chunk.
2905 unsigned ShiftCarriedForwards = 16;
2906 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2907 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2908
2909 if (ImmChunk != 0) {
2910 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2911 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2912 ShiftCarriedForwards = 0;
2913 }
2914
2915 ShiftCarriedForwards += 16;
2916 }
2917 ShiftCarriedForwards -= 16;
2918
2919 // Finish any remaining shifts left by trailing zeros.
2920 if (ShiftCarriedForwards)
2921 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2922
2923 if (UseSrcReg)
2924 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2925
2926 return false;
2927}
2928
2929bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2930 MCStreamer &Out, const MCSubtargetInfo *STI) {
2931 const MCOperand &ImmOp = Inst.getOperand(1);
2932 assert(ImmOp.isImm() && "expected immediate operand kind");
2933 const MCOperand &DstRegOp = Inst.getOperand(0);
2934 assert(DstRegOp.isReg() && "expected register operand kind");
2935
2936 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2937 Is32BitImm, false, IDLoc, Out, STI))
2938 return true;
2939
2940 return false;
2941}
2942
2943bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2944 const MCOperand &Offset,
2945 bool Is32BitAddress, SMLoc IDLoc,
2946 MCStreamer &Out,
2947 const MCSubtargetInfo *STI) {
2948 // la can't produce a usable address when addresses are 64-bit.
2949 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2950 Warning(IDLoc, "la used to load 64-bit address");
2951 // Continue as if we had 'dla' instead.
2952 Is32BitAddress = false;
2953 }
2954
2955 // dla requires 64-bit addresses.
2956 if (!Is32BitAddress && !hasMips3()) {
2957 Error(IDLoc, "instruction requires a 64-bit architecture");
2958 return true;
2959 }
2960
2961 if (!Offset.isImm())
2962 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2963 Is32BitAddress, IDLoc, Out, STI);
2964
2965 if (!ABI.ArePtrs64bit()) {
2966 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2967 Is32BitAddress = true;
2968 }
2969
2970 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2971 IDLoc, Out, STI);
2972}
2973
2974bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2975 unsigned DstReg, unsigned SrcReg,
2976 bool Is32BitSym, SMLoc IDLoc,
2977 MCStreamer &Out,
2978 const MCSubtargetInfo *STI) {
2979 MipsTargetStreamer &TOut = getTargetStreamer();
2980 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2981 SrcReg != Mips::ZERO_64;
2982 warnIfNoMacro(IDLoc);
2983
2984 if (inPicMode()) {
2985 MCValue Res;
2986 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2987 Error(IDLoc, "expected relocatable expression");
2988 return true;
2989 }
2990 if (Res.getSymB() != nullptr) {
2991 Error(IDLoc, "expected relocatable expression with only one symbol");
2992 return true;
2993 }
2994
2995 bool IsPtr64 = ABI.ArePtrs64bit();
2996 bool IsLocalSym =
2997 Res.getSymA()->getSymbol().isInSection() ||
2998 Res.getSymA()->getSymbol().isTemporary() ||
2999 (Res.getSymA()->getSymbol().isELF() &&
3000 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
3002 // For O32, "$"-prefixed symbols are recognized as temporary while
3003 // .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
3004 // manually.
3005 if (ABI.IsO32() && Res.getSymA()->getSymbol().getName().starts_with(".L"))
3006 IsLocalSym = true;
3007 bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3008
3009 // The case where the result register is $25 is somewhat special. If the
3010 // symbol in the final relocation is external and not modified with a
3011 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
3012 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
3013 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3014 Res.getConstant() == 0 && !IsLocalSym) {
3015 if (UseXGOT) {
3017 SymExpr, getContext());
3019 SymExpr, getContext());
3020 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3021 STI);
3022 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3023 IDLoc, STI);
3024 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3025 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3026 } else {
3027 const MCExpr *CallExpr =
3028 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
3029 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3030 MCOperand::createExpr(CallExpr), IDLoc, STI);
3031 }
3032 return false;
3033 }
3034
3035 unsigned TmpReg = DstReg;
3036 if (UseSrcReg &&
3037 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3038 SrcReg)) {
3039 // If $rs is the same as $rd, we need to use AT.
3040 // If it is not available we exit.
3041 unsigned ATReg = getATReg(IDLoc);
3042 if (!ATReg)
3043 return true;
3044 TmpReg = ATReg;
3045 }
3046
3047 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
3048 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
3049 // FIXME: Implement XGOT for microMIPS.
3050 if (UseXGOT) {
3051 // Loading address from XGOT
3052 // External GOT: lui $tmp, %got_hi(symbol)($gp)
3053 // addu $tmp, $tmp, $gp
3054 // lw $tmp, %got_lo(symbol)($tmp)
3055 // >addiu $tmp, $tmp, offset
3056 // >addiu $rd, $tmp, $rs
3057 // The addiu's marked with a '>' may be omitted if they are redundant. If
3058 // this happens then the last instruction must use $rd as the result
3059 // register.
3060 const MCExpr *CallHiExpr =
3061 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
3062 const MCExpr *CallLoExpr = MipsMCExpr::create(
3063 MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
3064
3065 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3066 STI);
3067 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3068 IDLoc, STI);
3069 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3070 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3071
3072 if (Res.getConstant() != 0)
3073 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3075 Res.getConstant(), getContext())),
3076 IDLoc, STI);
3077
3078 if (UseSrcReg)
3079 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3080 IDLoc, STI);
3081 return false;
3082 }
3083
3084 const MipsMCExpr *GotExpr = nullptr;
3085 const MCExpr *LoExpr = nullptr;
3086 if (ABI.IsN32() || ABI.IsN64()) {
3087 // The remaining cases are:
3088 // Small offset: ld $tmp, %got_disp(symbol)($gp)
3089 // >daddiu $tmp, $tmp, offset
3090 // >daddu $rd, $tmp, $rs
3091 // The daddiu's marked with a '>' may be omitted if they are redundant. If
3092 // this happens then the last instruction must use $rd as the result
3093 // register.
3095 getContext());
3096 if (Res.getConstant() != 0) {
3097 // Symbols fully resolve with just the %got_disp(symbol) but we
3098 // must still account for any offset to the symbol for
3099 // expressions like symbol+8.
3100 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3101
3102 // FIXME: Offsets greater than 16 bits are not yet implemented.
3103 // FIXME: The correct range is a 32-bit sign-extended number.
3104 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3105 Error(IDLoc, "macro instruction uses large offset, which is not "
3106 "currently supported");
3107 return true;
3108 }
3109 }
3110 } else {
3111 // The remaining cases are:
3112 // External GOT: lw $tmp, %got(symbol)($gp)
3113 // >addiu $tmp, $tmp, offset
3114 // >addiu $rd, $tmp, $rs
3115 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3116 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3117 // >addiu $rd, $tmp, $rs
3118 // The addiu's marked with a '>' may be omitted if they are redundant. If
3119 // this happens then the last instruction must use $rd as the result
3120 // register.
3121 if (IsLocalSym) {
3122 GotExpr =
3123 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3124 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3125 } else {
3126 // External symbols fully resolve the symbol with just the %got(symbol)
3127 // but we must still account for any offset to the symbol for
3128 // expressions like symbol+8.
3130 getContext());
3131 if (Res.getConstant() != 0)
3132 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3133 }
3134 }
3135
3136 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3137 MCOperand::createExpr(GotExpr), IDLoc, STI);
3138
3139 if (LoExpr)
3140 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3141 MCOperand::createExpr(LoExpr), IDLoc, STI);
3142
3143 if (UseSrcReg)
3144 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3145 IDLoc, STI);
3146
3147 return false;
3148 }
3149
3150 const MipsMCExpr *HiExpr =
3151 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3152 const MipsMCExpr *LoExpr =
3153 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3154
3155 // This is the 64-bit symbol address expansion.
3156 if (ABI.ArePtrs64bit() && isGP64bit()) {
3157 // We need AT for the 64-bit expansion in the cases where the optional
3158 // source register is the destination register and for the superscalar
3159 // scheduled form.
3160 //
3161 // If it is not available we exit if the destination is the same as the
3162 // source register.
3163
3164 const MipsMCExpr *HighestExpr =
3165 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3166 const MipsMCExpr *HigherExpr =
3167 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3168
3169 bool RdRegIsRsReg =
3170 UseSrcReg &&
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3172
3173 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3174 unsigned ATReg = getATReg(IDLoc);
3175
3176 // If $rs is the same as $rd:
3177 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3178 // daddiu $at, $at, %higher(sym)
3179 // dsll $at, $at, 16
3180 // daddiu $at, $at, %hi(sym)
3181 // dsll $at, $at, 16
3182 // daddiu $at, $at, %lo(sym)
3183 // daddu $rd, $at, $rd
3184 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3185 STI);
3186 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3187 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3188 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3189 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3190 IDLoc, STI);
3191 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3192 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3193 IDLoc, STI);
3194 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3195
3196 return false;
3197 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3198 unsigned ATReg = getATReg(IDLoc);
3199
3200 // If the $rs is different from $rd or if $rs isn't specified and we
3201 // have $at available:
3202 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3203 // lui $at, %hi(sym)
3204 // daddiu $rd, $rd, %higher(sym)
3205 // daddiu $at, $at, %lo(sym)
3206 // dsll32 $rd, $rd, 0
3207 // daddu $rd, $rd, $at
3208 // (daddu $rd, $rd, $rs)
3209 //
3210 // Which is preferred for superscalar issue.
3211 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3212 STI);
3213 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3214 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3215 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3216 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3217 IDLoc, STI);
3218 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3219 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3220 if (UseSrcReg)
3221 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3222
3223 return false;
3224 } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3225 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3226 // Otherwise, synthesize the address in the destination register
3227 // serially:
3228 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3229 // daddiu $rd, $rd, %higher(sym)
3230 // dsll $rd, $rd, 16
3231 // daddiu $rd, $rd, %hi(sym)
3232 // dsll $rd, $rd, 16
3233 // daddiu $rd, $rd, %lo(sym)
3234 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3235 STI);
3236 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3237 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3238 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3239 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3240 MCOperand::createExpr(HiExpr), IDLoc, STI);
3241 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3242 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3243 MCOperand::createExpr(LoExpr), IDLoc, STI);
3244 if (UseSrcReg)
3245 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3246
3247 return false;
3248 } else {
3249 // We have a case where SrcReg == DstReg and we don't have $at
3250 // available. We can't expand this case, so error out appropriately.
3251 assert(SrcReg == DstReg && !canUseATReg() &&
3252 "Could have expanded dla but didn't?");
3253 reportParseError(IDLoc,
3254 "pseudo-instruction requires $at, which is not available");
3255 return true;
3256 }
3257 }
3258
3259 // And now, the 32-bit symbol address expansion:
3260 // If $rs is the same as $rd:
3261 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3262 // ori $at, $at, %lo(sym)
3263 // addu $rd, $at, $rd
3264 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3265 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3266 // ori $rd, $rd, %lo(sym)
3267 // (addu $rd, $rd, $rs)
3268 unsigned TmpReg = DstReg;
3269 if (UseSrcReg &&
3270 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3271 // If $rs is the same as $rd, we need to use AT.
3272 // If it is not available we exit.
3273 unsigned ATReg = getATReg(IDLoc);
3274 if (!ATReg)
3275 return true;
3276 TmpReg = ATReg;
3277 }
3278
3279 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3280 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3281 IDLoc, STI);
3282
3283 if (UseSrcReg)
3284 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3285 else
3286 assert(
3287 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3288
3289 return false;
3290}
3291
3292// Each double-precision register DO-D15 overlaps with two of the single
3293// precision registers F0-F31. As an example, all of the following hold true:
3294// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3295static unsigned nextReg(unsigned Reg) {
3296 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3297 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3298 switch (Reg) {
3299 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3300 case Mips::ZERO: return Mips::AT;
3301 case Mips::AT: return Mips::V0;
3302 case Mips::V0: return Mips::V1;
3303 case Mips::V1: return Mips::A0;
3304 case Mips::A0: return Mips::A1;
3305 case Mips::A1: return Mips::A2;
3306 case Mips::A2: return Mips::A3;
3307 case Mips::A3: return Mips::T0;
3308 case Mips::T0: return Mips::T1;
3309 case Mips::T1: return Mips::T2;
3310 case Mips::T2: return Mips::T3;
3311 case Mips::T3: return Mips::T4;
3312 case Mips::T4: return Mips::T5;
3313 case Mips::T5: return Mips::T6;
3314 case Mips::T6: return Mips::T7;
3315 case Mips::T7: return Mips::S0;
3316 case Mips::S0: return Mips::S1;
3317 case Mips::S1: return Mips::S2;
3318 case Mips::S2: return Mips::S3;
3319 case Mips::S3: return Mips::S4;
3320 case Mips::S4: return Mips::S5;
3321 case Mips::S5: return Mips::S6;
3322 case Mips::S6: return Mips::S7;
3323 case Mips::S7: return Mips::T8;
3324 case Mips::T8: return Mips::T9;
3325 case Mips::T9: return Mips::K0;
3326 case Mips::K0: return Mips::K1;
3327 case Mips::K1: return Mips::GP;
3328 case Mips::GP: return Mips::SP;
3329 case Mips::SP: return Mips::FP;
3330 case Mips::FP: return Mips::RA;
3331 case Mips::RA: return Mips::ZERO;
3332 case Mips::D0: return Mips::F1;
3333 case Mips::D1: return Mips::F3;
3334 case Mips::D2: return Mips::F5;
3335 case Mips::D3: return Mips::F7;
3336 case Mips::D4: return Mips::F9;
3337 case Mips::D5: return Mips::F11;
3338 case Mips::D6: return Mips::F13;
3339 case Mips::D7: return Mips::F15;
3340 case Mips::D8: return Mips::F17;
3341 case Mips::D9: return Mips::F19;
3342 case Mips::D10: return Mips::F21;
3343 case Mips::D11: return Mips::F23;
3344 case Mips::D12: return Mips::F25;
3345 case Mips::D13: return Mips::F27;
3346 case Mips::D14: return Mips::F29;
3347 case Mips::D15: return Mips::F31;
3348 }
3349}
3350
3351// FIXME: This method is too general. In principle we should compute the number
3352// of instructions required to synthesize the immediate inline compared to
3353// synthesizing the address inline and relying on non .text sections.
3354// For static O32 and N32 this may yield a small benefit, for static N64 this is
3355// likely to yield a much larger benefit as we have to synthesize a 64bit
3356// address to load a 64 bit value.
3357bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3358 MCSymbol *Sym) {
3359 unsigned ATReg = getATReg(IDLoc);
3360 if (!ATReg)
3361 return true;
3362
3363 if(IsPicEnabled) {
3364 const MCExpr *GotSym =
3366 const MipsMCExpr *GotExpr =
3367 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3368
3369 if(isABI_O32() || isABI_N32()) {
3370 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3371 IDLoc, STI);
3372 } else { //isABI_N64()
3373 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3374 IDLoc, STI);
3375 }
3376 } else { //!IsPicEnabled
3377 const MCExpr *HiSym =
3379 const MipsMCExpr *HiExpr =
3380 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3381
3382 // FIXME: This is technically correct but gives a different result to gas,
3383 // but gas is incomplete there (it has a fixme noting it doesn't work with
3384 // 64-bit addresses).
3385 // FIXME: With -msym32 option, the address expansion for N64 should probably
3386 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3387 // symbol's value is considered sign extended.
3388 if(isABI_O32() || isABI_N32()) {
3389 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3390 } else { //isABI_N64()
3391 const MCExpr *HighestSym =
3393 const MipsMCExpr *HighestExpr =
3394 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3395 const MCExpr *HigherSym =
3397 const MipsMCExpr *HigherExpr =
3398 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3399
3400 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3401 STI);
3402 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3403 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3404 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3405 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3406 IDLoc, STI);
3407 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3408 }
3409 }
3410 return false;
3411}
3412
3414 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3415 // exponent field), convert it to double (e.g. 1 to 1.0)
3416 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3417 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3418 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3419 }
3420 return ImmOp64;
3421}
3422
3424 // Conversion of a double in an uint64_t to a float in a uint32_t,
3425 // retaining the bit pattern of a float.
3426 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3427 float TmpFloat = static_cast<float>(DoubleImm);
3428 return llvm::bit_cast<uint32_t>(TmpFloat);
3429}
3430
3431bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3432 MCStreamer &Out,
3433 const MCSubtargetInfo *STI) {
3434 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3435 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3436 "Invalid instruction operand.");
3437
3438 unsigned FirstReg = Inst.getOperand(0).getReg();
3439 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3440
3442
3443 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3444 Out, STI);
3445}
3446
3447bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3448 MCStreamer &Out,
3449 const MCSubtargetInfo *STI) {
3450 MipsTargetStreamer &TOut = getTargetStreamer();
3451 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3452 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3453 "Invalid instruction operand.");
3454
3455 unsigned FirstReg = Inst.getOperand(0).getReg();
3456 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3457
3458 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3459
3460 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3461
3462 unsigned TmpReg = Mips::ZERO;
3463 if (ImmOp32 != 0) {
3464 TmpReg = getATReg(IDLoc);
3465 if (!TmpReg)
3466 return true;
3467 }
3468
3469 if (Lo_32(ImmOp64) == 0) {
3470 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3471 true, false, IDLoc, Out, STI))
3472 return true;
3473 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3474 return false;
3475 }
3476
3477 MCSection *CS = getStreamer().getCurrentSectionOnly();
3478 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3479 // where appropriate.
3480 MCSection *ReadOnlySection =
3481 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3482
3483 MCSymbol *Sym = getContext().createTempSymbol();
3484 const MCExpr *LoSym =
3486 const MipsMCExpr *LoExpr =
3487 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3488
3489 getStreamer().switchSection(ReadOnlySection);
3490 getStreamer().emitLabel(Sym, IDLoc);
3491 getStreamer().emitInt32(ImmOp32);
3492 getStreamer().switchSection(CS);
3493
3494 if (emitPartialAddress(TOut, IDLoc, Sym))
3495 return true;
3496 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3497 IDLoc, STI);
3498 return false;
3499}
3500
3501bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3502 MCStreamer &Out,
3503 const MCSubtargetInfo *STI) {
3504 MipsTargetStreamer &TOut = getTargetStreamer();
3505 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3506 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3507 "Invalid instruction operand.");
3508
3509 unsigned FirstReg = Inst.getOperand(0).getReg();
3510 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3511
3512 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3513
3514 if (Lo_32(ImmOp64) == 0) {
3515 if (isGP64bit()) {
3516 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3517 IDLoc, Out, STI))
3518 return true;
3519 } else {
3520 if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3521 IDLoc, Out, STI))
3522 return true;
3523
3524 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3525 IDLoc, Out, STI))
3526 return true;
3527 }
3528 return false;
3529 }
3530
3531 MCSection *CS = getStreamer().getCurrentSectionOnly();
3532 MCSection *ReadOnlySection =
3533 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3534
3535 MCSymbol *Sym = getContext().createTempSymbol();
3536 const MCExpr *LoSym =
3538 const MipsMCExpr *LoExpr =
3539 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3540
3541 getStreamer().switchSection(ReadOnlySection);
3542 getStreamer().emitLabel(Sym, IDLoc);
3543 getStreamer().emitValueToAlignment(Align(8));
3544 getStreamer().emitIntValue(ImmOp64, 8);
3545 getStreamer().switchSection(CS);
3546
3547 unsigned TmpReg = getATReg(IDLoc);
3548 if (!TmpReg)
3549 return true;
3550
3551 if (emitPartialAddress(TOut, IDLoc, Sym))
3552 return true;
3553
3554 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3555 MCOperand::createExpr(LoExpr), IDLoc, STI);
3556
3557 if (isGP64bit())
3558 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3559 else {
3560 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3561 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3562 }
3563 return false;
3564}
3565
3566bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3567 SMLoc IDLoc, MCStreamer &Out,
3568 const MCSubtargetInfo *STI) {
3569 MipsTargetStreamer &TOut = getTargetStreamer();
3570 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3571 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3572 "Invalid instruction operand.");
3573
3574 unsigned FirstReg = Inst.getOperand(0).getReg();
3575 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3576
3577 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3578
3579 unsigned TmpReg = Mips::ZERO;
3580 if (ImmOp64 != 0) {
3581 TmpReg = getATReg(IDLoc);
3582 if (!TmpReg)
3583 return true;
3584 }
3585
3586 if ((Lo_32(ImmOp64) == 0) &&
3587 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3588 if (isGP64bit()) {
3589 if (TmpReg != Mips::ZERO &&
3590 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3591 Out, STI))
3592 return true;
3593 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3594 return false;
3595 }
3596
3597 if (TmpReg != Mips::ZERO &&
3598 loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3599 IDLoc, Out, STI))
3600 return true;
3601
3602 if (hasMips32r2()) {
3603 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3604 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3605 } else {
3606 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3607 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3608 }
3609 return false;
3610 }
3611
3612 MCSection *CS = getStreamer().getCurrentSectionOnly();
3613 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3614 // where appropriate.
3615 MCSection *ReadOnlySection =
3616 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3617
3618 MCSymbol *Sym = getContext().createTempSymbol();
3619 const MCExpr *LoSym =
3621 const MipsMCExpr *LoExpr =
3622 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3623
3624 getStreamer().switchSection(ReadOnlySection);
3625 getStreamer().emitLabel(Sym, IDLoc);
3626 getStreamer().emitValueToAlignment(Align(8));
3627 getStreamer().emitIntValue(ImmOp64, 8);
3628 getStreamer().switchSection(CS);
3629
3630 if (emitPartialAddress(TOut, IDLoc, Sym))
3631 return true;
3632
3633 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3634 MCOperand::createExpr(LoExpr), IDLoc, STI);
3635
3636 return false;
3637}
3638
3639bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3640 MCStreamer &Out,
3641 const MCSubtargetInfo *STI) {
3642 MipsTargetStreamer &TOut = getTargetStreamer();
3643
3644 assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 &&
3645 "unexpected number of operands");
3646
3647 MCOperand Offset = Inst.getOperand(0);
3648 if (Offset.isExpr()) {
3649 Inst.clear();
3650 Inst.setOpcode(Mips::BEQ_MM);
3651 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3652 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3653 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3654 } else {
3655 assert(Offset.isImm() && "expected immediate operand kind");
3656 if (isInt<11>(Offset.getImm())) {
3657 // If offset fits into 11 bits then this instruction becomes microMIPS
3658 // 16-bit unconditional branch instruction.
3659 if (inMicroMipsMode())
3660 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3661 } else {
3662 if (!isInt<17>(Offset.getImm()))
3663 return Error(IDLoc, "branch target out of range");
3664 if (offsetToAlignment(Offset.getImm(), Align(2)))
3665 return Error(IDLoc, "branch to misaligned address");
3666 Inst.clear();
3667 Inst.setOpcode(Mips::BEQ_MM);
3668 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3669 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3670 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3671 }
3672 }
3673 Out.emitInstruction(Inst, *STI);
3674
3675 // If .set reorder is active and branch instruction has a delay slot,
3676 // emit a NOP after it.
3677 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3678 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3679 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3680
3681 return false;
3682}
3683
3684bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3685 const MCSubtargetInfo *STI) {
3686 MipsTargetStreamer &TOut = getTargetStreamer();
3687 const MCOperand &DstRegOp = Inst.getOperand(0);
3688 assert(DstRegOp.isReg() && "expected register operand kind");
3689
3690 const MCOperand &ImmOp = Inst.getOperand(1);
3691 assert(ImmOp.isImm() && "expected immediate operand kind");
3692
3693 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3694 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3695 "expected immediate or expression operand");
3696
3697 bool IsLikely = false;
3698
3699 unsigned OpCode = 0;
3700 switch(Inst.getOpcode()) {
3701 case Mips::BneImm:
3702 OpCode = Mips::BNE;
3703 break;
3704 case Mips::BeqImm:
3705 OpCode = Mips::BEQ;
3706 break;
3707 case Mips::BEQLImmMacro:
3708 OpCode = Mips::BEQL;
3709 IsLikely = true;
3710 break;
3711 case Mips::BNELImmMacro:
3712 OpCode = Mips::BNEL;
3713 IsLikely = true;
3714 break;
3715 default:
3716 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3717 break;
3718 }
3719
3720 int64_t ImmValue = ImmOp.getImm();
3721 if (ImmValue == 0) {
3722 if (IsLikely) {
3723 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3724 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3725 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3726 } else
3727 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3728 STI);
3729 } else {
3730 warnIfNoMacro(IDLoc);
3731
3732 unsigned ATReg = getATReg(IDLoc);
3733 if (!ATReg)
3734 return true;
3735
3736 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3737 IDLoc, Out, STI))
3738 return true;
3739
3740 if (IsLikely) {
3741 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3742 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3743 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3744 } else
3745 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3746 }
3747 return false;
3748}
3749
3750void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3751 const MCSubtargetInfo *STI, bool IsLoad) {
3752 unsigned NumOp = Inst.getNumOperands();
3753 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3754 unsigned StartOp = NumOp == 3 ? 0 : 1;
3755
3756 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3757 assert(DstRegOp.isReg() && "expected register operand kind");
3758 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3759 assert(BaseRegOp.isReg() && "expected register operand kind");
3760 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3761
3762 MipsTargetStreamer &TOut = getTargetStreamer();
3763 unsigned OpCode = Inst.getOpcode();
3764 unsigned DstReg = DstRegOp.getReg();
3765 unsigned BaseReg = BaseRegOp.getReg();
3766 unsigned TmpReg = DstReg;
3767
3768 const MCInstrDesc &Desc = MII.get(OpCode);
3769 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3770 unsigned DstRegClassID =
3771 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3772 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3773 (DstRegClassID == Mips::GPR64RegClassID);
3774
3775 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3776 // At this point we need AT to perform the expansions
3777 // and we exit if it is not available.
3778 TmpReg = getATReg(IDLoc);
3779 if (!TmpReg)
3780 return;
3781 }
3782
3783 auto emitInstWithOffset = [&](const MCOperand &Off) {
3784 if (NumOp == 3)
3785 TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3786 else
3787 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3788 };
3789
3790 if (OffsetOp.isImm()) {
3791 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3792 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3793
3794 // If msb of LoOffset is 1(negative number) we must increment
3795 // HiOffset to account for the sign-extension of the low part.
3796 if (LoOffset & 0x8000)
3797 HiOffset += 0x10000;
3798
3799 bool IsLargeOffset = HiOffset != 0;
3800
3801 if (IsLargeOffset) {
3802 bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3803 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3804 IDLoc, Out, STI))
3805 return;
3806 }
3807
3808 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3809 TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3810 TmpReg, BaseReg, IDLoc, STI);
3811 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3812 return;
3813 }
3814
3815 if (OffsetOp.isExpr()) {
3816 if (inPicMode()) {
3817 // FIXME:
3818 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3819 // do not exceed 16-bit.
3820 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3821 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3822 // of GOT entries.
3823 MCValue Res;
3824 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3825 Error(IDLoc, "expected relocatable expression");
3826 return;
3827 }
3828 if (Res.getSymB() != nullptr) {
3829 Error(IDLoc, "expected relocatable expression with only one symbol");
3830 return;
3831 }
3832
3833 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3834 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3835 emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3836 } else {
3837 // FIXME: Implement 64-bit case.
3838 // 1) lw $8, sym => lui $8, %hi(sym)
3839 // lw $8, %lo(sym)($8)
3840 // 2) sw $8, sym => lui $at, %hi(sym)
3841 // sw $8, %lo(sym)($at)
3842 const MCExpr *OffExpr = OffsetOp.getExpr();
3843 MCOperand LoOperand = MCOperand::createExpr(
3844 MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
3845 MCOperand HiOperand = MCOperand::createExpr(
3846 MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
3847
3848 if (ABI.IsN64()) {
3849 MCOperand HighestOperand = MCOperand::createExpr(
3850 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
3851 MCOperand HigherOperand = MCOperand::createExpr(
3852 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
3853
3854 TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3855 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3856 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3857 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3858 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3859 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3860 TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3861 emitInstWithOffset(LoOperand);
3862 } else {
3863 // Generate the base address in TmpReg.
3864 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3865 if (BaseReg != Mips::ZERO)
3866 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3867 // Emit the load or store with the adjusted base and offset.
3868 emitInstWithOffset(LoOperand);
3869 }
3870 }
3871 return;
3872 }
3873
3874 llvm_unreachable("unexpected operand type");
3875}
3876
3877void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3878 const MCSubtargetInfo *STI, bool IsLoad) {
3879 unsigned NumOp = Inst.getNumOperands();
3880 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3881 unsigned StartOp = NumOp == 3 ? 0 : 1;
3882
3883 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3884 assert(DstRegOp.isReg() && "expected register operand kind");
3885 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3886 assert(BaseRegOp.isReg() && "expected register operand kind");
3887 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3888
3889 MipsTargetStreamer &TOut = getTargetStreamer();
3890 unsigned OpCode = Inst.getOpcode();
3891 unsigned DstReg = DstRegOp.getReg();
3892 unsigned BaseReg = BaseRegOp.getReg();
3893 unsigned TmpReg = DstReg;
3894
3895 const MCInstrDesc &Desc = MII.get(OpCode);
3896 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3897 unsigned DstRegClassID =
3898 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3899 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3900 (DstRegClassID == Mips::GPR64RegClassID);
3901
3902 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3903 // At this point we need AT to perform the expansions
3904 // and we exit if it is not available.
3905 TmpReg = getATReg(IDLoc);
3906 if (!TmpReg)
3907 return;
3908 }
3909
3910 auto emitInst = [&]() {
3911 if (NumOp == 3)
3912 TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3913 else
3914 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3915 IDLoc, STI);
3916 };
3917
3918 if (OffsetOp.isImm()) {
3919 loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3920 IDLoc, Out, STI);
3921 emitInst();
3922 return;
3923 }
3924
3925 if (OffsetOp.isExpr()) {
3926 loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3927 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3928 emitInst();
3929 return;
3930 }
3931
3932 llvm_unreachable("unexpected operand type");
3933}
3934
3935bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3936 MCStreamer &Out,
3937 const MCSubtargetInfo *STI) {
3938 unsigned OpNum = Inst.getNumOperands();
3939 unsigned Opcode = Inst.getOpcode();
3940 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3941
3942 assert(Inst.getOperand(OpNum - 1).isImm() &&
3943 Inst.getOperand(OpNum - 2).isReg() &&
3944 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3945
3946 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3947 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3948 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3949 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3950 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3951 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3952 // It can be implemented as SWM16 or LWM16 instruction.
3953 if (inMicroMipsMode() && hasMips32r6())
3954 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3955 else
3956 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3957 }
3958
3959 Inst.setOpcode(NewOpcode);
3960 Out.emitInstruction(Inst, *STI);
3961 return false;
3962}
3963
3964bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3965 MCStreamer &Out,
3966 const MCSubtargetInfo *STI) {
3967 MipsTargetStreamer &TOut = getTargetStreamer();
3968 bool EmittedNoMacroWarning = false;
3969 unsigned PseudoOpcode = Inst.getOpcode();
3970 unsigned SrcReg = Inst.getOperand(0).getReg();
3971 const MCOperand &TrgOp = Inst.getOperand(1);
3972 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3973
3974 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3975 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3976
3977 unsigned TrgReg;
3978 if (TrgOp.isReg())
3979 TrgReg = TrgOp.getReg();
3980 else if (TrgOp.isImm()) {
3981 warnIfNoMacro(IDLoc);
3982 EmittedNoMacroWarning = true;
3983
3984 TrgReg = getATReg(IDLoc);
3985 if (!TrgReg)
3986 return true;
3987
3988 switch(PseudoOpcode) {
3989 default:
3990 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3991 case Mips::BLTImmMacro:
3992 PseudoOpcode = Mips::BLT;
3993 break;
3994 case Mips::BLEImmMacro:
3995 PseudoOpcode = Mips::BLE;
3996 break;
3997 case Mips::BGEImmMacro:
3998 PseudoOpcode = Mips::BGE;
3999 break;
4000 case Mips::BGTImmMacro:
4001 PseudoOpcode = Mips::BGT;
4002 break;
4003 case Mips::BLTUImmMacro:
4004 PseudoOpcode = Mips::BLTU;
4005 break;
4006 case Mips::BLEUImmMacro:
4007 PseudoOpcode = Mips::BLEU;
4008 break;
4009 case Mips::BGEUImmMacro:
4010 PseudoOpcode = Mips::BGEU;
4011 break;
4012 case Mips::BGTUImmMacro:
4013 PseudoOpcode = Mips::BGTU;
4014 break;
4015 case Mips::BLTLImmMacro:
4016 PseudoOpcode = Mips::BLTL;
4017 break;
4018 case Mips::BLELImmMacro:
4019 PseudoOpcode = Mips::BLEL;
4020 break;
4021 case Mips::BGELImmMacro:
4022 PseudoOpcode = Mips::BGEL;
4023 break;
4024 case Mips::BGTLImmMacro:
4025 PseudoOpcode = Mips::BGTL;
4026 break;
4027 case Mips::BLTULImmMacro:
4028 PseudoOpcode = Mips::BLTUL;
4029 break;
4030 case Mips::BLEULImmMacro:
4031 PseudoOpcode = Mips::BLEUL;
4032 break;
4033 case Mips::BGEULImmMacro:
4034 PseudoOpcode = Mips::BGEUL;
4035 break;
4036 case Mips::BGTULImmMacro:
4037 PseudoOpcode = Mips::BGTUL;
4038 break;
4039 }
4040
4041 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4042 false, IDLoc, Out, STI))
4043 return true;
4044 }
4045
4046 switch (PseudoOpcode) {
4047 case Mips::BLT:
4048 case Mips::BLTU:
4049 case Mips::BLTL:
4050 case Mips::BLTUL:
4051 AcceptsEquality = false;
4052 ReverseOrderSLT = false;
4053 IsUnsigned =
4054 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4055 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4056 ZeroSrcOpcode = Mips::BGTZ;
4057 ZeroTrgOpcode = Mips::BLTZ;
4058 break;
4059 case Mips::BLE:
4060 case Mips::BLEU:
4061 case Mips::BLEL:
4062 case Mips::BLEUL:
4063 AcceptsEquality = true;
4064 ReverseOrderSLT = true;
4065 IsUnsigned =
4066 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4067 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4068 ZeroSrcOpcode = Mips::BGEZ;
4069 ZeroTrgOpcode = Mips::BLEZ;
4070 break;
4071 case Mips::BGE:
4072 case Mips::BGEU:
4073 case Mips::BGEL:
4074 case Mips::BGEUL:
4075 AcceptsEquality = true;
4076 ReverseOrderSLT = false;
4077 IsUnsigned =
4078 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4079 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4080 ZeroSrcOpcode = Mips::BLEZ;
4081 ZeroTrgOpcode = Mips::BGEZ;
4082 break;
4083 case Mips::BGT:
4084 case Mips::BGTU:
4085 case Mips::BGTL:
4086 case Mips::BGTUL:
4087 AcceptsEquality = false;
4088 ReverseOrderSLT = true;
4089 IsUnsigned =
4090 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4091 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4092 ZeroSrcOpcode = Mips::BLTZ;
4093 ZeroTrgOpcode = Mips::BGTZ;
4094 break;
4095 default:
4096 llvm_unreachable("unknown opcode for branch pseudo-instruction");
4097 }
4098
4099 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4100 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4101 if (IsSrcRegZero && IsTrgRegZero) {
4102 // FIXME: All of these Opcode-specific if's are needed for compatibility
4103 // with GAS' behaviour. However, they may not generate the most efficient
4104 // code in some circumstances.
4105 if (PseudoOpcode == Mips::BLT) {
4106 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4107 IDLoc, STI);
4108 return false;
4109 }
4110 if (PseudoOpcode == Mips::BLE) {
4111 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4112 IDLoc, STI);
4113 Warning(IDLoc, "branch is always taken");
4114 return false;
4115 }
4116 if (PseudoOpcode == Mips::BGE) {
4117 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4118 IDLoc, STI);
4119 Warning(IDLoc, "branch is always taken");
4120 return false;
4121 }
4122 if (PseudoOpcode == Mips::BGT) {
4123 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4124 IDLoc, STI);
4125 return false;
4126 }
4127 if (PseudoOpcode == Mips::BGTU) {
4128 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4129 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4130 return false;
4131 }
4132 if (AcceptsEquality) {
4133 // If both registers are $0 and the pseudo-branch accepts equality, it
4134 // will always be taken, so we emit an unconditional branch.
4135 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4136 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4137 Warning(IDLoc, "branch is always taken");
4138 return false;
4139 }
4140 // If both registers are $0 and the pseudo-branch does not accept
4141 // equality, it will never be taken, so we don't have to emit anything.
4142 return false;
4143 }
4144 if (IsSrcRegZero || IsTrgRegZero) {
4145 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4146 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4147 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4148 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4149 // the pseudo-branch will never be taken, so we don't emit anything.
4150 // This only applies to unsigned pseudo-branches.
4151 return false;
4152 }
4153 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4154 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4155 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4156 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4157 // the pseudo-branch will always be taken, so we emit an unconditional
4158 // branch.
4159 // This only applies to unsigned pseudo-branches.
4160 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4161 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4162 Warning(IDLoc, "branch is always taken");
4163 return false;
4164 }
4165 if (IsUnsigned) {
4166 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4167 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4168 // the pseudo-branch will be taken only when the non-zero register is
4169 // different from 0, so we emit a BNEZ.
4170 //
4171 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4172 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4173 // the pseudo-branch will be taken only when the non-zero register is
4174 // equal to 0, so we emit a BEQZ.
4175 //
4176 // Because only BLEU and BGEU branch on equality, we can use the
4177 // AcceptsEquality variable to decide when to emit the BEQZ.
4178 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4179 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4180 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4181 return false;
4182 }
4183 // If we have a signed pseudo-branch and one of the registers is $0,
4184 // we can use an appropriate compare-to-zero branch. We select which one
4185 // to use in the switch statement above.
4186 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4187 IsSrcRegZero ? TrgReg : SrcReg,
4188 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4189 return false;
4190 }
4191
4192 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4193 // expansions. If it is not available, we return.
4194 unsigned ATRegNum = getATReg(IDLoc);
4195 if (!ATRegNum)
4196 return true;
4197
4198 if (!EmittedNoMacroWarning)
4199 warnIfNoMacro(IDLoc);
4200
4201 // SLT fits well with 2 of our 4 pseudo-branches:
4202 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4203 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4204 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4205 // This is accomplished by using a BNEZ with the result of the SLT.
4206 //
4207 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4208 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4209 // Because only BGE and BLE branch on equality, we can use the
4210 // AcceptsEquality variable to decide when to emit the BEQZ.
4211 // Note that the order of the SLT arguments doesn't change between
4212 // opposites.
4213 //
4214 // The same applies to the unsigned variants, except that SLTu is used
4215 // instead of SLT.
4216 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4217 ReverseOrderSLT ? TrgReg : SrcReg,
4218 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4219
4220 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4221 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4222 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4223 STI);
4224 return false;
4225}
4226
4227// Expand a integer division macro.
4228//
4229// Notably we don't have to emit a warning when encountering $rt as the $zero
4230// register, or 0 as an immediate. processInstruction() has already done that.
4231//
4232// The destination register can only be $zero when expanding (S)DivIMacro or
4233// D(S)DivMacro.
4234
4235bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4236 const MCSubtargetInfo *STI,
4237 const bool IsMips64, const bool Signed) {
4238 MipsTargetStreamer &TOut = getTargetStreamer();
4239
4240 warnIfNoMacro(IDLoc);
4241
4242 const MCOperand &RdRegOp = Inst.getOperand(0);
4243 assert(RdRegOp.isReg() && "expected register operand kind");
4244 unsigned RdReg = RdRegOp.getReg();
4245
4246 const MCOperand &RsRegOp = Inst.getOperand(1);
4247 assert(RsRegOp.isReg() && "expected register operand kind");
4248 unsigned RsReg = RsRegOp.getReg();
4249
4250 unsigned RtReg;
4251 int64_t ImmValue;
4252
4253 const MCOperand &RtOp = Inst.getOperand(2);
4254 assert((RtOp.isReg() || RtOp.isImm()) &&
4255 "expected register or immediate operand kind");
4256 if (RtOp.isReg())
4257 RtReg = RtOp.getReg();
4258 else
4259 ImmValue = RtOp.getImm();
4260
4261 unsigned DivOp;
4262 unsigned ZeroReg;
4263 unsigned SubOp;
4264
4265 if (IsMips64) {
4266 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4267 ZeroReg = Mips::ZERO_64;
4268 SubOp = Mips::DSUB;
4269 } else {
4270 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4271 ZeroReg = Mips::ZERO;
4272 SubOp = Mips::SUB;
4273 }
4274
4275 bool UseTraps = useTraps();
4276
4277 unsigned Opcode = Inst.getOpcode();
4278 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4279 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4280 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4281 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4282
4283 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4284 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4285 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4286 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4287
4288 if (RtOp.isImm()) {
4289 unsigned ATReg = getATReg(IDLoc);
4290 if (!ATReg)
4291 return true;
4292
4293 if (ImmValue == 0) {
4294 if (UseTraps)
4295 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4296 else
4297 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4298 return false;
4299 }
4300
4301 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4302 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4303 return false;
4304 } else if (isDiv && ImmValue == 1) {
4305 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4306 return false;
4307 } else if (isDiv && Signed && ImmValue == -1) {
4308 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4309 return false;
4310 } else {
4311 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4312 false, Inst.getLoc(), Out, STI))
4313 return true;
4314 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4315 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4316 return false;
4317 }
4318 return true;
4319 }
4320
4321 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4322 // break, insert the trap/break and exit. This gives a different result to
4323 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4324 // are handled equivalently. As the observed behaviour is the same, we're ok.
4325 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4326 if (UseTraps) {
4327 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4328 return false;
4329 }
4330 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4331 return false;
4332 }
4333
4334 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4335 // not expand to macro sequence.
4336 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4337 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4338 return false;
4339 }
4340
4341 // Temporary label for first branch traget
4342 MCContext &Context = TOut.getStreamer().getContext();
4343 MCSymbol *BrTarget;
4344 MCOperand LabelOp;
4345
4346 if (UseTraps) {
4347 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4348 } else {
4349 // Branch to the li instruction.
4350 BrTarget = Context.createTempSymbol();
4351 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4352 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4353 }
4354
4355 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4356
4357 if (!UseTraps)
4358 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4359
4360 if (!Signed) {
4361 if (!UseTraps)
4362 TOut.getStreamer().emitLabel(BrTarget);
4363
4364 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4365 return false;
4366 }
4367
4368 unsigned ATReg = getATReg(IDLoc);
4369 if (!ATReg)
4370 return true;
4371
4372 if (!UseTraps)
4373 TOut.getStreamer().emitLabel(BrTarget);
4374
4375 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4376
4377 // Temporary label for the second branch target.
4378 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4379 MCOperand LabelOpEnd =
4380 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4381
4382 // Branch to the mflo instruction.
4383 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4384
4385 if (IsMips64) {
4386 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4387 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4388 } else {
4389 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4390 }
4391
4392 if (UseTraps)
4393 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4394 else {
4395 // Branch to the mflo instruction.
4396 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4397 TOut.emitNop(IDLoc, STI);
4398 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4399 }
4400
4401 TOut.getStreamer().emitLabel(BrTargetEnd);
4402 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4403 return false;
4404}
4405
4406bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4407 SMLoc IDLoc, MCStreamer &Out,
4408 const MCSubtargetInfo *STI) {
4409 MipsTargetStreamer &TOut = getTargetStreamer();
4410
4411 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4412 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4413 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4414
4415 unsigned FirstReg = Inst.getOperand(0).getReg();
4416 unsigned SecondReg = Inst.getOperand(1).getReg();
4417 unsigned ThirdReg = Inst.getOperand(2).getReg();
4418
4419 if (hasMips1() && !hasMips2()) {
4420 unsigned ATReg = getATReg(IDLoc);
4421 if (!ATReg)
4422 return true;
4423 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4424 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4425 TOut.emitNop(IDLoc, STI);
4426 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4427 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4428 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4429 TOut.emitNop(IDLoc, STI);
4430 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4431 : Mips::CVT_W_S,
4432 FirstReg, SecondReg, IDLoc, STI);
4433 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4434 TOut.emitNop(IDLoc, STI);
4435 return false;
4436 }
4437
4438 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4439 : Mips::TRUNC_W_S,
4440 FirstReg, SecondReg, IDLoc, STI);
4441
4442 return false;
4443}
4444
4445bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4446 MCStreamer &Out, const MCSubtargetInfo *STI) {
4447 if (hasMips32r6() || hasMips64r6()) {
4448 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4449 }
4450
4451 const MCOperand &DstRegOp = Inst.getOperand(0);
4452 assert(DstRegOp.isReg() && "expected register operand kind");
4453 const MCOperand &SrcRegOp = Inst.getOperand(1);
4454 assert(SrcRegOp.isReg() && "expected register operand kind");
4455 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4456 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4457
4458 MipsTargetStreamer &TOut = getTargetStreamer();
4459 unsigned DstReg = DstRegOp.getReg();
4460 unsigned SrcReg = SrcRegOp.getReg();
4461 int64_t OffsetValue = OffsetImmOp.getImm();
4462
4463 // NOTE: We always need AT for ULHU, as it is always used as the source
4464 // register for one of the LBu's.
4465 warnIfNoMacro(IDLoc);
4466 unsigned ATReg = getATReg(IDLoc);
4467 if (!ATReg)
4468 return true;
4469
4470 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4471 if (IsLargeOffset) {
4472 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4473 IDLoc, Out, STI))
4474 return true;
4475 }
4476
4477 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4478 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4479 if (isLittle())
4480 std::swap(FirstOffset, SecondOffset);
4481
4482 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4483 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4484
4485 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4486 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4487
4488 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4489 FirstOffset, IDLoc, STI);
4490 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4491 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4492 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4493
4494 return false;
4495}
4496
4497bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4498 const MCSubtargetInfo *STI) {
4499 if (hasMips32r6() || hasMips64r6()) {
4500 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4501 }
4502
4503 const MCOperand &DstRegOp = Inst.getOperand(0);
4504 assert(DstRegOp.isReg() && "expected register operand kind");
4505 const MCOperand &SrcRegOp = Inst.getOperand(1);
4506 assert(SrcRegOp.isReg() && "expected register operand kind");
4507 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4508 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4509
4510 MipsTargetStreamer &TOut = getTargetStreamer();
4511 unsigned DstReg = DstRegOp.getReg();
4512 unsigned SrcReg = SrcRegOp.getReg();
4513 int64_t OffsetValue = OffsetImmOp.getImm();
4514
4515 warnIfNoMacro(IDLoc);
4516 unsigned ATReg = getATReg(IDLoc);
4517 if (!ATReg)
4518 return true;
4519
4520 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4521 if (IsLargeOffset) {
4522 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4523 IDLoc, Out, STI))
4524 return true;
4525 }
4526
4527 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4528 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4529 if (isLittle())
4530 std::swap(FirstOffset, SecondOffset);
4531
4532 if (IsLargeOffset) {
4533 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4534 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4535 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4536 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4537 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4538 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4539 } else {
4540 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4541 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4542 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4543 }
4544
4545 return false;
4546}
4547
4548bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4549 const MCSubtargetInfo *STI) {
4550 if (hasMips32r6() || hasMips64r6()) {
4551 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4552 }
4553
4554 const MCOperand &DstRegOp = Inst.getOperand(0);
4555 assert(DstRegOp.isReg() && "expected register operand kind");
4556 const MCOperand &SrcRegOp = Inst.getOperand(1);
4557 assert(SrcRegOp.isReg() && "expected register operand kind");
4558 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4559 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4560
4561 MipsTargetStreamer &TOut = getTargetStreamer();
4562 unsigned DstReg = DstRegOp.getReg();
4563 unsigned SrcReg = SrcRegOp.getReg();
4564 int64_t OffsetValue = OffsetImmOp.getImm();
4565
4566 // Compute left/right load/store offsets.
4567 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4568 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4569 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4570 if (isLittle())
4571 std::swap(LxlOffset, LxrOffset);
4572
4573 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4574 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4575 unsigned TmpReg = SrcReg;
4576 if (IsLargeOffset || DoMove) {
4577 warnIfNoMacro(IDLoc);
4578 TmpReg = getATReg(IDLoc);
4579 if (!TmpReg)
4580 return true;
4581 }
4582
4583 if (IsLargeOffset) {
4584 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4585 IDLoc, Out, STI))
4586 return true;
4587 }
4588
4589 if (DoMove)
4590 std::swap(DstReg, TmpReg);
4591
4592 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4593 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4594 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4595 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4596
4597 if (DoMove)
4598 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4599
4600 return false;
4601}
4602
4603bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4604 const MCSubtargetInfo *STI) {
4605 MipsTargetStreamer &TOut = getTargetStreamer();
4606
4607 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4608 assert(Inst.getOperand(0).isReg() &&
4609 Inst.getOperand(1).isReg() &&
4610 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4611
4612 unsigned DstReg = Inst.getOperand(0).getReg();
4613 unsigned SrcReg = Inst.getOperand(1).getReg();
4614 unsigned OpReg = Inst.getOperand(2).getReg();
4615 unsigned OpCode;
4616
4617 warnIfNoMacro(IDLoc);
4618
4619 switch (Inst.getOpcode()) {
4620 case Mips::SGE:
4621 OpCode = Mips::SLT;
4622 break;
4623 case Mips::SGEU:
4624 OpCode = Mips::SLTu;
4625 break;
4626 default:
4627 llvm_unreachable("unexpected 'sge' opcode");
4628 }
4629
4630 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4631 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4632 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4633
4634 return false;
4635}
4636
4637bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4638 const MCSubtargetInfo *STI) {
4639 MipsTargetStreamer &TOut = getTargetStreamer();
4640
4641 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4642 assert(Inst.getOperand(0).isReg() &&
4643 Inst.getOperand(1).isReg() &&
4644 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4645
4646 unsigned DstReg = Inst.getOperand(0).getReg();
4647 unsigned SrcReg = Inst.getOperand(1).getReg();
4648 int64_t ImmValue = Inst.getOperand(2).getImm();
4649 unsigned OpRegCode, OpImmCode;
4650
4651 warnIfNoMacro(IDLoc);
4652
4653 switch (Inst.getOpcode()) {
4654 case Mips::SGEImm:
4655 case Mips::SGEImm64:
4656 OpRegCode = Mips::SLT;
4657 OpImmCode = Mips::SLTi;
4658 break;
4659 case Mips::SGEUImm:
4660 case Mips::SGEUImm64:
4661 OpRegCode = Mips::SLTu;
4662 OpImmCode = Mips::SLTiu;
4663 break;
4664 default:
4665 llvm_unreachable("unexpected 'sge' opcode with immediate");
4666 }
4667
4668 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4669 if (isInt<16>(ImmValue)) {
4670 // Use immediate version of STL.
4671 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4672 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4673 } else {
4674 unsigned ImmReg = DstReg;
4675 if (DstReg == SrcReg) {
4676 unsigned ATReg = getATReg(Inst.getLoc());
4677 if (!ATReg)
4678 return true;
4679 ImmReg = ATReg;
4680 }
4681
4682 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4683 false, IDLoc, Out, STI))
4684 return true;
4685
4686 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4687 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4688 }
4689
4690 return false;
4691}
4692
4693bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4694 const MCSubtargetInfo *STI) {
4695 MipsTargetStreamer &TOut = getTargetStreamer();
4696
4697 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4698 assert(Inst.getOperand(0).isReg() &&
4699 Inst.getOperand(1).isReg() &&
4700 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4701
4702 unsigned DstReg = Inst.getOperand(0).getReg();
4703 unsigned SrcReg = Inst.getOperand(1).getReg();
4704 unsigned ImmReg = DstReg;
4705 int64_t ImmValue = Inst.getOperand(2).getImm();
4706 unsigned OpCode;
4707
4708 warnIfNoMacro(IDLoc);
4709
4710 switch (Inst.getOpcode()) {
4711 case Mips::SGTImm:
4712 case Mips::SGTImm64:
4713 OpCode = Mips::SLT;
4714 break;
4715 case Mips::SGTUImm:
4716 case Mips::SGTUImm64:
4717 OpCode = Mips::SLTu;
4718 break;
4719 default:
4720 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4721 }
4722
4723 if (DstReg == SrcReg) {
4724 unsigned ATReg = getATReg(Inst.getLoc());
4725 if (!ATReg)
4726 return true;
4727 ImmReg = ATReg;
4728 }
4729
4730 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4731 false, IDLoc, Out, STI))
4732 return true;
4733
4734 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4735 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4736
4737 return false;
4738}
4739
4740bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4741 const MCSubtargetInfo *STI) {
4742 MipsTargetStreamer &TOut = getTargetStreamer();
4743
4744 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4745 assert(Inst.getOperand(0).isReg() &&
4746 Inst.getOperand(1).isReg() &&
4747 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4748
4749 unsigned DstReg = Inst.getOperand(0).getReg();
4750 unsigned SrcReg = Inst.getOperand(1).getReg();
4751 unsigned OpReg = Inst.getOperand(2).getReg();
4752 unsigned OpCode;
4753
4754 warnIfNoMacro(IDLoc);
4755
4756 switch (Inst.getOpcode()) {
4757 case Mips::SLE:
4758 OpCode = Mips::SLT;
4759 break;
4760 case Mips::SLEU:
4761 OpCode = Mips::SLTu;
4762 break;
4763 default:
4764 llvm_unreachable("unexpected 'sge' opcode");
4765 }
4766
4767 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4768 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4769 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4770
4771 return false;
4772}
4773
4774bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4775 const MCSubtargetInfo *STI) {
4776 MipsTargetStreamer &TOut = getTargetStreamer();
4777
4778 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4779 assert(Inst.getOperand(0).isReg() &&
4780 Inst.getOperand(1).isReg() &&
4781 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4782
4783 unsigned DstReg = Inst.getOperand(0).getReg();
4784 unsigned SrcReg = Inst.getOperand(1).getReg();
4785 int64_t ImmValue = Inst.getOperand(2).getImm();
4786 unsigned OpRegCode;
4787
4788 warnIfNoMacro(IDLoc);
4789
4790 switch (Inst.getOpcode()) {
4791 case Mips::SLEImm:
4792 case Mips::SLEImm64:
4793 OpRegCode = Mips::SLT;
4794 break;
4795 case Mips::SLEUImm:
4796 case Mips::SLEUImm64:
4797 OpRegCode = Mips::SLTu;
4798 break;
4799 default:
4800 llvm_unreachable("unexpected 'sge' opcode with immediate");
4801 }
4802
4803 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4804 unsigned ImmReg = DstReg;
4805 if (DstReg == SrcReg) {
4806 unsigned ATReg = getATReg(Inst.getLoc());
4807 if (!ATReg)
4808 return true;
4809 ImmReg = ATReg;
4810 }
4811
4812 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4813 false, IDLoc, Out, STI))
4814 return true;
4815
4816 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4817 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4818
4819 return false;
4820}
4821
4822bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4823 MCStreamer &Out,
4824 const MCSubtargetInfo *STI) {
4825 MipsTargetStreamer &TOut = getTargetStreamer();
4826
4827 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4828 assert(Inst.getOperand(0).isReg() &&
4829 Inst.getOperand(1).isReg() &&
4830 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4831
4832 unsigned ATReg = Mips::NoRegister;
4833 unsigned FinalDstReg = Mips::NoRegister;
4834 unsigned DstReg = Inst.getOperand(0).getReg();
4835 unsigned SrcReg = Inst.getOperand(1).getReg();
4836 int64_t ImmValue = Inst.getOperand(2).getImm();
4837
4838 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4839
4840 unsigned FinalOpcode = Inst.getOpcode();
4841
4842 if (DstReg == SrcReg) {
4843 ATReg = getATReg(Inst.getLoc());
4844 if (!ATReg)
4845 return true;
4846 FinalDstReg = DstReg;
4847 DstReg = ATReg;
4848 }
4849
4850 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4851 Inst.getLoc(), Out, STI)) {
4852 switch (FinalOpcode) {
4853 default:
4854 llvm_unreachable("unimplemented expansion");
4855 case Mips::ADDi:
4856 FinalOpcode = Mips::ADD;
4857 break;
4858 case Mips::ADDiu:
4859 FinalOpcode = Mips::ADDu;
4860 break;
4861 case Mips::ANDi:
4862 FinalOpcode = Mips::AND;
4863 break;
4864 case Mips::NORImm:
4865 FinalOpcode = Mips::NOR;
4866 break;
4867 case Mips::ORi:
4868 FinalOpcode = Mips::OR;
4869 break;
4870 case Mips::SLTi:
4871 FinalOpcode = Mips::SLT;
4872 break;
4873 case Mips::SLTiu:
4874 FinalOpcode = Mips::SLTu;
4875 break;
4876 case Mips::XORi:
4877 FinalOpcode = Mips::XOR;
4878 break;
4879 case Mips::ADDi_MM:
4880 FinalOpcode = Mips::ADD_MM;
4881 break;
4882 case Mips::ADDiu_MM:
4883 FinalOpcode = Mips::ADDu_MM;
4884 break;
4885 case Mips::ANDi_MM:
4886 FinalOpcode = Mips::AND_MM;
4887 break;
4888 case Mips::ORi_MM:
4889 FinalOpcode = Mips::OR_MM;
4890 break;
4891 case Mips::SLTi_MM:
4892 FinalOpcode = Mips::SLT_MM;
4893 break;
4894 case Mips::SLTiu_MM:
4895 FinalOpcode = Mips::SLTu_MM;
4896 break;
4897 case Mips::XORi_MM:
4898 FinalOpcode = Mips::XOR_MM;
4899 break;
4900 case Mips::ANDi64:
4901 FinalOpcode = Mips::AND64;
4902 break;
4903 case Mips::NORImm64:
4904 FinalOpcode = Mips::NOR64;
4905 break;
4906 case Mips::ORi64:
4907 FinalOpcode = Mips::OR64;
4908 break;
4909 case Mips::SLTImm64:
4910 FinalOpcode = Mips::SLT64;
4911 break;
4912 case Mips::SLTUImm64:
4913 FinalOpcode = Mips::SLTu64;
4914 break;
4915 case Mips::XORi64:
4916 FinalOpcode = Mips::XOR64;
4917 break;
4918 }
4919
4920 if (FinalDstReg == Mips::NoRegister)
4921 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4922 else
4923 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4924 return false;
4925 }
4926 return true;
4927}
4928
4929bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4930 const MCSubtargetInfo *STI) {
4931 MipsTargetStreamer &TOut = getTargetStreamer();
4932 unsigned ATReg = Mips::NoRegister;
4933 unsigned DReg = Inst.getOperand(0).getReg();
4934 unsigned SReg = Inst.getOperand(1).getReg();
4935 unsigned TReg = Inst.getOperand(2).getReg();
4936 unsigned TmpReg = DReg;
4937
4938 unsigned FirstShift = Mips::NOP;
4939 unsigned SecondShift = Mips::NOP;
4940
4941 if (hasMips32r2()) {
4942 if (DReg == SReg) {
4943 TmpReg = getATReg(Inst.getLoc());
4944 if (!TmpReg)
4945 return true;
4946 }
4947
4948 if (Inst.getOpcode() == Mips::ROL) {
4949 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4950 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4951 return false;
4952 }
4953
4954 if (Inst.getOpcode() == Mips::ROR) {
4955 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4956 return false;
4957 }
4958
4959 return true;
4960 }
4961
4962 if (hasMips32()) {
4963 switch (Inst.getOpcode()) {
4964 default:
4965 llvm_unreachable("unexpected instruction opcode");
4966 case Mips::ROL:
4967 FirstShift = Mips::SRLV;
4968 SecondShift = Mips::SLLV;
4969 break;
4970 case Mips::ROR:
4971 FirstShift = Mips::SLLV;
4972 SecondShift = Mips::SRLV;
4973 break;
4974 }
4975
4976 ATReg = getATReg(Inst.getLoc());
4977 if (!ATReg)
4978 return true;
4979
4980 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4981 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4982 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4983 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4984
4985 return false;
4986 }
4987
4988 return true;
4989}
4990
4991bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4992 MCStreamer &Out,
4993 const MCSubtargetInfo *STI) {
4994 MipsTargetStreamer &TOut = getTargetStreamer();
4995 unsigned ATReg = Mips::NoRegister;
4996 unsigned DReg = Inst.getOperand(0).getReg();
4997 unsigned SReg = Inst.getOperand(1).getReg();
4998 int64_t ImmValue = Inst.getOperand(2).getImm();
4999
5000 unsigned FirstShift = Mips::NOP;
5001 unsigned SecondShift = Mips::NOP;
5002
5003 if (hasMips32r2()) {
5004 if (Inst.getOpcode() == Mips::ROLImm) {
5005 uint64_t MaxShift = 32;
5006 uint64_t ShiftValue = ImmValue;
5007 if (ImmValue != 0)
5008 ShiftValue = MaxShift - ImmValue;
5009 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5010 return false;
5011 }
5012
5013 if (Inst.getOpcode() == Mips::RORImm) {
5014 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
5015 return false;
5016 }
5017
5018 return true;
5019 }
5020
5021 if (hasMips32()) {
5022 if (ImmValue == 0) {
5023 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
5024 return false;
5025 }
5026
5027 switch (Inst.getOpcode()) {
5028 default:
5029 llvm_unreachable("unexpected instruction opcode");
5030 case Mips::ROLImm:
5031 FirstShift = Mips::SLL;
5032 SecondShift = Mips::SRL;
5033 break;
5034 case Mips::RORImm:
5035 FirstShift = Mips::SRL;
5036 SecondShift = Mips::SLL;
5037 break;
5038 }
5039
5040 ATReg = getATReg(Inst.getLoc());
5041 if (!ATReg)
5042 return true;
5043
5044 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
5045 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
5046 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5047
5048 return false;
5049 }
5050
5051 return true;
5052}
5053
5054bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5055 const MCSubtargetInfo *STI) {
5056 MipsTargetStreamer &TOut = getTargetStreamer();
5057 unsigned ATReg = Mips::NoRegister;
5058 unsigned DReg = Inst.getOperand(0).getReg();
5059 unsigned SReg = Inst.getOperand(1).getReg();
5060 unsigned TReg = Inst.getOperand(2).getReg();
5061 unsigned TmpReg = DReg;
5062
5063 unsigned FirstShift = Mips::NOP;
5064 unsigned SecondShift = Mips::NOP;
5065
5066 if (hasMips64r2()) {
5067 if (TmpReg == SReg) {
5068 TmpReg = getATReg(Inst.getLoc());
5069 if (!TmpReg)
5070 return true;
5071 }
5072
5073 if (Inst.getOpcode() == Mips::DROL) {
5074 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5075 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
5076 return false;
5077 }
5078
5079 if (Inst.getOpcode() == Mips::DROR) {
5080 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
5081 return false;
5082 }
5083
5084 return true;
5085 }
5086
5087 if (hasMips64()) {
5088 switch (Inst.getOpcode()) {
5089 default:
5090 llvm_unreachable("unexpected instruction opcode");
5091 case Mips::DROL:
5092 FirstShift = Mips::DSRLV;
5093 SecondShift = Mips::DSLLV;
5094 break;
5095 case Mips::DROR:
5096 FirstShift = Mips::DSLLV;
5097 SecondShift = Mips::DSRLV;
5098 break;
5099 }
5100
5101 ATReg = getATReg(Inst.getLoc());
5102 if (!ATReg)
5103 return true;
5104
5105 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5106 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5107 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5108 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5109
5110 return false;
5111 }
5112
5113 return true;
5114}
5115
5116bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5117 MCStreamer &Out,
5118 const MCSubtargetInfo *STI) {
5119 MipsTargetStreamer &TOut = getTargetStreamer();
5120 unsigned ATReg = Mips::NoRegister;
5121 unsigned DReg = Inst.getOperand(0).getReg();
5122 unsigned SReg = Inst.getOperand(1).getReg();
5123 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5124
5125 unsigned FirstShift = Mips::NOP;
5126 unsigned SecondShift = Mips::NOP;
5127
5128 MCInst TmpInst;
5129
5130 if (hasMips64r2()) {
5131 unsigned FinalOpcode = Mips::NOP;
5132 if (ImmValue == 0)
5133 FinalOpcode = Mips::DROTR;
5134 else if (ImmValue % 32 == 0)
5135 FinalOpcode = Mips::DROTR32;
5136 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5137 if (Inst.getOpcode() == Mips::DROLImm)
5138 FinalOpcode = Mips::DROTR32;
5139 else
5140 FinalOpcode = Mips::DROTR;
5141 } else if (ImmValue >= 33) {
5142 if (Inst.getOpcode() == Mips::DROLImm)
5143 FinalOpcode = Mips::DROTR;
5144 else
5145 FinalOpcode = Mips::DROTR32;
5146 }
5147
5148 uint64_t ShiftValue = ImmValue % 32;
5149 if (Inst.getOpcode() == Mips::DROLImm)
5150 ShiftValue = (32 - ImmValue % 32) % 32;
5151
5152 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5153
5154 return false;
5155 }
5156
5157 if (hasMips64()) {
5158 if (ImmValue == 0) {
5159 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5160 return false;
5161 }
5162
5163 switch (Inst.getOpcode()) {
5164 default:
5165 llvm_unreachable("unexpected instruction opcode");
5166 case Mips::DROLImm:
5167 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5168 FirstShift = Mips::DSLL;
5169 SecondShift = Mips::DSRL32;
5170 }
5171 if (ImmValue == 32) {
5172 FirstShift = Mips::DSLL32;
5173 SecondShift = Mips::DSRL32;
5174 }
5175 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5176 FirstShift = Mips::DSLL32;
5177 SecondShift = Mips::DSRL;
5178 }
5179 break;
5180 case Mips::DRORImm:
5181 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5182 FirstShift = Mips::DSRL;
5183 SecondShift = Mips::DSLL32;
5184 }
5185 if (ImmValue == 32) {
5186 FirstShift = Mips::DSRL32;
5187 SecondShift = Mips::DSLL32;
5188 }
5189 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5190 FirstShift = Mips::DSRL32;
5191 SecondShift = Mips::DSLL;
5192 }
5193 break;
5194 }
5195
5196 ATReg = getATReg(Inst.getLoc());
5197 if (!ATReg)
5198 return true;
5199
5200 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5201 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5202 Inst.getLoc(), STI);
5203 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5204
5205 return false;
5206 }
5207
5208 return true;
5209}
5210
5211bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5212 const MCSubtargetInfo *STI) {
5213 MipsTargetStreamer &TOut = getTargetStreamer();
5214 unsigned FirstRegOp = Inst.getOperand(0).getReg();
5215 unsigned SecondRegOp = Inst.getOperand(1).getReg();
5216
5217 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5218 if (FirstRegOp != SecondRegOp)
5219 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5220 else
5221 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5222 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5223
5224 return false;
5225}
5226
5227bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5228 const MCSubtargetInfo *STI) {
5229 MipsTargetStreamer &TOut = getTargetStreamer();
5230 unsigned ATReg = Mips::NoRegister;
5231 unsigned DstReg = Inst.getOperand(0).getReg();
5232 unsigned SrcReg = Inst.getOperand(1).getReg();
5233 int32_t ImmValue = Inst.getOperand(2).getImm();
5234
5235 ATReg = getATReg(IDLoc);
5236 if (!ATReg)
5237 return true;
5238
5239 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
5240 STI);
5241
5242 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5243 SrcReg, ATReg, IDLoc, STI);
5244
5245 TOut.