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