LLVM 18.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 bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2924
2925 // The case where the result register is $25 is somewhat special. If the
2926 // symbol in the final relocation is external and not modified with a
2927 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2928 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2929 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2930 Res.getConstant() == 0 && !IsLocalSym) {
2931 if (UseXGOT) {
2933 SymExpr, getContext());
2935 SymExpr, getContext());
2936 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2937 STI);
2938 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2939 IDLoc, STI);
2940 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2941 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2942 } else {
2943 const MCExpr *CallExpr =
2944 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2945 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2946 MCOperand::createExpr(CallExpr), IDLoc, STI);
2947 }
2948 return false;
2949 }
2950
2951 unsigned TmpReg = DstReg;
2952 if (UseSrcReg &&
2953 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2954 SrcReg)) {
2955 // If $rs is the same as $rd, we need to use AT.
2956 // If it is not available we exit.
2957 unsigned ATReg = getATReg(IDLoc);
2958 if (!ATReg)
2959 return true;
2960 TmpReg = ATReg;
2961 }
2962
2963 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
2964 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
2965 // FIXME: Implement XGOT for microMIPS.
2966 if (UseXGOT) {
2967 // Loading address from XGOT
2968 // External GOT: lui $tmp, %got_hi(symbol)($gp)
2969 // addu $tmp, $tmp, $gp
2970 // lw $tmp, %got_lo(symbol)($tmp)
2971 // >addiu $tmp, $tmp, offset
2972 // >addiu $rd, $tmp, $rs
2973 // The addiu's marked with a '>' may be omitted if they are redundant. If
2974 // this happens then the last instruction must use $rd as the result
2975 // register.
2976 const MCExpr *CallHiExpr =
2977 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
2978 const MCExpr *CallLoExpr = MipsMCExpr::create(
2979 MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
2980
2981 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2982 STI);
2983 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2984 IDLoc, STI);
2985 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
2986 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2987
2988 if (Res.getConstant() != 0)
2989 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
2991 Res.getConstant(), getContext())),
2992 IDLoc, STI);
2993
2994 if (UseSrcReg)
2995 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
2996 IDLoc, STI);
2997 return false;
2998 }
2999
3000 const MipsMCExpr *GotExpr = nullptr;
3001 const MCExpr *LoExpr = nullptr;
3002 if (ABI.IsN32() || ABI.IsN64()) {
3003 // The remaining cases are:
3004 // Small offset: ld $tmp, %got_disp(symbol)($gp)
3005 // >daddiu $tmp, $tmp, offset
3006 // >daddu $rd, $tmp, $rs
3007 // The daddiu's marked with a '>' may be omitted if they are redundant. If
3008 // this happens then the last instruction must use $rd as the result
3009 // register.
3011 getContext());
3012 if (Res.getConstant() != 0) {
3013 // Symbols fully resolve with just the %got_disp(symbol) but we
3014 // must still account for any offset to the symbol for
3015 // expressions like symbol+8.
3016 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3017
3018 // FIXME: Offsets greater than 16 bits are not yet implemented.
3019 // FIXME: The correct range is a 32-bit sign-extended number.
3020 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3021 Error(IDLoc, "macro instruction uses large offset, which is not "
3022 "currently supported");
3023 return true;
3024 }
3025 }
3026 } else {
3027 // The remaining cases are:
3028 // External GOT: lw $tmp, %got(symbol)($gp)
3029 // >addiu $tmp, $tmp, offset
3030 // >addiu $rd, $tmp, $rs
3031 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3032 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3033 // >addiu $rd, $tmp, $rs
3034 // The addiu's marked with a '>' may be omitted if they are redundant. If
3035 // this happens then the last instruction must use $rd as the result
3036 // register.
3037 if (IsLocalSym) {
3038 GotExpr =
3039 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3040 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3041 } else {
3042 // External symbols fully resolve the symbol with just the %got(symbol)
3043 // but we must still account for any offset to the symbol for
3044 // expressions like symbol+8.
3046 getContext());
3047 if (Res.getConstant() != 0)
3048 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3049 }
3050 }
3051
3052 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3053 MCOperand::createExpr(GotExpr), IDLoc, STI);
3054
3055 if (LoExpr)
3056 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3057 MCOperand::createExpr(LoExpr), IDLoc, STI);
3058
3059 if (UseSrcReg)
3060 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3061 IDLoc, STI);
3062
3063 return false;
3064 }
3065
3066 const MipsMCExpr *HiExpr =
3067 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3068 const MipsMCExpr *LoExpr =
3069 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3070
3071 // This is the 64-bit symbol address expansion.
3072 if (ABI.ArePtrs64bit() && isGP64bit()) {
3073 // We need AT for the 64-bit expansion in the cases where the optional
3074 // source register is the destination register and for the superscalar
3075 // scheduled form.
3076 //
3077 // If it is not available we exit if the destination is the same as the
3078 // source register.
3079
3080 const MipsMCExpr *HighestExpr =
3081 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3082 const MipsMCExpr *HigherExpr =
3083 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3084
3085 bool RdRegIsRsReg =
3086 UseSrcReg &&
3087 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3088
3089 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3090 unsigned ATReg = getATReg(IDLoc);
3091
3092 // If $rs is the same as $rd:
3093 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3094 // daddiu $at, $at, %higher(sym)
3095 // dsll $at, $at, 16
3096 // daddiu $at, $at, %hi(sym)
3097 // dsll $at, $at, 16
3098 // daddiu $at, $at, %lo(sym)
3099 // daddu $rd, $at, $rd
3100 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3101 STI);
3102 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3103 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3104 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3105 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3106 IDLoc, STI);
3107 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3108 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3109 IDLoc, STI);
3110 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3111
3112 return false;
3113 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3114 unsigned ATReg = getATReg(IDLoc);
3115
3116 // If the $rs is different from $rd or if $rs isn't specified and we
3117 // have $at available:
3118 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3119 // lui $at, %hi(sym)
3120 // daddiu $rd, $rd, %higher(sym)
3121 // daddiu $at, $at, %lo(sym)
3122 // dsll32 $rd, $rd, 0
3123 // daddu $rd, $rd, $at
3124 // (daddu $rd, $rd, $rs)
3125 //
3126 // Which is preferred for superscalar issue.
3127 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3128 STI);
3129 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3130 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3131 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3132 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3133 IDLoc, STI);
3134 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3135 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3136 if (UseSrcReg)
3137 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3138
3139 return false;
3140 } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3141 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3142 // Otherwise, synthesize the address in the destination register
3143 // serially:
3144 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3145 // daddiu $rd, $rd, %higher(sym)
3146 // dsll $rd, $rd, 16
3147 // daddiu $rd, $rd, %hi(sym)
3148 // dsll $rd, $rd, 16
3149 // daddiu $rd, $rd, %lo(sym)
3150 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3151 STI);
3152 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3153 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3154 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3155 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3156 MCOperand::createExpr(HiExpr), IDLoc, STI);
3157 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3158 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3159 MCOperand::createExpr(LoExpr), IDLoc, STI);
3160 if (UseSrcReg)
3161 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3162
3163 return false;
3164 } else {
3165 // We have a case where SrcReg == DstReg and we don't have $at
3166 // available. We can't expand this case, so error out appropriately.
3167 assert(SrcReg == DstReg && !canUseATReg() &&
3168 "Could have expanded dla but didn't?");
3169 reportParseError(IDLoc,
3170 "pseudo-instruction requires $at, which is not available");
3171 return true;
3172 }
3173 }
3174
3175 // And now, the 32-bit symbol address expansion:
3176 // If $rs is the same as $rd:
3177 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3178 // ori $at, $at, %lo(sym)
3179 // addu $rd, $at, $rd
3180 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3181 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3182 // ori $rd, $rd, %lo(sym)
3183 // (addu $rd, $rd, $rs)
3184 unsigned TmpReg = DstReg;
3185 if (UseSrcReg &&
3186 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3187 // If $rs is the same as $rd, we need to use AT.
3188 // If it is not available we exit.
3189 unsigned ATReg = getATReg(IDLoc);
3190 if (!ATReg)
3191 return true;
3192 TmpReg = ATReg;
3193 }
3194
3195 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3196 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3197 IDLoc, STI);
3198
3199 if (UseSrcReg)
3200 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3201 else
3202 assert(
3203 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3204
3205 return false;
3206}
3207
3208// Each double-precision register DO-D15 overlaps with two of the single
3209// precision registers F0-F31. As an example, all of the following hold true:
3210// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3211static unsigned nextReg(unsigned Reg) {
3212 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3213 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3214 switch (Reg) {
3215 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3216 case Mips::ZERO: return Mips::AT;
3217 case Mips::AT: return Mips::V0;
3218 case Mips::V0: return Mips::V1;
3219 case Mips::V1: return Mips::A0;
3220 case Mips::A0: return Mips::A1;
3221 case Mips::A1: return Mips::A2;
3222 case Mips::A2: return Mips::A3;
3223 case Mips::A3: return Mips::T0;
3224 case Mips::T0: return Mips::T1;
3225 case Mips::T1: return Mips::T2;
3226 case Mips::T2: return Mips::T3;
3227 case Mips::T3: return Mips::T4;
3228 case Mips::T4: return Mips::T5;
3229 case Mips::T5: return Mips::T6;
3230 case Mips::T6: return Mips::T7;
3231 case Mips::T7: return Mips::S0;
3232 case Mips::S0: return Mips::S1;
3233 case Mips::S1: return Mips::S2;
3234 case Mips::S2: return Mips::S3;
3235 case Mips::S3: return Mips::S4;
3236 case Mips::S4: return Mips::S5;
3237 case Mips::S5: return Mips::S6;
3238 case Mips::S6: return Mips::S7;
3239 case Mips::S7: return Mips::T8;
3240 case Mips::T8: return Mips::T9;
3241 case Mips::T9: return Mips::K0;
3242 case Mips::K0: return Mips::K1;
3243 case Mips::K1: return Mips::GP;
3244 case Mips::GP: return Mips::SP;
3245 case Mips::SP: return Mips::FP;
3246 case Mips::FP: return Mips::RA;
3247 case Mips::RA: return Mips::ZERO;
3248 case Mips::D0: return Mips::F1;
3249 case Mips::D1: return Mips::F3;
3250 case Mips::D2: return Mips::F5;
3251 case Mips::D3: return Mips::F7;
3252 case Mips::D4: return Mips::F9;
3253 case Mips::D5: return Mips::F11;
3254 case Mips::D6: return Mips::F13;
3255 case Mips::D7: return Mips::F15;
3256 case Mips::D8: return Mips::F17;
3257 case Mips::D9: return Mips::F19;
3258 case Mips::D10: return Mips::F21;
3259 case Mips::D11: return Mips::F23;
3260 case Mips::D12: return Mips::F25;
3261 case Mips::D13: return Mips::F27;
3262 case Mips::D14: return Mips::F29;
3263 case Mips::D15: return Mips::F31;
3264 }
3265}
3266
3267// FIXME: This method is too general. In principle we should compute the number
3268// of instructions required to synthesize the immediate inline compared to
3269// synthesizing the address inline and relying on non .text sections.
3270// For static O32 and N32 this may yield a small benefit, for static N64 this is
3271// likely to yield a much larger benefit as we have to synthesize a 64bit
3272// address to load a 64 bit value.
3273bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3274 MCSymbol *Sym) {
3275 unsigned ATReg = getATReg(IDLoc);
3276 if (!ATReg)
3277 return true;
3278
3279 if(IsPicEnabled) {
3280 const MCExpr *GotSym =
3282 const MipsMCExpr *GotExpr =
3283 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3284
3285 if(isABI_O32() || isABI_N32()) {
3286 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3287 IDLoc, STI);
3288 } else { //isABI_N64()
3289 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3290 IDLoc, STI);
3291 }
3292 } else { //!IsPicEnabled
3293 const MCExpr *HiSym =
3295 const MipsMCExpr *HiExpr =
3296 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3297
3298 // FIXME: This is technically correct but gives a different result to gas,
3299 // but gas is incomplete there (it has a fixme noting it doesn't work with
3300 // 64-bit addresses).
3301 // FIXME: With -msym32 option, the address expansion for N64 should probably
3302 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3303 // symbol's value is considered sign extended.
3304 if(isABI_O32() || isABI_N32()) {
3305 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3306 } else { //isABI_N64()
3307 const MCExpr *HighestSym =
3309 const MipsMCExpr *HighestExpr =
3310 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3311 const MCExpr *HigherSym =
3313 const MipsMCExpr *HigherExpr =
3314 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3315
3316 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3317 STI);
3318 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3319 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3320 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3321 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3322 IDLoc, STI);
3323 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3324 }
3325 }
3326 return false;
3327}
3328
3330 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3331 // exponent field), convert it to double (e.g. 1 to 1.0)
3332 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3333 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3334 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3335 }
3336 return ImmOp64;
3337}
3338
3340 // Conversion of a double in an uint64_t to a float in a uint32_t,
3341 // retaining the bit pattern of a float.
3342 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3343 float TmpFloat = static_cast<float>(DoubleImm);
3344 return llvm::bit_cast<uint32_t>(TmpFloat);
3345}
3346
3347bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3348 MCStreamer &Out,
3349 const MCSubtargetInfo *STI) {
3350 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3351 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3352 "Invalid instruction operand.");
3353
3354 unsigned FirstReg = Inst.getOperand(0).getReg();
3355 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3356
3358
3359 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3360 Out, STI);
3361}
3362
3363bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3364 MCStreamer &Out,
3365 const MCSubtargetInfo *STI) {
3366 MipsTargetStreamer &TOut = getTargetStreamer();
3367 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3368 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3369 "Invalid instruction operand.");
3370
3371 unsigned FirstReg = Inst.getOperand(0).getReg();
3372 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3373
3374 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3375
3376 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3377
3378 unsigned TmpReg = Mips::ZERO;
3379 if (ImmOp32 != 0) {
3380 TmpReg = getATReg(IDLoc);
3381 if (!TmpReg)
3382 return true;
3383 }
3384
3385 if (Lo_32(ImmOp64) == 0) {
3386 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3387 true, false, IDLoc, Out, STI))
3388 return true;
3389 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3390 return false;
3391 }
3392
3393 MCSection *CS = getStreamer().getCurrentSectionOnly();
3394 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3395 // where appropriate.
3396 MCSection *ReadOnlySection =
3397 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3398
3399 MCSymbol *Sym = getContext().createTempSymbol();
3400 const MCExpr *LoSym =
3402 const MipsMCExpr *LoExpr =
3403 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3404
3405 getStreamer().switchSection(ReadOnlySection);
3406 getStreamer().emitLabel(Sym, IDLoc);
3407 getStreamer().emitInt32(ImmOp32);
3408 getStreamer().switchSection(CS);
3409
3410 if (emitPartialAddress(TOut, IDLoc, Sym))
3411 return true;
3412 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3413 IDLoc, STI);
3414 return false;
3415}
3416
3417bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3418 MCStreamer &Out,
3419 const MCSubtargetInfo *STI) {
3420 MipsTargetStreamer &TOut = getTargetStreamer();
3421 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3422 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3423 "Invalid instruction operand.");
3424
3425 unsigned FirstReg = Inst.getOperand(0).getReg();
3426 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3427
3428 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3429
3430 if (Lo_32(ImmOp64) == 0) {
3431 if (isGP64bit()) {
3432 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3433 IDLoc, Out, STI))
3434 return true;
3435 } else {
3436 if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3437 IDLoc, Out, STI))
3438 return true;
3439
3440 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3441 IDLoc, Out, STI))
3442 return true;
3443 }
3444 return false;
3445 }
3446
3447 MCSection *CS = getStreamer().getCurrentSectionOnly();
3448 MCSection *ReadOnlySection =
3449 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3450
3451 MCSymbol *Sym = getContext().createTempSymbol();
3452 const MCExpr *LoSym =
3454 const MipsMCExpr *LoExpr =
3455 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3456
3457 getStreamer().switchSection(ReadOnlySection);
3458 getStreamer().emitLabel(Sym, IDLoc);
3459 getStreamer().emitValueToAlignment(Align(8));
3460 getStreamer().emitIntValue(ImmOp64, 8);
3461 getStreamer().switchSection(CS);
3462
3463 unsigned TmpReg = getATReg(IDLoc);
3464 if (!TmpReg)
3465 return true;
3466
3467 if (emitPartialAddress(TOut, IDLoc, Sym))
3468 return true;
3469
3470 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3471 MCOperand::createExpr(LoExpr), IDLoc, STI);
3472
3473 if (isGP64bit())
3474 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3475 else {
3476 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3477 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3478 }
3479 return false;
3480}
3481
3482bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3483 SMLoc IDLoc, MCStreamer &Out,
3484 const MCSubtargetInfo *STI) {
3485 MipsTargetStreamer &TOut = getTargetStreamer();
3486 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3487 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3488 "Invalid instruction operand.");
3489
3490 unsigned FirstReg = Inst.getOperand(0).getReg();
3491 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3492
3493 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3494
3495 unsigned TmpReg = Mips::ZERO;
3496 if (ImmOp64 != 0) {
3497 TmpReg = getATReg(IDLoc);
3498 if (!TmpReg)
3499 return true;
3500 }
3501
3502 if ((Lo_32(ImmOp64) == 0) &&
3503 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3504 if (isGP64bit()) {
3505 if (TmpReg != Mips::ZERO &&
3506 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3507 Out, STI))
3508 return true;
3509 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3510 return false;
3511 }
3512
3513 if (TmpReg != Mips::ZERO &&
3514 loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3515 IDLoc, Out, STI))
3516 return true;
3517
3518 if (hasMips32r2()) {
3519 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3520 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3521 } else {
3522 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3523 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3524 }
3525 return false;
3526 }
3527
3528 MCSection *CS = getStreamer().getCurrentSectionOnly();
3529 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3530 // where appropriate.
3531 MCSection *ReadOnlySection =
3532 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3533
3534 MCSymbol *Sym = getContext().createTempSymbol();
3535 const MCExpr *LoSym =
3537 const MipsMCExpr *LoExpr =
3538 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3539
3540 getStreamer().switchSection(ReadOnlySection);
3541 getStreamer().emitLabel(Sym, IDLoc);
3542 getStreamer().emitValueToAlignment(Align(8));
3543 getStreamer().emitIntValue(ImmOp64, 8);
3544 getStreamer().switchSection(CS);
3545
3546 if (emitPartialAddress(TOut, IDLoc, Sym))
3547 return true;
3548
3549 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3550 MCOperand::createExpr(LoExpr), IDLoc, STI);
3551
3552 return false;
3553}
3554
3555bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3556 MCStreamer &Out,
3557 const MCSubtargetInfo *STI) {
3558 MipsTargetStreamer &TOut = getTargetStreamer();
3559
3560 assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 &&
3561 "unexpected number of operands");
3562
3563 MCOperand Offset = Inst.getOperand(0);
3564 if (Offset.isExpr()) {
3565 Inst.clear();
3566 Inst.setOpcode(Mips::BEQ_MM);
3567 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3568 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3569 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3570 } else {
3571 assert(Offset.isImm() && "expected immediate operand kind");
3572 if (isInt<11>(Offset.getImm())) {
3573 // If offset fits into 11 bits then this instruction becomes microMIPS
3574 // 16-bit unconditional branch instruction.
3575 if (inMicroMipsMode())
3576 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3577 } else {
3578 if (!isInt<17>(Offset.getImm()))
3579 return Error(IDLoc, "branch target out of range");
3580 if (offsetToAlignment(Offset.getImm(), Align(2)))
3581 return Error(IDLoc, "branch to misaligned address");
3582 Inst.clear();
3583 Inst.setOpcode(Mips::BEQ_MM);
3584 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3585 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3586 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3587 }
3588 }
3589 Out.emitInstruction(Inst, *STI);
3590
3591 // If .set reorder is active and branch instruction has a delay slot,
3592 // emit a NOP after it.
3593 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3594 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3595 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3596
3597 return false;
3598}
3599
3600bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3601 const MCSubtargetInfo *STI) {
3602 MipsTargetStreamer &TOut = getTargetStreamer();
3603 const MCOperand &DstRegOp = Inst.getOperand(0);
3604 assert(DstRegOp.isReg() && "expected register operand kind");
3605
3606 const MCOperand &ImmOp = Inst.getOperand(1);
3607 assert(ImmOp.isImm() && "expected immediate operand kind");
3608
3609 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3610 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3611 "expected immediate or expression operand");
3612
3613 bool IsLikely = false;
3614
3615 unsigned OpCode = 0;
3616 switch(Inst.getOpcode()) {
3617 case Mips::BneImm:
3618 OpCode = Mips::BNE;
3619 break;
3620 case Mips::BeqImm:
3621 OpCode = Mips::BEQ;
3622 break;
3623 case Mips::BEQLImmMacro:
3624 OpCode = Mips::BEQL;
3625 IsLikely = true;
3626 break;
3627 case Mips::BNELImmMacro:
3628 OpCode = Mips::BNEL;
3629 IsLikely = true;
3630 break;
3631 default:
3632 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3633 break;
3634 }
3635
3636 int64_t ImmValue = ImmOp.getImm();
3637 if (ImmValue == 0) {
3638 if (IsLikely) {
3639 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3640 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3641 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3642 } else
3643 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3644 STI);
3645 } else {
3646 warnIfNoMacro(IDLoc);
3647
3648 unsigned ATReg = getATReg(IDLoc);
3649 if (!ATReg)
3650 return true;
3651
3652 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3653 IDLoc, Out, STI))
3654 return true;
3655
3656 if (IsLikely) {
3657 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3658 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3659 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3660 } else
3661 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3662 }
3663 return false;
3664}
3665
3666void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3667 const MCSubtargetInfo *STI, bool IsLoad) {
3668 unsigned NumOp = Inst.getNumOperands();
3669 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3670 unsigned StartOp = NumOp == 3 ? 0 : 1;
3671
3672 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3673 assert(DstRegOp.isReg() && "expected register operand kind");
3674 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3675 assert(BaseRegOp.isReg() && "expected register operand kind");
3676 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3677
3678 MipsTargetStreamer &TOut = getTargetStreamer();
3679 unsigned OpCode = Inst.getOpcode();
3680 unsigned DstReg = DstRegOp.getReg();
3681 unsigned BaseReg = BaseRegOp.getReg();
3682 unsigned TmpReg = DstReg;
3683
3684 const MCInstrDesc &Desc = MII.get(OpCode);
3685 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3686 unsigned DstRegClassID =
3687 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3688 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3689 (DstRegClassID == Mips::GPR64RegClassID);
3690
3691 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3692 // At this point we need AT to perform the expansions
3693 // and we exit if it is not available.
3694 TmpReg = getATReg(IDLoc);
3695 if (!TmpReg)
3696 return;
3697 }
3698
3699 auto emitInstWithOffset = [&](const MCOperand &Off) {
3700 if (NumOp == 3)
3701 TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3702 else
3703 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3704 };
3705
3706 if (OffsetOp.isImm()) {
3707 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3708 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3709
3710 // If msb of LoOffset is 1(negative number) we must increment
3711 // HiOffset to account for the sign-extension of the low part.
3712 if (LoOffset & 0x8000)
3713 HiOffset += 0x10000;
3714
3715 bool IsLargeOffset = HiOffset != 0;
3716
3717 if (IsLargeOffset) {
3718 bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3719 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3720 IDLoc, Out, STI))
3721 return;
3722 }
3723
3724 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3725 TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3726 TmpReg, BaseReg, IDLoc, STI);
3727 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3728 return;
3729 }
3730
3731 if (OffsetOp.isExpr()) {
3732 if (inPicMode()) {
3733 // FIXME:
3734 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3735 // do not exceed 16-bit.
3736 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3737 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3738 // of GOT entries.
3739 MCValue Res;
3740 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3741 Error(IDLoc, "expected relocatable expression");
3742 return;
3743 }
3744 if (Res.getSymB() != nullptr) {
3745 Error(IDLoc, "expected relocatable expression with only one symbol");
3746 return;
3747 }
3748
3749 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3750 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3751 emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3752 } else {
3753 // FIXME: Implement 64-bit case.
3754 // 1) lw $8, sym => lui $8, %hi(sym)
3755 // lw $8, %lo(sym)($8)
3756 // 2) sw $8, sym => lui $at, %hi(sym)
3757 // sw $8, %lo(sym)($at)
3758 const MCExpr *OffExpr = OffsetOp.getExpr();
3759 MCOperand LoOperand = MCOperand::createExpr(
3760 MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
3761 MCOperand HiOperand = MCOperand::createExpr(
3762 MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
3763
3764 if (ABI.IsN64()) {
3765 MCOperand HighestOperand = MCOperand::createExpr(
3766 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
3767 MCOperand HigherOperand = MCOperand::createExpr(
3768 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
3769
3770 TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3771 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3772 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3773 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3774 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3775 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3776 TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3777 emitInstWithOffset(LoOperand);
3778 } else {
3779 // Generate the base address in TmpReg.
3780 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3781 if (BaseReg != Mips::ZERO)
3782 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3783 // Emit the load or store with the adjusted base and offset.
3784 emitInstWithOffset(LoOperand);
3785 }
3786 }
3787 return;
3788 }
3789
3790 llvm_unreachable("unexpected operand type");
3791}
3792
3793void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3794 const MCSubtargetInfo *STI, bool IsLoad) {
3795 unsigned NumOp = Inst.getNumOperands();
3796 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3797 unsigned StartOp = NumOp == 3 ? 0 : 1;
3798
3799 const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3800 assert(DstRegOp.isReg() && "expected register operand kind");
3801 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3802 assert(BaseRegOp.isReg() && "expected register operand kind");
3803 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3804
3805 MipsTargetStreamer &TOut = getTargetStreamer();
3806 unsigned OpCode = Inst.getOpcode();
3807 unsigned DstReg = DstRegOp.getReg();
3808 unsigned BaseReg = BaseRegOp.getReg();
3809 unsigned TmpReg = DstReg;
3810
3811 const MCInstrDesc &Desc = MII.get(OpCode);
3812 int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3813 unsigned DstRegClassID =
3814 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3815 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3816 (DstRegClassID == Mips::GPR64RegClassID);
3817
3818 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3819 // At this point we need AT to perform the expansions
3820 // and we exit if it is not available.
3821 TmpReg = getATReg(IDLoc);
3822 if (!TmpReg)
3823 return;
3824 }
3825
3826 auto emitInst = [&]() {
3827 if (NumOp == 3)
3828 TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3829 else
3830 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3831 IDLoc, STI);
3832 };
3833
3834 if (OffsetOp.isImm()) {
3835 loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3836 IDLoc, Out, STI);
3837 emitInst();
3838 return;
3839 }
3840
3841 if (OffsetOp.isExpr()) {
3842 loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3843 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3844 emitInst();
3845 return;
3846 }
3847
3848 llvm_unreachable("unexpected operand type");
3849}
3850
3851bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3852 MCStreamer &Out,
3853 const MCSubtargetInfo *STI) {
3854 unsigned OpNum = Inst.getNumOperands();
3855 unsigned Opcode = Inst.getOpcode();
3856 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3857
3858 assert(Inst.getOperand(OpNum - 1).isImm() &&
3859 Inst.getOperand(OpNum - 2).isReg() &&
3860 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3861
3862 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3863 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3864 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3865 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3866 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3867 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3868 // It can be implemented as SWM16 or LWM16 instruction.
3869 if (inMicroMipsMode() && hasMips32r6())
3870 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3871 else
3872 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3873 }
3874
3875 Inst.setOpcode(NewOpcode);
3876 Out.emitInstruction(Inst, *STI);
3877 return false;
3878}
3879
3880bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3881 MCStreamer &Out,
3882 const MCSubtargetInfo *STI) {
3883 MipsTargetStreamer &TOut = getTargetStreamer();
3884 bool EmittedNoMacroWarning = false;
3885 unsigned PseudoOpcode = Inst.getOpcode();
3886 unsigned SrcReg = Inst.getOperand(0).getReg();
3887 const MCOperand &TrgOp = Inst.getOperand(1);
3888 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3889
3890 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3891 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3892
3893 unsigned TrgReg;
3894 if (TrgOp.isReg())
3895 TrgReg = TrgOp.getReg();
3896 else if (TrgOp.isImm()) {
3897 warnIfNoMacro(IDLoc);
3898 EmittedNoMacroWarning = true;
3899
3900 TrgReg = getATReg(IDLoc);
3901 if (!TrgReg)
3902 return true;
3903
3904 switch(PseudoOpcode) {
3905 default:
3906 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3907 case Mips::BLTImmMacro:
3908 PseudoOpcode = Mips::BLT;
3909 break;
3910 case Mips::BLEImmMacro:
3911 PseudoOpcode = Mips::BLE;
3912 break;
3913 case Mips::BGEImmMacro:
3914 PseudoOpcode = Mips::BGE;
3915 break;
3916 case Mips::BGTImmMacro:
3917 PseudoOpcode = Mips::BGT;
3918 break;
3919 case Mips::BLTUImmMacro:
3920 PseudoOpcode = Mips::BLTU;
3921 break;
3922 case Mips::BLEUImmMacro:
3923 PseudoOpcode = Mips::BLEU;
3924 break;
3925 case Mips::BGEUImmMacro:
3926 PseudoOpcode = Mips::BGEU;
3927 break;
3928 case Mips::BGTUImmMacro:
3929 PseudoOpcode = Mips::BGTU;
3930 break;
3931 case Mips::BLTLImmMacro:
3932 PseudoOpcode = Mips::BLTL;
3933 break;
3934 case Mips::BLELImmMacro:
3935 PseudoOpcode = Mips::BLEL;
3936 break;
3937 case Mips::BGELImmMacro:
3938 PseudoOpcode = Mips::BGEL;
3939 break;
3940 case Mips::BGTLImmMacro:
3941 PseudoOpcode = Mips::BGTL;
3942 break;
3943 case Mips::BLTULImmMacro:
3944 PseudoOpcode = Mips::BLTUL;
3945 break;
3946 case Mips::BLEULImmMacro:
3947 PseudoOpcode = Mips::BLEUL;
3948 break;
3949 case Mips::BGEULImmMacro:
3950 PseudoOpcode = Mips::BGEUL;
3951 break;
3952 case Mips::BGTULImmMacro:
3953 PseudoOpcode = Mips::BGTUL;
3954 break;
3955 }
3956
3957 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3958 false, IDLoc, Out, STI))
3959 return true;
3960 }
3961
3962 switch (PseudoOpcode) {
3963 case Mips::BLT:
3964 case Mips::BLTU:
3965 case Mips::BLTL:
3966 case Mips::BLTUL:
3967 AcceptsEquality = false;
3968 ReverseOrderSLT = false;
3969 IsUnsigned =
3970 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3971 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3972 ZeroSrcOpcode = Mips::BGTZ;
3973 ZeroTrgOpcode = Mips::BLTZ;
3974 break;
3975 case Mips::BLE:
3976 case Mips::BLEU:
3977 case Mips::BLEL:
3978 case Mips::BLEUL:
3979 AcceptsEquality = true;
3980 ReverseOrderSLT = true;
3981 IsUnsigned =
3982 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3983 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3984 ZeroSrcOpcode = Mips::BGEZ;
3985 ZeroTrgOpcode = Mips::BLEZ;
3986 break;
3987 case Mips::BGE:
3988 case Mips::BGEU:
3989 case Mips::BGEL:
3990 case Mips::BGEUL:
3991 AcceptsEquality = true;
3992 ReverseOrderSLT = false;
3993 IsUnsigned =
3994 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3995 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3996 ZeroSrcOpcode = Mips::BLEZ;
3997 ZeroTrgOpcode = Mips::BGEZ;
3998 break;
3999 case Mips::BGT:
4000 case Mips::BGTU:
4001 case Mips::BGTL:
4002 case Mips::BGTUL:
4003 AcceptsEquality = false;
4004 ReverseOrderSLT = true;
4005 IsUnsigned =
4006 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4007 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4008 ZeroSrcOpcode = Mips::BLTZ;
4009 ZeroTrgOpcode = Mips::BGTZ;
4010 break;
4011 default:
4012 llvm_unreachable("unknown opcode for branch pseudo-instruction");
4013 }
4014
4015 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4016 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4017 if (IsSrcRegZero && IsTrgRegZero) {
4018 // FIXME: All of these Opcode-specific if's are needed for compatibility
4019 // with GAS' behaviour. However, they may not generate the most efficient
4020 // code in some circumstances.
4021 if (PseudoOpcode == Mips::BLT) {
4022 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4023 IDLoc, STI);
4024 return false;
4025 }
4026 if (PseudoOpcode == Mips::BLE) {
4027 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4028 IDLoc, STI);
4029 Warning(IDLoc, "branch is always taken");
4030 return false;
4031 }
4032 if (PseudoOpcode == Mips::BGE) {
4033 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4034 IDLoc, STI);
4035 Warning(IDLoc, "branch is always taken");
4036 return false;
4037 }
4038 if (PseudoOpcode == Mips::BGT) {
4039 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4040 IDLoc, STI);
4041 return false;
4042 }
4043 if (PseudoOpcode == Mips::BGTU) {
4044 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4045 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4046 return false;
4047 }
4048 if (AcceptsEquality) {
4049 // If both registers are $0 and the pseudo-branch accepts equality, it
4050 // will always be taken, so we emit an unconditional branch.
4051 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4052 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4053 Warning(IDLoc, "branch is always taken");
4054 return false;
4055 }
4056 // If both registers are $0 and the pseudo-branch does not accept
4057 // equality, it will never be taken, so we don't have to emit anything.
4058 return false;
4059 }
4060 if (IsSrcRegZero || IsTrgRegZero) {
4061 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4062 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4063 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4064 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4065 // the pseudo-branch will never be taken, so we don't emit anything.
4066 // This only applies to unsigned pseudo-branches.
4067 return false;
4068 }
4069 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4070 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4071 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4072 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4073 // the pseudo-branch will always be taken, so we emit an unconditional
4074 // branch.
4075 // This only applies to unsigned pseudo-branches.
4076 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4077 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4078 Warning(IDLoc, "branch is always taken");
4079 return false;
4080 }
4081 if (IsUnsigned) {
4082 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4083 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4084 // the pseudo-branch will be taken only when the non-zero register is
4085 // different from 0, so we emit a BNEZ.
4086 //
4087 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4088 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4089 // the pseudo-branch will be taken only when the non-zero register is
4090 // equal to 0, so we emit a BEQZ.
4091 //
4092 // Because only BLEU and BGEU branch on equality, we can use the
4093 // AcceptsEquality variable to decide when to emit the BEQZ.
4094 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4095 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4096 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4097 return false;
4098 }
4099 // If we have a signed pseudo-branch and one of the registers is $0,
4100 // we can use an appropriate compare-to-zero branch. We select which one
4101 // to use in the switch statement above.
4102 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4103 IsSrcRegZero ? TrgReg : SrcReg,
4104 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4105 return false;
4106 }
4107
4108 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4109 // expansions. If it is not available, we return.
4110 unsigned ATRegNum = getATReg(IDLoc);
4111 if (!ATRegNum)
4112 return true;
4113
4114 if (!EmittedNoMacroWarning)
4115 warnIfNoMacro(IDLoc);
4116
4117 // SLT fits well with 2 of our 4 pseudo-branches:
4118 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4119 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4120 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4121 // This is accomplished by using a BNEZ with the result of the SLT.
4122 //
4123 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4124 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4125 // Because only BGE and BLE branch on equality, we can use the
4126 // AcceptsEquality variable to decide when to emit the BEQZ.
4127 // Note that the order of the SLT arguments doesn't change between
4128 // opposites.
4129 //
4130 // The same applies to the unsigned variants, except that SLTu is used
4131 // instead of SLT.
4132 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4133 ReverseOrderSLT ? TrgReg : SrcReg,
4134 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4135
4136 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4137 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4138 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4139 STI);
4140 return false;
4141}
4142
4143// Expand a integer division macro.
4144//
4145// Notably we don't have to emit a warning when encountering $rt as the $zero
4146// register, or 0 as an immediate. processInstruction() has already done that.
4147//
4148// The destination register can only be $zero when expanding (S)DivIMacro or
4149// D(S)DivMacro.
4150
4151bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4152 const MCSubtargetInfo *STI,
4153 const bool IsMips64, const bool Signed) {
4154 MipsTargetStreamer &TOut = getTargetStreamer();
4155
4156 warnIfNoMacro(IDLoc);
4157
4158 const MCOperand &RdRegOp = Inst.getOperand(0);
4159 assert(RdRegOp.isReg() && "expected register operand kind");
4160 unsigned RdReg = RdRegOp.getReg();
4161
4162 const MCOperand &RsRegOp = Inst.getOperand(1);
4163 assert(RsRegOp.isReg() && "expected register operand kind");
4164 unsigned RsReg = RsRegOp.getReg();
4165
4166 unsigned RtReg;
4167 int64_t ImmValue;
4168
4169 const MCOperand &RtOp = Inst.getOperand(2);
4170 assert((RtOp.isReg() || RtOp.isImm()) &&
4171 "expected register or immediate operand kind");
4172 if (RtOp.isReg())
4173 RtReg = RtOp.getReg();
4174 else
4175 ImmValue = RtOp.getImm();
4176
4177 unsigned DivOp;
4178 unsigned ZeroReg;
4179 unsigned SubOp;
4180
4181 if (IsMips64) {
4182 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4183 ZeroReg = Mips::ZERO_64;
4184 SubOp = Mips::DSUB;
4185 } else {
4186 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4187 ZeroReg = Mips::ZERO;
4188 SubOp = Mips::SUB;
4189 }
4190
4191 bool UseTraps = useTraps();
4192
4193 unsigned Opcode = Inst.getOpcode();
4194 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4195 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4196 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4197 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4198
4199 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4200 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4201 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4202 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4203
4204 if (RtOp.isImm()) {
4205 unsigned ATReg = getATReg(IDLoc);
4206 if (!ATReg)
4207 return true;
4208
4209 if (ImmValue == 0) {
4210 if (UseTraps)
4211 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4212 else
4213 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4214 return false;
4215 }
4216
4217 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4218 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4219 return false;
4220 } else if (isDiv && ImmValue == 1) {
4221 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4222 return false;
4223 } else if (isDiv && Signed && ImmValue == -1) {
4224 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4225 return false;
4226 } else {
4227 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4228 false, Inst.getLoc(), Out, STI))
4229 return true;
4230 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4231 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4232 return false;
4233 }
4234 return true;
4235 }
4236
4237 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4238 // break, insert the trap/break and exit. This gives a different result to
4239 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4240 // are handled equivalently. As the observed behaviour is the same, we're ok.
4241 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4242 if (UseTraps) {
4243 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4244 return false;
4245 }
4246 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4247 return false;
4248 }
4249
4250 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4251 // not expand to macro sequence.
4252 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4253 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4254 return false;
4255 }
4256
4257 // Temporary label for first branch traget
4259 MCSymbol *BrTarget;
4260 MCOperand LabelOp;
4261
4262 if (UseTraps) {
4263 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4264 } else {
4265 // Branch to the li instruction.
4266 BrTarget = Context.createTempSymbol();
4267 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4268 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4269 }
4270
4271 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4272
4273 if (!UseTraps)
4274 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4275
4276 if (!Signed) {
4277 if (!UseTraps)
4278 TOut.getStreamer().emitLabel(BrTarget);
4279
4280 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4281 return false;
4282 }
4283
4284 unsigned ATReg = getATReg(IDLoc);
4285 if (!ATReg)
4286 return true;
4287
4288 if (!UseTraps)
4289 TOut.getStreamer().emitLabel(BrTarget);
4290
4291 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4292
4293 // Temporary label for the second branch target.
4294 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4295 MCOperand LabelOpEnd =
4296 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4297
4298 // Branch to the mflo instruction.
4299 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4300
4301 if (IsMips64) {
4302 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4303 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4304 } else {
4305 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4306 }
4307
4308 if (UseTraps)
4309 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4310 else {
4311 // Branch to the mflo instruction.
4312 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4313 TOut.emitNop(IDLoc, STI);
4314 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4315 }
4316
4317 TOut.getStreamer().emitLabel(BrTargetEnd);
4318 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4319 return false;
4320}
4321
4322bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4323 SMLoc IDLoc, MCStreamer &Out,
4324 const MCSubtargetInfo *STI) {
4325 MipsTargetStreamer &TOut = getTargetStreamer();
4326
4327 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4328 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4329 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4330
4331 unsigned FirstReg = Inst.getOperand(0).getReg();
4332 unsigned SecondReg = Inst.getOperand(1).getReg();
4333 unsigned ThirdReg = Inst.getOperand(2).getReg();
4334
4335 if (hasMips1() && !hasMips2()) {
4336 unsigned ATReg = getATReg(IDLoc);
4337 if (!ATReg)
4338 return true;
4339 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4340 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4341 TOut.emitNop(IDLoc, STI);
4342 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4343 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4344 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4345 TOut.emitNop(IDLoc, STI);
4346 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4347 : Mips::CVT_W_S,
4348 FirstReg, SecondReg, IDLoc, STI);
4349 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4350 TOut.emitNop(IDLoc, STI);
4351 return false;
4352 }
4353
4354 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4355 : Mips::TRUNC_W_S,
4356 FirstReg, SecondReg, IDLoc, STI);
4357
4358 return false;
4359}
4360
4361bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4362 MCStreamer &Out, const MCSubtargetInfo *STI) {
4363 if (hasMips32r6() || hasMips64r6()) {
4364 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4365 }
4366
4367 const MCOperand &DstRegOp = Inst.getOperand(0);
4368 assert(DstRegOp.isReg() && "expected register operand kind");
4369 const MCOperand &SrcRegOp = Inst.getOperand(1);
4370 assert(SrcRegOp.isReg() && "expected register operand kind");
4371 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4372 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4373
4374 MipsTargetStreamer &TOut = getTargetStreamer();
4375 unsigned DstReg = DstRegOp.getReg();
4376 unsigned SrcReg = SrcRegOp.getReg();
4377 int64_t OffsetValue = OffsetImmOp.getImm();
4378
4379 // NOTE: We always need AT for ULHU, as it is always used as the source
4380 // register for one of the LBu's.
4381 warnIfNoMacro(IDLoc);
4382 unsigned ATReg = getATReg(IDLoc);
4383 if (!ATReg)
4384 return true;
4385
4386 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4387 if (IsLargeOffset) {
4388 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4389 IDLoc, Out, STI))
4390 return true;
4391 }
4392
4393 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4394 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4395 if (isLittle())
4396 std::swap(FirstOffset, SecondOffset);
4397
4398 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4399 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4400
4401 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4402 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4403
4404 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4405 FirstOffset, IDLoc, STI);
4406 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4407 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4408 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4409
4410 return false;
4411}
4412
4413bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4414 const MCSubtargetInfo *STI) {
4415 if (hasMips32r6() || hasMips64r6()) {
4416 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4417 }
4418
4419 const MCOperand &DstRegOp = Inst.getOperand(0);
4420 assert(DstRegOp.isReg() && "expected register operand kind");
4421 const MCOperand &SrcRegOp = Inst.getOperand(1);
4422 assert(SrcRegOp.isReg() && "expected register operand kind");
4423 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4424 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4425
4426 MipsTargetStreamer &TOut = getTargetStreamer();
4427 unsigned DstReg = DstRegOp.getReg();
4428 unsigned SrcReg = SrcRegOp.getReg();
4429 int64_t OffsetValue = OffsetImmOp.getImm();
4430
4431 warnIfNoMacro(IDLoc);
4432 unsigned ATReg = getATReg(IDLoc);
4433 if (!ATReg)
4434 return true;
4435
4436 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4437 if (IsLargeOffset) {
4438 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4439 IDLoc, Out, STI))
4440 return true;
4441 }
4442
4443 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4444 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4445 if (isLittle())
4446 std::swap(FirstOffset, SecondOffset);
4447
4448 if (IsLargeOffset) {
4449 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4450 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4451 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4452 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4453 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4454 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4455 } else {
4456 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4457 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4458 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4459 }
4460
4461 return false;
4462}
4463
4464bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4465 const MCSubtargetInfo *STI) {
4466 if (hasMips32r6() || hasMips64r6()) {
4467 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4468 }
4469
4470 const MCOperand &DstRegOp = Inst.getOperand(0);
4471 assert(DstRegOp.isReg() && "expected register operand kind");
4472 const MCOperand &SrcRegOp = Inst.getOperand(1);
4473 assert(SrcRegOp.isReg() && "expected register operand kind");
4474 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4475 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4476
4477 MipsTargetStreamer &TOut = getTargetStreamer();
4478 unsigned DstReg = DstRegOp.getReg();
4479 unsigned SrcReg = SrcRegOp.getReg();
4480 int64_t OffsetValue = OffsetImmOp.getImm();
4481
4482 // Compute left/right load/store offsets.
4483 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4484 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4485 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4486 if (isLittle())
4487 std::swap(LxlOffset, LxrOffset);
4488
4489 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4490 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4491 unsigned TmpReg = SrcReg;
4492 if (IsLargeOffset || DoMove) {
4493 warnIfNoMacro(IDLoc);
4494 TmpReg = getATReg(IDLoc);
4495 if (!TmpReg)
4496 return true;
4497 }
4498
4499 if (IsLargeOffset) {
4500 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4501 IDLoc, Out, STI))
4502 return true;
4503 }
4504
4505 if (DoMove)
4506 std::swap(DstReg, TmpReg);
4507
4508 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4509 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4510 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4511 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4512
4513 if (DoMove)
4514 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4515
4516 return false;
4517}
4518
4519bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4520 const MCSubtargetInfo *STI) {
4521 MipsTargetStreamer &TOut = getTargetStreamer();
4522
4523 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4524 assert(Inst.getOperand(0).isReg() &&
4525 Inst.getOperand(1).isReg() &&
4526 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4527
4528 unsigned DstReg = Inst.getOperand(0).getReg();
4529 unsigned SrcReg = Inst.getOperand(1).getReg();
4530 unsigned OpReg = Inst.getOperand(2).getReg();
4531 unsigned OpCode;
4532
4533 warnIfNoMacro(IDLoc);
4534
4535 switch (Inst.getOpcode()) {
4536 case Mips::SGE:
4537 OpCode = Mips::SLT;
4538 break;
4539 case Mips::SGEU:
4540 OpCode = Mips::SLTu;
4541 break;
4542 default:
4543 llvm_unreachable("unexpected 'sge' opcode");
4544 }
4545
4546 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4547 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4548 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4549
4550 return false;
4551}
4552
4553bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4554 const MCSubtargetInfo *STI) {
4555 MipsTargetStreamer &TOut = getTargetStreamer();
4556
4557 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4558 assert(Inst.getOperand(0).isReg() &&
4559 Inst.getOperand(1).isReg() &&
4560 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4561
4562 unsigned DstReg = Inst.getOperand(0).getReg();
4563 unsigned SrcReg = Inst.getOperand(1).getReg();
4564 int64_t ImmValue = Inst.getOperand(2).getImm();
4565 unsigned OpRegCode, OpImmCode;
4566
4567 warnIfNoMacro(IDLoc);
4568
4569 switch (Inst.getOpcode()) {
4570 case Mips::SGEImm:
4571 case Mips::SGEImm64:
4572 OpRegCode = Mips::SLT;
4573 OpImmCode = Mips::SLTi;
4574 break;
4575 case Mips::SGEUImm:
4576 case Mips::SGEUImm64:
4577 OpRegCode = Mips::SLTu;
4578 OpImmCode = Mips::SLTiu;
4579 break;
4580 default:
4581 llvm_unreachable("unexpected 'sge' opcode with immediate");
4582 }
4583
4584 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4585 if (isInt<16>(ImmValue)) {
4586 // Use immediate version of STL.
4587 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4588 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4589 } else {
4590 unsigned ImmReg = DstReg;
4591 if (DstReg == SrcReg) {
4592 unsigned ATReg = getATReg(Inst.getLoc());
4593 if (!ATReg)
4594 return true;
4595 ImmReg = ATReg;
4596 }
4597
4598 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4599 false, IDLoc, Out, STI))
4600 return true;
4601
4602 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4603 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4604 }
4605
4606 return false;
4607}
4608
4609bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4610 const MCSubtargetInfo *STI) {
4611 MipsTargetStreamer &TOut = getTargetStreamer();
4612
4613 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4614 assert(Inst.getOperand(0).isReg() &&
4615 Inst.getOperand(1).isReg() &&
4616 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4617
4618 unsigned DstReg = Inst.getOperand(0).getReg();
4619 unsigned SrcReg = Inst.getOperand(1).getReg();
4620 unsigned ImmReg = DstReg;
4621 int64_t ImmValue = Inst.getOperand(2).getImm();
4622 unsigned OpCode;
4623
4624 warnIfNoMacro(IDLoc);
4625
4626 switch (Inst.getOpcode()) {
4627 case Mips::SGTImm:
4628 case Mips::SGTImm64:
4629 OpCode = Mips::SLT;
4630 break;
4631 case Mips::SGTUImm:
4632 case Mips::SGTUImm64:
4633 OpCode = Mips::SLTu;
4634 break;
4635 default:
4636 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4637 }
4638
4639 if (DstReg == SrcReg) {
4640 unsigned ATReg = getATReg(Inst.getLoc());
4641 if (!ATReg)
4642 return true;
4643 ImmReg = ATReg;
4644 }
4645
4646 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4647 false, IDLoc, Out, STI))
4648 return true;
4649
4650 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4651 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4652
4653 return false;
4654}
4655
4656bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4657 const MCSubtargetInfo *STI) {
4658 MipsTargetStreamer &TOut = getTargetStreamer();
4659
4660 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4661 assert(Inst.getOperand(0).isReg() &&
4662 Inst.getOperand(1).isReg() &&
4663 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4664
4665 unsigned DstReg = Inst.getOperand(0).getReg();
4666 unsigned SrcReg = Inst.getOperand(1).getReg();
4667 unsigned OpReg = Inst.getOperand(2).getReg();
4668 unsigned OpCode;
4669
4670 warnIfNoMacro(IDLoc);
4671
4672 switch (Inst.getOpcode()) {
4673 case Mips::SLE:
4674 OpCode = Mips::SLT;
4675 break;
4676 case Mips::SLEU:
4677 OpCode = Mips::SLTu;
4678 break;
4679 default:
4680 llvm_unreachable("unexpected 'sge' opcode");
4681 }
4682
4683 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4684 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4685 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4686
4687 return false;
4688}
4689
4690bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4691 const MCSubtargetInfo *STI) {
4692 MipsTargetStreamer &TOut = getTargetStreamer();
4693
4694 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4695 assert(Inst.getOperand(0).isReg() &&
4696 Inst.getOperand(1).isReg() &&
4697 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4698
4699 unsigned DstReg = Inst.getOperand(0).getReg();
4700 unsigned SrcReg = Inst.getOperand(1).getReg();
4701 int64_t ImmValue = Inst.getOperand(2).getImm();
4702 unsigned OpRegCode;
4703
4704 warnIfNoMacro(IDLoc);
4705
4706 switch (Inst.getOpcode()) {
4707 case Mips::SLEImm:
4708 case Mips::SLEImm64:
4709 OpRegCode = Mips::SLT;
4710 break;
4711 case Mips::SLEUImm:
4712 case Mips::SLEUImm64:
4713 OpRegCode = Mips::SLTu;
4714 break;
4715 default:
4716 llvm_unreachable("unexpected 'sge' opcode with immediate");
4717 }
4718
4719 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4720 unsigned ImmReg = DstReg;
4721 if (DstReg == SrcReg) {
4722 unsigned ATReg = getATReg(Inst.getLoc());
4723 if (!ATReg)
4724 return true;
4725 ImmReg = ATReg;
4726 }
4727
4728 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4729 false, IDLoc, Out, STI))
4730 return true;
4731
4732 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4733 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4734
4735 return false;
4736}
4737
4738bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4739 MCStreamer &Out,
4740 const MCSubtargetInfo *STI) {
4741 MipsTargetStreamer &TOut = getTargetStreamer();
4742
4743 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4744 assert(Inst.getOperand(0).isReg() &&
4745 Inst.getOperand(1).isReg() &&
4746 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4747
4748 unsigned ATReg = Mips::NoRegister;
4749 unsigned FinalDstReg = Mips::NoRegister;
4750 unsigned DstReg = Inst.getOperand(0).getReg();
4751 unsigned SrcReg = Inst.getOperand(1).getReg();
4752 int64_t ImmValue = Inst.getOperand(2).getImm();
4753
4754 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4755
4756 unsigned FinalOpcode = Inst.getOpcode();
4757
4758 if (DstReg == SrcReg) {
4759 ATReg = getATReg(Inst.getLoc());
4760 if (!ATReg)
4761 return true;
4762 FinalDstReg = DstReg;
4763 DstReg = ATReg;
4764 }
4765
4766 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4767 Inst.getLoc(), Out, STI)) {
4768 switch (FinalOpcode) {
4769 default:
4770 llvm_unreachable("unimplemented expansion");
4771 case Mips::ADDi:
4772 FinalOpcode = Mips::ADD;
4773 break;
4774 case Mips::ADDiu:
4775 FinalOpcode = Mips::ADDu;
4776 break;
4777 case Mips::ANDi:
4778 FinalOpcode = Mips::AND;
4779 break;
4780 case Mips::NORImm:
4781 FinalOpcode = Mips::NOR;
4782 break;
4783 case Mips::ORi:
4784 FinalOpcode = Mips::OR;
4785 break;
4786 case Mips::SLTi:
4787 FinalOpcode = Mips::SLT;
4788 break;
4789 case Mips::SLTiu:
4790 FinalOpcode = Mips::SLTu;
4791 break;
4792 case Mips::XORi:
4793 FinalOpcode = Mips::XOR;
4794 break;
4795 case Mips::ADDi_MM:
4796 FinalOpcode = Mips::ADD_MM;
4797 break;
4798 case Mips::ADDiu_MM:
4799 FinalOpcode = Mips::ADDu_MM;
4800 break;
4801 case Mips::ANDi_MM:
4802 FinalOpcode = Mips::AND_MM;
4803 break;
4804 case Mips::ORi_MM:
4805 FinalOpcode = Mips::OR_MM;
4806 break;
4807 case Mips::SLTi_MM:
4808 FinalOpcode = Mips::SLT_MM;
4809 break;
4810 case Mips::SLTiu_MM:
4811 FinalOpcode = Mips::SLTu_MM;
4812 break;
4813 case Mips::XORi_MM:
4814 FinalOpcode = Mips::XOR_MM;
4815 break;
4816 case Mips::ANDi64:
4817 FinalOpcode = Mips::AND64;
4818 break;
4819 case Mips::NORImm64:
4820 FinalOpcode = Mips::NOR64;
4821 break;
4822 case Mips::ORi64:
4823 FinalOpcode = Mips::OR64;
4824 break;
4825 case Mips::SLTImm64:
4826 FinalOpcode = Mips::SLT64;
4827 break;
4828 case Mips::SLTUImm64:
4829 FinalOpcode = Mips::SLTu64;
4830 break;
4831 case Mips::XORi64:
4832 FinalOpcode = Mips::XOR64;
4833 break;
4834 }
4835
4836 if (FinalDstReg == Mips::NoRegister)
4837 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4838 else
4839 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4840 return false;
4841 }
4842 return true;
4843}
4844
4845bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4846 const MCSubtargetInfo *STI) {
4847 MipsTargetStreamer &TOut = getTargetStreamer();
4848 unsigned ATReg = Mips::NoRegister;
4849 unsigned DReg = Inst.getOperand(0).getReg();
4850 unsigned SReg = Inst.getOperand(1).getReg();
4851 unsigned TReg = Inst.getOperand(2).getReg();
4852 unsigned TmpReg = DReg;
4853
4854 unsigned FirstShift = Mips::NOP;
4855 unsigned SecondShift = Mips::NOP;
4856
4857 if (hasMips32r2()) {
4858 if (DReg == SReg) {
4859 TmpReg = getATReg(Inst.getLoc());
4860 if (!TmpReg)
4861 return true;
4862 }
4863
4864 if (Inst.getOpcode() == Mips::ROL) {
4865 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4866 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4867 return false;
4868 }
4869
4870 if (Inst.getOpcode() == Mips::ROR) {
4871 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4872 return false;
4873 }
4874
4875 return true;
4876 }
4877
4878 if (hasMips32()) {
4879 switch (Inst.getOpcode()) {
4880 default:
4881 llvm_unreachable("unexpected instruction opcode");
4882 case Mips::ROL:
4883 FirstShift = Mips::SRLV;
4884 SecondShift = Mips::SLLV;
4885 break;
4886 case Mips::ROR:
4887 FirstShift = Mips::SLLV;
4888 SecondShift = Mips::SRLV;
4889 break;
4890 }
4891
4892 ATReg = getATReg(Inst.getLoc());
4893 if (!ATReg)
4894 return true;
4895
4896 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4897 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4898 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4899 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4900
4901 return false;
4902 }
4903
4904 return true;
4905}
4906
4907bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4908 MCStreamer &Out,
4909 const MCSubtargetInfo *STI) {
4910 MipsTargetStreamer &TOut = getTargetStreamer();
4911 unsigned ATReg = Mips::NoRegister;
4912 unsigned DReg = Inst.getOperand(0).getReg();
4913 unsigned SReg = Inst.getOperand(1).getReg();
4914 int64_t ImmValue = Inst.getOperand(2).getImm();
4915
4916 unsigned FirstShift = Mips::NOP;
4917 unsigned SecondShift = Mips::NOP;
4918
4919 if (hasMips32r2()) {
4920 if (Inst.getOpcode() == Mips::ROLImm) {
4921 uint64_t MaxShift = 32;
4922 uint64_t ShiftValue = ImmValue;
4923 if (ImmValue != 0)
4924 ShiftValue = MaxShift - ImmValue;
4925 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4926 return false;
4927 }
4928
4929 if (Inst.getOpcode() == Mips::RORImm) {
4930 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4931 return false;
4932 }
4933
4934 return true;
4935 }
4936
4937 if (hasMips32()) {
4938 if (ImmValue == 0) {
4939 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4940 return false;
4941 }
4942
4943 switch (Inst.getOpcode()) {
4944 default:
4945 llvm_unreachable("unexpected instruction opcode");
4946 case Mips::ROLImm:
4947 FirstShift = Mips::SLL;
4948 SecondShift = Mips::SRL;
4949 break;
4950 case Mips::RORImm:
4951 FirstShift = Mips::SRL;
4952 SecondShift = Mips::SLL;
4953 break;
4954 }
4955
4956 ATReg = getATReg(Inst.getLoc());
4957 if (!ATReg)
4958 return true;
4959
4960 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4961 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4962 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4963
4964 return false;
4965 }
4966
4967 return true;
4968}
4969
4970bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4971 const MCSubtargetInfo *STI) {
4972 MipsTargetStreamer &TOut = getTargetStreamer();
4973 unsigned ATReg = Mips::NoRegister;
4974 unsigned DReg = Inst.getOperand(0).getReg();
4975 unsigned SReg = Inst.getOperand(1).getReg();
4976 unsigned TReg = Inst.getOperand(2).getReg();
4977 unsigned TmpReg = DReg;
4978
4979 unsigned FirstShift = Mips::NOP;
4980 unsigned SecondShift = Mips::NOP;
4981
4982 if (hasMips64r2()) {
4983 if (TmpReg == SReg) {
4984 TmpReg = getATReg(Inst.getLoc());
4985 if (!TmpReg)
4986 return true;
4987 }
4988
4989 if (Inst.getOpcode() == Mips::DROL) {
4990 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4991 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4992 return false;
4993 }
4994
4995 if (Inst.getOpcode() == Mips::DROR) {
4996 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4997 return false;
4998 }
4999
5000 return true;
5001 }
5002
5003 if (hasMips64()) {
5004 switch (Inst.getOpcode()) {
5005 default:
5006 llvm_unreachable("unexpected instruction opcode");
5007 case Mips::DROL:
5008 FirstShift = Mips::DSRLV;
5009 SecondShift = Mips::DSLLV;
5010 break;
5011 case Mips::DROR:
5012 FirstShift = Mips::DSLLV;
5013 SecondShift = Mips::DSRLV;
5014 break;
5015 }
5016
5017 ATReg = getATReg(Inst.getLoc());
5018 if (!ATReg)
5019 return true;
5020
5021 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5022 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5023 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5024 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5025
5026 return false;
5027 }
5028
5029 return true;
5030}
5031
5032bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5033 MCStreamer &Out,
5034 const MCSubtargetInfo *STI) {
5035 MipsTargetStreamer &TOut = getTargetStreamer();
5036 unsigned ATReg = Mips::NoRegister;
5037 unsigned DReg = Inst.getOperand(0).getReg();
5038 unsigned SReg = Inst.getOperand(1).getReg();
5039 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5040
5041 unsigned FirstShift = Mips::NOP;
5042 unsigned SecondShift = Mips::NOP;
5043
5044 MCInst TmpInst;
5045
5046 if (hasMips64r2()) {
5047 unsigned FinalOpcode = Mips::NOP;
5048 if (ImmValue == 0)
5049 FinalOpcode = Mips::DROTR;
5050 else if (ImmValue % 32 == 0)
5051 FinalOpcode = Mips::DROTR32;
5052 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5053 if (Inst.getOpcode() == Mips::DROLImm)
5054 FinalOpcode = Mips::DROTR32;
5055 else
5056 FinalOpcode = Mips::DROTR;
5057 } else if (ImmValue >= 33) {
5058 if (Inst.getOpcode() == Mips::DROLImm)
5059 FinalOpcode = Mips::DROTR;
5060 else
5061 FinalOpcode = Mips::DROTR32;
5062 }
5063
5064 uint64_t ShiftValue = ImmValue % 32;
5065 if (Inst.getOpcode() == Mips::DROLImm)
5066 ShiftValue = (32 - ImmValue % 32) % 32;
5067
5068 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5069
5070 return false;
5071 }
5072
5073 if (hasMips64()) {
5074 if (ImmValue == 0) {
5075 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5076 return false;
5077 }
5078
5079 switch (Inst.getOpcode()) {
5080 default:
5081 llvm_unreachable("unexpected instruction opcode");
5082 case Mips::DROLImm:
5083 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5084 FirstShift = Mips::DSLL;
5085 SecondShift = Mips::DSRL32;
5086 }
5087 if (ImmValue == 32) {
5088 FirstShift = Mips::DSLL32;
5089 SecondShift = Mips::DSRL32;
5090 }
5091 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5092 FirstShift = Mips::DSLL32;
5093 SecondShift = Mips::DSRL;
5094 }
5095 break;
5096 case Mips::DRORImm:
5097 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5098 FirstShift = Mips::DSRL;
5099 SecondShift = Mips::DSLL32;
5100 }
5101 if (ImmValue == 32) {
5102 FirstShift = Mips::DSRL32;
5103 SecondShift = Mips::DSLL32;
5104 }
5105 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5106 FirstShift = Mips::DSRL32;
5107 SecondShift = Mips::DSLL;
5108 }
5109 break;
5110 }
5111
5112 ATReg = getATReg(Inst.getLoc());
5113 if (!ATReg)
5114 return true;
5115
5116 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5117 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5118 Inst.getLoc(), STI);
5119 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5120
5121 return false;
5122 }
5123
5124 return true;
5125}
5126
5127bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5128 const MCSubtargetInfo *STI) {
5129 MipsTargetStreamer &TOut = getTargetStreamer();
5130 unsigned FirstRegOp = Inst.getOperand(0).getReg();
5131 unsigned SecondRegOp = Inst.getOperand(1).getReg();
5132
5133 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5134 if (FirstRegOp != SecondRegOp)
5135 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5136 else
5137 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5138 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5139
5140 return false;
5141}
5142
5143bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5144 const MCSubtargetInfo *STI) {
5145 MipsTargetStreamer &TOut = getTargetStreamer();
5146 unsigned ATReg = Mips::NoRegister;
5147 unsigned DstReg = Inst.getOperand(0).getReg();
5148 unsigned SrcReg = Inst.getOperand(1).getReg();
5149 int32_t ImmValue = Inst.getOperand(2).getImm();
5150
5151 ATReg = getATReg(IDLoc);
5152 if (!ATReg)
5153 return true;
5154
5155 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
5156 STI);
5157
5158 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5159 SrcReg, ATReg, IDLoc, STI);
5160
5161 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5162
5163 return false;
5164}
5165
5166bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5167 const MCSubtargetInfo *STI) {
5168 MipsTargetStreamer &TOut = getTargetStreamer();
5169 unsigned ATReg = Mips::NoRegister;
5170 unsigned DstReg = Inst.getOperand(0).getReg();
5171 unsigned SrcReg = Inst.getOperand(1).getReg();
5172 unsigned TmpReg = Inst.getOperand(2).getReg();
5173
5174 ATReg = getATReg(Inst.getLoc());
5175 if (!ATReg)
5176 return true;
5177
5178 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5179 SrcReg, TmpReg, IDLoc, STI);
5180
5181 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5182
5183 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5184 DstReg, DstReg, 0x1F, IDLoc, STI);
5185
5186 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5187
5188 if (useTraps()) {
5189 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5190 } else {
5192 MCSymbol * BrTarget = Context.createTempSymbol();
5193 MCOperand LabelOp =
5195
5196 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5197 if (AssemblerOptions.back()->isReorder())
5198 TOut.emitNop(IDLoc, STI);
5199 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5200
5201 TOut.getStreamer().emitLabel(BrTarget);
5202 }
5203 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5204
5205 return false;
5206}
5207
5208bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5209 const MCSubtargetInfo *STI) {
5210 MipsTargetStreamer &TOut = getTargetStreamer();
5211 unsigned ATReg = Mips::NoRegister;
5212 unsigned DstReg = Inst.getOperand(0).getReg();
5213 unsigned SrcReg = Inst.getOperand(1).getReg();
5214 unsigned TmpReg = Inst.getOperand(2).getReg();
5215
5216 ATReg = getATReg(IDLoc);
5217 if (!ATReg)
5218 return true;
5219
5220 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5221 SrcReg, TmpReg, IDLoc, STI);
5222
5223 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5224 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5225 if (useTraps()) {
5226 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5227 } else {
5228 MCContext & Context = TOut.