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