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