[InstCombine] Signed saturation patterns
[llvm-core.git] / lib / Target / Mips / AsmParser / MipsAsmParser.cpp
blob21d0df74d458a0a78770994606552c448fe5c1da
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 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/MipsABIFlagsSection.h"
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsBaseInfo.h"
12 #include "MCTargetDesc/MipsMCExpr.h"
13 #include "MCTargetDesc/MipsMCTargetDesc.h"
14 #include "MipsTargetStreamer.h"
15 #include "TargetInfo/MipsTargetInfo.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCAsmParser.h"
31 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
32 #include "llvm/MC/MCParser/MCAsmParserUtils.h"
33 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
35 #include "llvm/MC/MCSectionELF.h"
36 #include "llvm/MC/MCStreamer.h"
37 #include "llvm/MC/MCSubtargetInfo.h"
38 #include "llvm/MC/MCSymbol.h"
39 #include "llvm/MC/MCSymbolELF.h"
40 #include "llvm/MC/MCValue.h"
41 #include "llvm/MC/SubtargetFeature.h"
42 #include "llvm/Support/Alignment.h"
43 #include "llvm/Support/Casting.h"
44 #include "llvm/Support/CommandLine.h"
45 #include "llvm/Support/Compiler.h"
46 #include "llvm/Support/Debug.h"
47 #include "llvm/Support/ErrorHandling.h"
48 #include "llvm/Support/MathExtras.h"
49 #include "llvm/Support/SMLoc.h"
50 #include "llvm/Support/SourceMgr.h"
51 #include "llvm/Support/TargetRegistry.h"
52 #include "llvm/Support/raw_ostream.h"
53 #include <algorithm>
54 #include <cassert>
55 #include <cstdint>
56 #include <memory>
57 #include <string>
58 #include <utility>
60 using namespace llvm;
62 #define DEBUG_TYPE "mips-asm-parser"
64 namespace llvm {
66 class MCInstrInfo;
68 } // end namespace llvm
70 extern cl::opt<bool> EmitJalrReloc;
72 namespace {
74 class MipsAssemblerOptions {
75 public:
76 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
78 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
85 unsigned getATRegIndex() const { return ATReg; }
86 bool setATRegIndex(unsigned Reg) {
87 if (Reg > 31)
88 return false;
90 ATReg = Reg;
91 return true;
94 bool isReorder() const { return Reorder; }
95 void setReorder() { Reorder = true; }
96 void setNoReorder() { Reorder = false; }
98 bool isMacro() const { return Macro; }
99 void setMacro() { Macro = true; }
100 void setNoMacro() { Macro = false; }
102 const FeatureBitset &getFeatures() const { return Features; }
103 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
105 // Set of features that are either architecture features or referenced
106 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
107 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
108 // The reason we need this mask is explained in the selectArch function.
109 // FIXME: Ideally we would like TableGen to generate this information.
110 static const FeatureBitset AllArchRelatedMask;
112 private:
113 unsigned ATReg = 1;
114 bool Reorder = true;
115 bool Macro = true;
116 FeatureBitset Features;
119 } // end anonymous namespace
121 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
132 namespace {
134 class MipsAsmParser : public MCTargetAsmParser {
135 MipsTargetStreamer &getTargetStreamer() {
136 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
137 return static_cast<MipsTargetStreamer &>(TS);
140 MipsABIInfo ABI;
141 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
142 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
143 // nullptr, which indicates that no function is currently
144 // selected. This usually happens after an '.end func'
145 // directive.
146 bool IsLittleEndian;
147 bool IsPicEnabled;
148 bool IsCpRestoreSet;
149 int CpRestoreOffset;
150 unsigned GPReg;
151 unsigned CpSaveLocation;
152 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
153 bool CpSaveLocationIsRegister;
155 // Map of register aliases created via the .set directive.
156 StringMap<AsmToken> RegisterSets;
158 // Print a warning along with its fix-it message at the given range.
159 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
160 SMRange Range, bool ShowColors = true);
162 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
164 #define GET_ASSEMBLER_HEADER
165 #include "MipsGenAsmMatcher.inc"
167 unsigned
168 checkEarlyTargetMatchPredicate(MCInst &Inst,
169 const OperandVector &Operands) override;
170 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
172 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
173 OperandVector &Operands, MCStreamer &Out,
174 uint64_t &ErrorInfo,
175 bool MatchingInlineAsm) override;
177 /// Parse a register as used in CFI directives
178 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
180 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
182 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
184 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
186 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
187 SMLoc NameLoc, OperandVector &Operands) override;
189 bool ParseDirective(AsmToken DirectiveID) override;
191 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
192 OperandMatchResultTy
193 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
194 StringRef Identifier, SMLoc S);
195 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
196 const AsmToken &Token,
197 SMLoc S);
198 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
199 SMLoc S);
200 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
201 OperandMatchResultTy parseImm(OperandVector &Operands);
202 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
203 OperandMatchResultTy parseInvNum(OperandVector &Operands);
204 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
206 bool searchSymbolAlias(OperandVector &Operands);
208 bool parseOperand(OperandVector &, StringRef Mnemonic);
210 enum MacroExpanderResultTy {
211 MER_NotAMacro,
212 MER_Success,
213 MER_Fail,
216 // Expands assembly pseudo instructions.
217 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
218 MCStreamer &Out,
219 const MCSubtargetInfo *STI);
221 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
222 const MCSubtargetInfo *STI);
224 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
225 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
226 MCStreamer &Out, const MCSubtargetInfo *STI);
228 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
229 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
230 MCStreamer &Out, const MCSubtargetInfo *STI);
232 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
234 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
235 MCStreamer &Out, const MCSubtargetInfo *STI);
237 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
238 const MCSubtargetInfo *STI);
239 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
240 const MCSubtargetInfo *STI);
241 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
242 const MCSubtargetInfo *STI);
243 bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
244 MCStreamer &Out, const MCSubtargetInfo *STI);
246 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
247 const MCOperand &Offset, bool Is32BitAddress,
248 SMLoc IDLoc, MCStreamer &Out,
249 const MCSubtargetInfo *STI);
251 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
252 const MCSubtargetInfo *STI);
254 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI, bool IsLoad);
257 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI);
260 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI);
263 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264 const MCSubtargetInfo *STI);
266 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
267 const MCSubtargetInfo *STI);
269 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270 const MCSubtargetInfo *STI, const bool IsMips64,
271 const bool Signed);
273 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
274 MCStreamer &Out, const MCSubtargetInfo *STI);
276 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI);
279 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
282 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
285 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
288 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289 const MCSubtargetInfo *STI);
291 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292 const MCSubtargetInfo *STI);
294 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
295 MCStreamer &Out, const MCSubtargetInfo *STI);
296 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
298 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
300 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301 const MCSubtargetInfo *STI);
303 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304 const MCSubtargetInfo *STI);
306 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
307 const MCSubtargetInfo *STI);
309 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310 const MCSubtargetInfo *STI);
312 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI);
315 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316 const MCSubtargetInfo *STI);
318 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319 const MCSubtargetInfo *STI, bool IsLoad);
321 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322 const MCSubtargetInfo *STI);
324 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325 const MCSubtargetInfo *STI);
327 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
328 const MCSubtargetInfo *STI);
330 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
331 const MCSubtargetInfo *STI);
333 bool reportParseError(Twine ErrorMsg);
334 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
336 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
338 bool isEvaluated(const MCExpr *Expr);
339 bool parseSetMips0Directive();
340 bool parseSetArchDirective();
341 bool parseSetFeature(uint64_t Feature);
342 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
343 bool parseDirectiveCpLoad(SMLoc Loc);
344 bool parseDirectiveCpLocal(SMLoc Loc);
345 bool parseDirectiveCpRestore(SMLoc Loc);
346 bool parseDirectiveCPSetup();
347 bool parseDirectiveCPReturn();
348 bool parseDirectiveNaN();
349 bool parseDirectiveSet();
350 bool parseDirectiveOption();
351 bool parseInsnDirective();
352 bool parseRSectionDirective(StringRef Section);
353 bool parseSSectionDirective(StringRef Section, unsigned Type);
355 bool parseSetAtDirective();
356 bool parseSetNoAtDirective();
357 bool parseSetMacroDirective();
358 bool parseSetNoMacroDirective();
359 bool parseSetMsaDirective();
360 bool parseSetNoMsaDirective();
361 bool parseSetNoDspDirective();
362 bool parseSetReorderDirective();
363 bool parseSetNoReorderDirective();
364 bool parseSetMips16Directive();
365 bool parseSetNoMips16Directive();
366 bool parseSetFpDirective();
367 bool parseSetOddSPRegDirective();
368 bool parseSetNoOddSPRegDirective();
369 bool parseSetPopDirective();
370 bool parseSetPushDirective();
371 bool parseSetSoftFloatDirective();
372 bool parseSetHardFloatDirective();
373 bool parseSetMtDirective();
374 bool parseSetNoMtDirective();
375 bool parseSetNoCRCDirective();
376 bool parseSetNoVirtDirective();
377 bool parseSetNoGINVDirective();
379 bool parseSetAssignment();
381 bool parseDirectiveGpWord();
382 bool parseDirectiveGpDWord();
383 bool parseDirectiveDtpRelWord();
384 bool parseDirectiveDtpRelDWord();
385 bool parseDirectiveTpRelWord();
386 bool parseDirectiveTpRelDWord();
387 bool parseDirectiveModule();
388 bool parseDirectiveModuleFP();
389 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
390 StringRef Directive);
392 bool parseInternalDirectiveReallowModule();
394 bool eatComma(StringRef ErrorStr);
396 int matchCPURegisterName(StringRef Symbol);
398 int matchHWRegsRegisterName(StringRef Symbol);
400 int matchFPURegisterName(StringRef Name);
402 int matchFCCRegisterName(StringRef Name);
404 int matchACRegisterName(StringRef Name);
406 int matchMSA128RegisterName(StringRef Name);
408 int matchMSA128CtrlRegisterName(StringRef Name);
410 unsigned getReg(int RC, int RegNo);
412 /// Returns the internal register number for the current AT. Also checks if
413 /// the current AT is unavailable (set to $0) and gives an error if it is.
414 /// This should be used in pseudo-instruction expansions which need AT.
415 unsigned getATReg(SMLoc Loc);
417 bool canUseATReg();
419 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
420 const MCSubtargetInfo *STI);
422 // Helper function that checks if the value of a vector index is within the
423 // boundaries of accepted values for each RegisterKind
424 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
425 bool validateMSAIndex(int Val, int RegKind);
427 // Selects a new architecture by updating the FeatureBits with the necessary
428 // info including implied dependencies.
429 // Internally, it clears all the feature bits related to *any* architecture
430 // and selects the new one using the ToggleFeature functionality of the
431 // MCSubtargetInfo object that handles implied dependencies. The reason we
432 // clear all the arch related bits manually is because ToggleFeature only
433 // clears the features that imply the feature being cleared and not the
434 // features implied by the feature being cleared. This is easier to see
435 // with an example:
436 // --------------------------------------------------
437 // | Feature | Implies |
438 // | -------------------------------------------------|
439 // | FeatureMips1 | None |
440 // | FeatureMips2 | FeatureMips1 |
441 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
442 // | FeatureMips4 | FeatureMips3 |
443 // | ... | |
444 // --------------------------------------------------
446 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
447 // FeatureMipsGP64 | FeatureMips1)
448 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
449 void selectArch(StringRef ArchFeature) {
450 MCSubtargetInfo &STI = copySTI();
451 FeatureBitset FeatureBits = STI.getFeatureBits();
452 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
453 STI.setFeatureBits(FeatureBits);
454 setAvailableFeatures(
455 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
456 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
459 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
460 if (!(getSTI().getFeatureBits()[Feature])) {
461 MCSubtargetInfo &STI = copySTI();
462 setAvailableFeatures(
463 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
464 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
468 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
469 if (getSTI().getFeatureBits()[Feature]) {
470 MCSubtargetInfo &STI = copySTI();
471 setAvailableFeatures(
472 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
473 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
477 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
478 setFeatureBits(Feature, FeatureString);
479 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
482 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
483 clearFeatureBits(Feature, FeatureString);
484 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
487 public:
488 enum MipsMatchResultTy {
489 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
490 Match_RequiresDifferentOperands,
491 Match_RequiresNoZeroRegister,
492 Match_RequiresSameSrcAndDst,
493 Match_NoFCCRegisterForCurrentISA,
494 Match_NonZeroOperandForSync,
495 Match_NonZeroOperandForMTCX,
496 Match_RequiresPosSizeRange0_32,
497 Match_RequiresPosSizeRange33_64,
498 Match_RequiresPosSizeUImm6,
499 #define GET_OPERAND_DIAGNOSTIC_TYPES
500 #include "MipsGenAsmMatcher.inc"
501 #undef GET_OPERAND_DIAGNOSTIC_TYPES
504 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
505 const MCInstrInfo &MII, const MCTargetOptions &Options)
506 : MCTargetAsmParser(Options, sti, MII),
507 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
508 sti.getCPU(), Options)) {
509 MCAsmParserExtension::Initialize(parser);
511 parser.addAliasForDirective(".asciiz", ".asciz");
512 parser.addAliasForDirective(".hword", ".2byte");
513 parser.addAliasForDirective(".word", ".4byte");
514 parser.addAliasForDirective(".dword", ".8byte");
516 // Initialize the set of available features.
517 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
519 // Remember the initial assembler options. The user can not modify these.
520 AssemblerOptions.push_back(
521 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
523 // Create an assembler options environment for the user to modify.
524 AssemblerOptions.push_back(
525 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
527 getTargetStreamer().updateABIInfo(*this);
529 if (!isABI_O32() && !useOddSPReg() != 0)
530 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
532 CurrentFn = nullptr;
534 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
536 IsCpRestoreSet = false;
537 CpRestoreOffset = -1;
538 GPReg = ABI.GetGlobalPtr();
540 const Triple &TheTriple = sti.getTargetTriple();
541 IsLittleEndian = TheTriple.isLittleEndian();
543 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
544 report_fatal_error("microMIPS64R6 is not supported", false);
546 if (!isABI_O32() && inMicroMipsMode())
547 report_fatal_error("microMIPS64 is not supported", false);
550 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
551 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
553 bool isGP64bit() const {
554 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
557 bool isFP64bit() const {
558 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
561 const MipsABIInfo &getABI() const { return ABI; }
562 bool isABI_N32() const { return ABI.IsN32(); }
563 bool isABI_N64() const { return ABI.IsN64(); }
564 bool isABI_O32() const { return ABI.IsO32(); }
565 bool isABI_FPXX() const {
566 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
569 bool useOddSPReg() const {
570 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
573 bool inMicroMipsMode() const {
574 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
577 bool hasMips1() const {
578 return getSTI().getFeatureBits()[Mips::FeatureMips1];
581 bool hasMips2() const {
582 return getSTI().getFeatureBits()[Mips::FeatureMips2];
585 bool hasMips3() const {
586 return getSTI().getFeatureBits()[Mips::FeatureMips3];
589 bool hasMips4() const {
590 return getSTI().getFeatureBits()[Mips::FeatureMips4];
593 bool hasMips5() const {
594 return getSTI().getFeatureBits()[Mips::FeatureMips5];
597 bool hasMips32() const {
598 return getSTI().getFeatureBits()[Mips::FeatureMips32];
601 bool hasMips64() const {
602 return getSTI().getFeatureBits()[Mips::FeatureMips64];
605 bool hasMips32r2() const {
606 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
609 bool hasMips64r2() const {
610 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
613 bool hasMips32r3() const {
614 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
617 bool hasMips64r3() const {
618 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
621 bool hasMips32r5() const {
622 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
625 bool hasMips64r5() const {
626 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
629 bool hasMips32r6() const {
630 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
633 bool hasMips64r6() const {
634 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
637 bool hasDSP() const {
638 return getSTI().getFeatureBits()[Mips::FeatureDSP];
641 bool hasDSPR2() const {
642 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
645 bool hasDSPR3() const {
646 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
649 bool hasMSA() const {
650 return getSTI().getFeatureBits()[Mips::FeatureMSA];
653 bool hasCnMips() const {
654 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
657 bool inPicMode() {
658 return IsPicEnabled;
661 bool inMips16Mode() const {
662 return getSTI().getFeatureBits()[Mips::FeatureMips16];
665 bool useTraps() const {
666 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
669 bool useSoftFloat() const {
670 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
672 bool hasMT() const {
673 return getSTI().getFeatureBits()[Mips::FeatureMT];
676 bool hasCRC() const {
677 return getSTI().getFeatureBits()[Mips::FeatureCRC];
680 bool hasVirt() const {
681 return getSTI().getFeatureBits()[Mips::FeatureVirt];
684 bool hasGINV() const {
685 return getSTI().getFeatureBits()[Mips::FeatureGINV];
688 /// Warn if RegIndex is the same as the current AT.
689 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
691 void warnIfNoMacro(SMLoc Loc);
693 bool isLittle() const { return IsLittleEndian; }
695 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
696 AsmToken::TokenKind OperatorToken,
697 MCContext &Ctx) override {
698 switch(OperatorToken) {
699 default:
700 llvm_unreachable("Unknown token");
701 return nullptr;
702 case AsmToken::PercentCall16:
703 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
704 case AsmToken::PercentCall_Hi:
705 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
706 case AsmToken::PercentCall_Lo:
707 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
708 case AsmToken::PercentDtprel_Hi:
709 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
710 case AsmToken::PercentDtprel_Lo:
711 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
712 case AsmToken::PercentGot:
713 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
714 case AsmToken::PercentGot_Disp:
715 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
716 case AsmToken::PercentGot_Hi:
717 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
718 case AsmToken::PercentGot_Lo:
719 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
720 case AsmToken::PercentGot_Ofst:
721 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
722 case AsmToken::PercentGot_Page:
723 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
724 case AsmToken::PercentGottprel:
725 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
726 case AsmToken::PercentGp_Rel:
727 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
728 case AsmToken::PercentHi:
729 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
730 case AsmToken::PercentHigher:
731 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
732 case AsmToken::PercentHighest:
733 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
734 case AsmToken::PercentLo:
735 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
736 case AsmToken::PercentNeg:
737 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
738 case AsmToken::PercentPcrel_Hi:
739 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
740 case AsmToken::PercentPcrel_Lo:
741 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
742 case AsmToken::PercentTlsgd:
743 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
744 case AsmToken::PercentTlsldm:
745 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
746 case AsmToken::PercentTprel_Hi:
747 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
748 case AsmToken::PercentTprel_Lo:
749 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
754 /// MipsOperand - Instances of this class represent a parsed Mips machine
755 /// instruction.
756 class MipsOperand : public MCParsedAsmOperand {
757 public:
758 /// Broad categories of register classes
759 /// The exact class is finalized by the render method.
760 enum RegKind {
761 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
762 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
763 /// isFP64bit())
764 RegKind_FCC = 4, /// FCC
765 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
766 RegKind_MSACtrl = 16, /// MSA control registers
767 RegKind_COP2 = 32, /// COP2
768 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
769 /// context).
770 RegKind_CCR = 128, /// CCR
771 RegKind_HWRegs = 256, /// HWRegs
772 RegKind_COP3 = 512, /// COP3
773 RegKind_COP0 = 1024, /// COP0
774 /// Potentially any (e.g. $1)
775 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
776 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
777 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
780 private:
781 enum KindTy {
782 k_Immediate, /// An immediate (possibly involving symbol references)
783 k_Memory, /// Base + Offset Memory Address
784 k_RegisterIndex, /// A register index in one or more RegKind.
785 k_Token, /// A simple token
786 k_RegList, /// A physical register list
787 } Kind;
789 public:
790 MipsOperand(KindTy K, MipsAsmParser &Parser)
791 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
793 ~MipsOperand() override {
794 switch (Kind) {
795 case k_Memory:
796 delete Mem.Base;
797 break;
798 case k_RegList:
799 delete RegList.List;
800 break;
801 case k_Immediate:
802 case k_RegisterIndex:
803 case k_Token:
804 break;
808 private:
809 /// For diagnostics, and checking the assembler temporary
810 MipsAsmParser &AsmParser;
812 struct Token {
813 const char *Data;
814 unsigned Length;
817 struct RegIdxOp {
818 unsigned Index; /// Index into the register class
819 RegKind Kind; /// Bitfield of the kinds it could possibly be
820 struct Token Tok; /// The input token this operand originated from.
821 const MCRegisterInfo *RegInfo;
824 struct ImmOp {
825 const MCExpr *Val;
828 struct MemOp {
829 MipsOperand *Base;
830 const MCExpr *Off;
833 struct RegListOp {
834 SmallVector<unsigned, 10> *List;
837 union {
838 struct Token Tok;
839 struct RegIdxOp RegIdx;
840 struct ImmOp Imm;
841 struct MemOp Mem;
842 struct RegListOp RegList;
845 SMLoc StartLoc, EndLoc;
847 /// Internal constructor for register kinds
848 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
849 RegKind RegKind,
850 const MCRegisterInfo *RegInfo,
851 SMLoc S, SMLoc E,
852 MipsAsmParser &Parser) {
853 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
854 Op->RegIdx.Index = Index;
855 Op->RegIdx.RegInfo = RegInfo;
856 Op->RegIdx.Kind = RegKind;
857 Op->RegIdx.Tok.Data = Str.data();
858 Op->RegIdx.Tok.Length = Str.size();
859 Op->StartLoc = S;
860 Op->EndLoc = E;
861 return Op;
864 public:
865 /// Coerce the register to GPR32 and return the real register for the current
866 /// target.
867 unsigned getGPR32Reg() const {
868 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
869 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
870 unsigned ClassID = Mips::GPR32RegClassID;
871 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
874 /// Coerce the register to GPR32 and return the real register for the current
875 /// target.
876 unsigned getGPRMM16Reg() const {
877 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
878 unsigned ClassID = Mips::GPR32RegClassID;
879 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
882 /// Coerce the register to GPR64 and return the real register for the current
883 /// target.
884 unsigned getGPR64Reg() const {
885 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
886 unsigned ClassID = Mips::GPR64RegClassID;
887 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
890 private:
891 /// Coerce the register to AFGR64 and return the real register for the current
892 /// target.
893 unsigned getAFGR64Reg() const {
894 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
895 if (RegIdx.Index % 2 != 0)
896 AsmParser.Warning(StartLoc, "Float register should be even.");
897 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
898 .getRegister(RegIdx.Index / 2);
901 /// Coerce the register to FGR64 and return the real register for the current
902 /// target.
903 unsigned getFGR64Reg() const {
904 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
905 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
906 .getRegister(RegIdx.Index);
909 /// Coerce the register to FGR32 and return the real register for the current
910 /// target.
911 unsigned getFGR32Reg() const {
912 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
913 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
914 .getRegister(RegIdx.Index);
917 /// Coerce the register to FCC and return the real register for the current
918 /// target.
919 unsigned getFCCReg() const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
921 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
922 .getRegister(RegIdx.Index);
925 /// Coerce the register to MSA128 and return the real register for the current
926 /// target.
927 unsigned getMSA128Reg() const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
929 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
930 // identical
931 unsigned ClassID = Mips::MSA128BRegClassID;
932 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
935 /// Coerce the register to MSACtrl and return the real register for the
936 /// current target.
937 unsigned getMSACtrlReg() const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
939 unsigned ClassID = Mips::MSACtrlRegClassID;
940 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
943 /// Coerce the register to COP0 and return the real register for the
944 /// current target.
945 unsigned getCOP0Reg() const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
947 unsigned ClassID = Mips::COP0RegClassID;
948 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
951 /// Coerce the register to COP2 and return the real register for the
952 /// current target.
953 unsigned getCOP2Reg() const {
954 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
955 unsigned ClassID = Mips::COP2RegClassID;
956 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
959 /// Coerce the register to COP3 and return the real register for the
960 /// current target.
961 unsigned getCOP3Reg() const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
963 unsigned ClassID = Mips::COP3RegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
967 /// Coerce the register to ACC64DSP and return the real register for the
968 /// current target.
969 unsigned getACC64DSPReg() const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
971 unsigned ClassID = Mips::ACC64DSPRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
975 /// Coerce the register to HI32DSP and return the real register for the
976 /// current target.
977 unsigned getHI32DSPReg() const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
979 unsigned ClassID = Mips::HI32DSPRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
983 /// Coerce the register to LO32DSP and return the real register for the
984 /// current target.
985 unsigned getLO32DSPReg() const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
987 unsigned ClassID = Mips::LO32DSPRegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
991 /// Coerce the register to CCR and return the real register for the
992 /// current target.
993 unsigned getCCRReg() const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
995 unsigned ClassID = Mips::CCRRegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
999 /// Coerce the register to HWRegs and return the real register for the
1000 /// current target.
1001 unsigned getHWRegsReg() const {
1002 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
1003 unsigned ClassID = Mips::HWRegsRegClassID;
1004 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1007 public:
1008 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1009 // Add as immediate when possible. Null MCExpr = 0.
1010 if (!Expr)
1011 Inst.addOperand(MCOperand::createImm(0));
1012 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1013 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1014 else
1015 Inst.addOperand(MCOperand::createExpr(Expr));
1018 void addRegOperands(MCInst &Inst, unsigned N) const {
1019 llvm_unreachable("Use a custom parser instead");
1022 /// Render the operand to an MCInst as a GPR32
1023 /// Asserts if the wrong number of operands are requested, or the operand
1024 /// is not a k_RegisterIndex compatible with RegKind_GPR
1025 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1026 assert(N == 1 && "Invalid number of operands!");
1027 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1030 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1031 assert(N == 1 && "Invalid number of operands!");
1032 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1035 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1036 assert(N == 1 && "Invalid number of operands!");
1037 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1040 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1041 assert(N == 1 && "Invalid number of operands!");
1042 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1045 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1046 assert(N == 1 && "Invalid number of operands!");
1047 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1050 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1051 assert(N == 1 && "Invalid number of operands!");
1052 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1055 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1056 assert(N == 1 && "Invalid number of operands!");
1057 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1060 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1061 unsigned N) const {
1062 assert(N == 1 && "Invalid number of operands!");
1063 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1066 /// Render the operand to an MCInst as a GPR64
1067 /// Asserts if the wrong number of operands are requested, or the operand
1068 /// is not a k_RegisterIndex compatible with RegKind_GPR
1069 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1070 assert(N == 1 && "Invalid number of operands!");
1071 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1074 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1075 assert(N == 1 && "Invalid number of operands!");
1076 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1079 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1080 assert(N == 1 && "Invalid number of operands!");
1081 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1084 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1085 assert(N == 1 && "Invalid number of operands!");
1086 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1089 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1090 assert(N == 1 && "Invalid number of operands!");
1091 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1094 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1095 assert(N == 1 && "Invalid number of operands!");
1096 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1097 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1098 // FIXME: This should propagate failure up to parseStatement.
1099 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1100 AsmParser.getParser().printError(
1101 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1102 "registers");
1105 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1106 assert(N == 1 && "Invalid number of operands!");
1107 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1108 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1109 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1110 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1111 "registers");
1114 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1115 assert(N == 1 && "Invalid number of operands!");
1116 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1119 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1120 assert(N == 1 && "Invalid number of operands!");
1121 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1124 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1125 assert(N == 1 && "Invalid number of operands!");
1126 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1129 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1130 assert(N == 1 && "Invalid number of operands!");
1131 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1134 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1135 assert(N == 1 && "Invalid number of operands!");
1136 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1139 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1140 assert(N == 1 && "Invalid number of operands!");
1141 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1144 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1145 assert(N == 1 && "Invalid number of operands!");
1146 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1149 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1150 assert(N == 1 && "Invalid number of operands!");
1151 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1154 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1155 assert(N == 1 && "Invalid number of operands!");
1156 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1159 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1160 assert(N == 1 && "Invalid number of operands!");
1161 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1164 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1165 assert(N == 1 && "Invalid number of operands!");
1166 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1169 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1170 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1171 assert(N == 1 && "Invalid number of operands!");
1172 uint64_t Imm = getConstantImm() - Offset;
1173 Imm &= (1ULL << Bits) - 1;
1174 Imm += Offset;
1175 Imm += AdjustOffset;
1176 Inst.addOperand(MCOperand::createImm(Imm));
1179 template <unsigned Bits>
1180 void addSImmOperands(MCInst &Inst, unsigned N) const {
1181 if (isImm() && !isConstantImm()) {
1182 addExpr(Inst, getImm());
1183 return;
1185 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1188 template <unsigned Bits>
1189 void addUImmOperands(MCInst &Inst, unsigned N) const {
1190 if (isImm() && !isConstantImm()) {
1191 addExpr(Inst, getImm());
1192 return;
1194 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1197 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1198 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1199 assert(N == 1 && "Invalid number of operands!");
1200 int64_t Imm = getConstantImm() - Offset;
1201 Imm = SignExtend64<Bits>(Imm);
1202 Imm += Offset;
1203 Imm += AdjustOffset;
1204 Inst.addOperand(MCOperand::createImm(Imm));
1207 void addImmOperands(MCInst &Inst, unsigned N) const {
1208 assert(N == 1 && "Invalid number of operands!");
1209 const MCExpr *Expr = getImm();
1210 addExpr(Inst, Expr);
1213 void addMemOperands(MCInst &Inst, unsigned N) const {
1214 assert(N == 2 && "Invalid number of operands!");
1216 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1217 ? getMemBase()->getGPR64Reg()
1218 : getMemBase()->getGPR32Reg()));
1220 const MCExpr *Expr = getMemOff();
1221 addExpr(Inst, Expr);
1224 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1225 assert(N == 2 && "Invalid number of operands!");
1227 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1229 const MCExpr *Expr = getMemOff();
1230 addExpr(Inst, Expr);
1233 void addRegListOperands(MCInst &Inst, unsigned N) const {
1234 assert(N == 1 && "Invalid number of operands!");
1236 for (auto RegNo : getRegList())
1237 Inst.addOperand(MCOperand::createReg(RegNo));
1240 bool isReg() const override {
1241 // As a special case until we sort out the definition of div/divu, accept
1242 // $0/$zero here so that MCK_ZERO works correctly.
1243 return isGPRAsmReg() && RegIdx.Index == 0;
1246 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1247 bool isImm() const override { return Kind == k_Immediate; }
1249 bool isConstantImm() const {
1250 int64_t Res;
1251 return isImm() && getImm()->evaluateAsAbsolute(Res);
1254 bool isConstantImmz() const {
1255 return isConstantImm() && getConstantImm() == 0;
1258 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1259 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1262 template <unsigned Bits> bool isSImm() const {
1263 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1266 template <unsigned Bits> bool isUImm() const {
1267 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1270 template <unsigned Bits> bool isAnyImm() const {
1271 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1272 isUInt<Bits>(getConstantImm()))
1273 : isImm();
1276 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1277 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1280 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1281 return isConstantImm() && getConstantImm() >= Bottom &&
1282 getConstantImm() <= Top;
1285 bool isToken() const override {
1286 // Note: It's not possible to pretend that other operand kinds are tokens.
1287 // The matcher emitter checks tokens first.
1288 return Kind == k_Token;
1291 bool isMem() const override { return Kind == k_Memory; }
1293 bool isConstantMemOff() const {
1294 return isMem() && isa<MCConstantExpr>(getMemOff());
1297 // Allow relocation operators.
1298 // FIXME: This predicate and others need to look through binary expressions
1299 // and determine whether a Value is a constant or not.
1300 template <unsigned Bits, unsigned ShiftAmount = 0>
1301 bool isMemWithSimmOffset() const {
1302 if (!isMem())
1303 return false;
1304 if (!getMemBase()->isGPRAsmReg())
1305 return false;
1306 if (isa<MCTargetExpr>(getMemOff()) ||
1307 (isConstantMemOff() &&
1308 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1309 return true;
1310 MCValue Res;
1311 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1312 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1315 bool isMemWithPtrSizeOffset() const {
1316 if (!isMem())
1317 return false;
1318 if (!getMemBase()->isGPRAsmReg())
1319 return false;
1320 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1321 if (isa<MCTargetExpr>(getMemOff()) ||
1322 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1323 return true;
1324 MCValue Res;
1325 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1326 return IsReloc && isIntN(PtrBits, Res.getConstant());
1329 bool isMemWithGRPMM16Base() const {
1330 return isMem() && getMemBase()->isMM16AsmReg();
1333 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1334 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1335 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1338 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1339 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1340 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1341 && (getMemBase()->getGPR32Reg() == Mips::SP);
1344 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1345 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1346 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1347 && (getMemBase()->getGPR32Reg() == Mips::GP);
1350 template <unsigned Bits, unsigned ShiftLeftAmount>
1351 bool isScaledUImm() const {
1352 return isConstantImm() &&
1353 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1356 template <unsigned Bits, unsigned ShiftLeftAmount>
1357 bool isScaledSImm() const {
1358 if (isConstantImm() &&
1359 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1360 return true;
1361 // Operand can also be a symbol or symbol plus
1362 // offset in case of relocations.
1363 if (Kind != k_Immediate)
1364 return false;
1365 MCValue Res;
1366 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1367 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1370 bool isRegList16() const {
1371 if (!isRegList())
1372 return false;
1374 int Size = RegList.List->size();
1375 if (Size < 2 || Size > 5)
1376 return false;
1378 unsigned R0 = RegList.List->front();
1379 unsigned R1 = RegList.List->back();
1380 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1381 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1382 return false;
1384 int PrevReg = *RegList.List->begin();
1385 for (int i = 1; i < Size - 1; i++) {
1386 int Reg = (*(RegList.List))[i];
1387 if ( Reg != PrevReg + 1)
1388 return false;
1389 PrevReg = Reg;
1392 return true;
1395 bool isInvNum() const { return Kind == k_Immediate; }
1397 bool isLSAImm() const {
1398 if (!isConstantImm())
1399 return false;
1400 int64_t Val = getConstantImm();
1401 return 1 <= Val && Val <= 4;
1404 bool isRegList() const { return Kind == k_RegList; }
1406 StringRef getToken() const {
1407 assert(Kind == k_Token && "Invalid access!");
1408 return StringRef(Tok.Data, Tok.Length);
1411 unsigned getReg() const override {
1412 // As a special case until we sort out the definition of div/divu, accept
1413 // $0/$zero here so that MCK_ZERO works correctly.
1414 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1415 RegIdx.Kind & RegKind_GPR)
1416 return getGPR32Reg(); // FIXME: GPR64 too
1418 llvm_unreachable("Invalid access!");
1419 return 0;
1422 const MCExpr *getImm() const {
1423 assert((Kind == k_Immediate) && "Invalid access!");
1424 return Imm.Val;
1427 int64_t getConstantImm() const {
1428 const MCExpr *Val = getImm();
1429 int64_t Value = 0;
1430 (void)Val->evaluateAsAbsolute(Value);
1431 return Value;
1434 MipsOperand *getMemBase() const {
1435 assert((Kind == k_Memory) && "Invalid access!");
1436 return Mem.Base;
1439 const MCExpr *getMemOff() const {
1440 assert((Kind == k_Memory) && "Invalid access!");
1441 return Mem.Off;
1444 int64_t getConstantMemOff() const {
1445 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1448 const SmallVectorImpl<unsigned> &getRegList() const {
1449 assert((Kind == k_RegList) && "Invalid access!");
1450 return *(RegList.List);
1453 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1454 MipsAsmParser &Parser) {
1455 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1456 Op->Tok.Data = Str.data();
1457 Op->Tok.Length = Str.size();
1458 Op->StartLoc = S;
1459 Op->EndLoc = S;
1460 return Op;
1463 /// Create a numeric register (e.g. $1). The exact register remains
1464 /// unresolved until an instruction successfully matches
1465 static std::unique_ptr<MipsOperand>
1466 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1467 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1468 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1469 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1472 /// Create a register that is definitely a GPR.
1473 /// This is typically only used for named registers such as $gp.
1474 static std::unique_ptr<MipsOperand>
1475 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1476 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1477 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1480 /// Create a register that is definitely a FGR.
1481 /// This is typically only used for named registers such as $f0.
1482 static std::unique_ptr<MipsOperand>
1483 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1484 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1485 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1488 /// Create a register that is definitely a HWReg.
1489 /// This is typically only used for named registers such as $hwr_cpunum.
1490 static std::unique_ptr<MipsOperand>
1491 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1492 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1493 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1496 /// Create a register that is definitely an FCC.
1497 /// This is typically only used for named registers such as $fcc0.
1498 static std::unique_ptr<MipsOperand>
1499 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1500 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1501 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1504 /// Create a register that is definitely an ACC.
1505 /// This is typically only used for named registers such as $ac0.
1506 static std::unique_ptr<MipsOperand>
1507 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1508 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1509 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1512 /// Create a register that is definitely an MSA128.
1513 /// This is typically only used for named registers such as $w0.
1514 static std::unique_ptr<MipsOperand>
1515 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1516 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1517 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1520 /// Create a register that is definitely an MSACtrl.
1521 /// This is typically only used for named registers such as $msaaccess.
1522 static std::unique_ptr<MipsOperand>
1523 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1524 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1525 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1528 static std::unique_ptr<MipsOperand>
1529 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1530 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1531 Op->Imm.Val = Val;
1532 Op->StartLoc = S;
1533 Op->EndLoc = E;
1534 return Op;
1537 static std::unique_ptr<MipsOperand>
1538 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1539 SMLoc E, MipsAsmParser &Parser) {
1540 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1541 Op->Mem.Base = Base.release();
1542 Op->Mem.Off = Off;
1543 Op->StartLoc = S;
1544 Op->EndLoc = E;
1545 return Op;
1548 static std::unique_ptr<MipsOperand>
1549 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1550 MipsAsmParser &Parser) {
1551 assert(Regs.size() > 0 && "Empty list not allowed");
1553 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1554 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1555 Op->StartLoc = StartLoc;
1556 Op->EndLoc = EndLoc;
1557 return Op;
1560 bool isGPRZeroAsmReg() const {
1561 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1564 bool isGPRNonZeroAsmReg() const {
1565 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1566 RegIdx.Index <= 31;
1569 bool isGPRAsmReg() const {
1570 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1573 bool isMM16AsmReg() const {
1574 if (!(isRegIdx() && RegIdx.Kind))
1575 return false;
1576 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1577 || RegIdx.Index == 16 || RegIdx.Index == 17);
1580 bool isMM16AsmRegZero() const {
1581 if (!(isRegIdx() && RegIdx.Kind))
1582 return false;
1583 return (RegIdx.Index == 0 ||
1584 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1585 RegIdx.Index == 17);
1588 bool isMM16AsmRegMoveP() const {
1589 if (!(isRegIdx() && RegIdx.Kind))
1590 return false;
1591 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1592 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1595 bool isMM16AsmRegMovePPairFirst() const {
1596 if (!(isRegIdx() && RegIdx.Kind))
1597 return false;
1598 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1601 bool isMM16AsmRegMovePPairSecond() const {
1602 if (!(isRegIdx() && RegIdx.Kind))
1603 return false;
1604 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1605 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1608 bool isFGRAsmReg() const {
1609 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1610 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1613 bool isStrictlyFGRAsmReg() const {
1614 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1615 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1618 bool isHWRegsAsmReg() const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1622 bool isCCRAsmReg() const {
1623 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1626 bool isFCCAsmReg() const {
1627 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1628 return false;
1629 return RegIdx.Index <= 7;
1632 bool isACCAsmReg() const {
1633 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1636 bool isCOP0AsmReg() const {
1637 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1640 bool isCOP2AsmReg() const {
1641 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1644 bool isCOP3AsmReg() const {
1645 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1648 bool isMSA128AsmReg() const {
1649 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1652 bool isMSACtrlAsmReg() const {
1653 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1656 /// getStartLoc - Get the location of the first token of this operand.
1657 SMLoc getStartLoc() const override { return StartLoc; }
1658 /// getEndLoc - Get the location of the last token of this operand.
1659 SMLoc getEndLoc() const override { return EndLoc; }
1661 void print(raw_ostream &OS) const override {
1662 switch (Kind) {
1663 case k_Immediate:
1664 OS << "Imm<";
1665 OS << *Imm.Val;
1666 OS << ">";
1667 break;
1668 case k_Memory:
1669 OS << "Mem<";
1670 Mem.Base->print(OS);
1671 OS << ", ";
1672 OS << *Mem.Off;
1673 OS << ">";
1674 break;
1675 case k_RegisterIndex:
1676 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1677 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1678 break;
1679 case k_Token:
1680 OS << getToken();
1681 break;
1682 case k_RegList:
1683 OS << "RegList< ";
1684 for (auto Reg : (*RegList.List))
1685 OS << Reg << " ";
1686 OS << ">";
1687 break;
1691 bool isValidForTie(const MipsOperand &Other) const {
1692 if (Kind != Other.Kind)
1693 return false;
1695 switch (Kind) {
1696 default:
1697 llvm_unreachable("Unexpected kind");
1698 return false;
1699 case k_RegisterIndex: {
1700 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1701 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1702 return Token == OtherToken;
1706 }; // class MipsOperand
1708 } // end anonymous namespace
1710 namespace llvm {
1712 extern const MCInstrDesc MipsInsts[];
1714 } // end namespace llvm
1716 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1717 return MipsInsts[Opcode];
1720 static bool hasShortDelaySlot(MCInst &Inst) {
1721 switch (Inst.getOpcode()) {
1722 case Mips::BEQ_MM:
1723 case Mips::BNE_MM:
1724 case Mips::BLTZ_MM:
1725 case Mips::BGEZ_MM:
1726 case Mips::BLEZ_MM:
1727 case Mips::BGTZ_MM:
1728 case Mips::JRC16_MM:
1729 case Mips::JALS_MM:
1730 case Mips::JALRS_MM:
1731 case Mips::JALRS16_MM:
1732 case Mips::BGEZALS_MM:
1733 case Mips::BLTZALS_MM:
1734 return true;
1735 case Mips::J_MM:
1736 return !Inst.getOperand(0).isReg();
1737 default:
1738 return false;
1742 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1743 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1744 return &SRExpr->getSymbol();
1747 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1748 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1749 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1751 if (LHSSym)
1752 return LHSSym;
1754 if (RHSSym)
1755 return RHSSym;
1757 return nullptr;
1760 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1761 return getSingleMCSymbol(UExpr->getSubExpr());
1763 return nullptr;
1766 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1767 if (isa<MCSymbolRefExpr>(Expr))
1768 return 1;
1770 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1771 return countMCSymbolRefExpr(BExpr->getLHS()) +
1772 countMCSymbolRefExpr(BExpr->getRHS());
1774 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1775 return countMCSymbolRefExpr(UExpr->getSubExpr());
1777 return 0;
1780 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1781 MCStreamer &Out,
1782 const MCSubtargetInfo *STI) {
1783 MipsTargetStreamer &TOut = getTargetStreamer();
1784 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1785 bool ExpandedJalSym = false;
1787 Inst.setLoc(IDLoc);
1789 if (MCID.isBranch() || MCID.isCall()) {
1790 const unsigned Opcode = Inst.getOpcode();
1791 MCOperand Offset;
1793 switch (Opcode) {
1794 default:
1795 break;
1796 case Mips::BBIT0:
1797 case Mips::BBIT032:
1798 case Mips::BBIT1:
1799 case Mips::BBIT132:
1800 assert(hasCnMips() && "instruction only valid for octeon cpus");
1801 LLVM_FALLTHROUGH;
1803 case Mips::BEQ:
1804 case Mips::BNE:
1805 case Mips::BEQ_MM:
1806 case Mips::BNE_MM:
1807 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1808 Offset = Inst.getOperand(2);
1809 if (!Offset.isImm())
1810 break; // We'll deal with this situation later on when applying fixups.
1811 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1812 return Error(IDLoc, "branch target out of range");
1813 if (offsetToAlignment(Offset.getImm(),
1814 (inMicroMipsMode() ? Align(2) : Align(4))))
1815 return Error(IDLoc, "branch to misaligned address");
1816 break;
1817 case Mips::BGEZ:
1818 case Mips::BGTZ:
1819 case Mips::BLEZ:
1820 case Mips::BLTZ:
1821 case Mips::BGEZAL:
1822 case Mips::BLTZAL:
1823 case Mips::BC1F:
1824 case Mips::BC1T:
1825 case Mips::BGEZ_MM:
1826 case Mips::BGTZ_MM:
1827 case Mips::BLEZ_MM:
1828 case Mips::BLTZ_MM:
1829 case Mips::BGEZAL_MM:
1830 case Mips::BLTZAL_MM:
1831 case Mips::BC1F_MM:
1832 case Mips::BC1T_MM:
1833 case Mips::BC1EQZC_MMR6:
1834 case Mips::BC1NEZC_MMR6:
1835 case Mips::BC2EQZC_MMR6:
1836 case Mips::BC2NEZC_MMR6:
1837 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1838 Offset = Inst.getOperand(1);
1839 if (!Offset.isImm())
1840 break; // We'll deal with this situation later on when applying fixups.
1841 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1842 return Error(IDLoc, "branch target out of range");
1843 if (offsetToAlignment(Offset.getImm(),
1844 (inMicroMipsMode() ? Align(2) : Align(4))))
1845 return Error(IDLoc, "branch to misaligned address");
1846 break;
1847 case Mips::BGEC: case Mips::BGEC_MMR6:
1848 case Mips::BLTC: case Mips::BLTC_MMR6:
1849 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1850 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1851 case Mips::BEQC: case Mips::BEQC_MMR6:
1852 case Mips::BNEC: case Mips::BNEC_MMR6:
1853 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1854 Offset = Inst.getOperand(2);
1855 if (!Offset.isImm())
1856 break; // We'll deal with this situation later on when applying fixups.
1857 if (!isIntN(18, Offset.getImm()))
1858 return Error(IDLoc, "branch target out of range");
1859 if (offsetToAlignment(Offset.getImm(), Align(4)))
1860 return Error(IDLoc, "branch to misaligned address");
1861 break;
1862 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1863 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1864 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1865 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1866 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1867 Offset = Inst.getOperand(1);
1868 if (!Offset.isImm())
1869 break; // We'll deal with this situation later on when applying fixups.
1870 if (!isIntN(18, Offset.getImm()))
1871 return Error(IDLoc, "branch target out of range");
1872 if (offsetToAlignment(Offset.getImm(), Align(4)))
1873 return Error(IDLoc, "branch to misaligned address");
1874 break;
1875 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1876 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1877 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1878 Offset = Inst.getOperand(1);
1879 if (!Offset.isImm())
1880 break; // We'll deal with this situation later on when applying fixups.
1881 if (!isIntN(23, Offset.getImm()))
1882 return Error(IDLoc, "branch target out of range");
1883 if (offsetToAlignment(Offset.getImm(), Align(4)))
1884 return Error(IDLoc, "branch to misaligned address");
1885 break;
1886 case Mips::BEQZ16_MM:
1887 case Mips::BEQZC16_MMR6:
1888 case Mips::BNEZ16_MM:
1889 case Mips::BNEZC16_MMR6:
1890 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1891 Offset = Inst.getOperand(1);
1892 if (!Offset.isImm())
1893 break; // We'll deal with this situation later on when applying fixups.
1894 if (!isInt<8>(Offset.getImm()))
1895 return Error(IDLoc, "branch target out of range");
1896 if (offsetToAlignment(Offset.getImm(), Align(2)))
1897 return Error(IDLoc, "branch to misaligned address");
1898 break;
1902 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1903 // We still accept it but it is a normal nop.
1904 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1905 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1906 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1907 "nop instruction");
1910 if (hasCnMips()) {
1911 const unsigned Opcode = Inst.getOpcode();
1912 MCOperand Opnd;
1913 int Imm;
1915 switch (Opcode) {
1916 default:
1917 break;
1919 case Mips::BBIT0:
1920 case Mips::BBIT032:
1921 case Mips::BBIT1:
1922 case Mips::BBIT132:
1923 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1924 // The offset is handled above
1925 Opnd = Inst.getOperand(1);
1926 if (!Opnd.isImm())
1927 return Error(IDLoc, "expected immediate operand kind");
1928 Imm = Opnd.getImm();
1929 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1930 Opcode == Mips::BBIT1 ? 63 : 31))
1931 return Error(IDLoc, "immediate operand value out of range");
1932 if (Imm > 31) {
1933 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1934 : Mips::BBIT132);
1935 Inst.getOperand(1).setImm(Imm - 32);
1937 break;
1939 case Mips::SEQi:
1940 case Mips::SNEi:
1941 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1942 Opnd = Inst.getOperand(2);
1943 if (!Opnd.isImm())
1944 return Error(IDLoc, "expected immediate operand kind");
1945 Imm = Opnd.getImm();
1946 if (!isInt<10>(Imm))
1947 return Error(IDLoc, "immediate operand value out of range");
1948 break;
1952 // Warn on division by zero. We're checking here as all instructions get
1953 // processed here, not just the macros that need expansion.
1955 // The MIPS backend models most of the divison instructions and macros as
1956 // three operand instructions. The pre-R6 divide instructions however have
1957 // two operands and explicitly define HI/LO as part of the instruction,
1958 // not in the operands.
1959 unsigned FirstOp = 1;
1960 unsigned SecondOp = 2;
1961 switch (Inst.getOpcode()) {
1962 default:
1963 break;
1964 case Mips::SDivIMacro:
1965 case Mips::UDivIMacro:
1966 case Mips::DSDivIMacro:
1967 case Mips::DUDivIMacro:
1968 if (Inst.getOperand(2).getImm() == 0) {
1969 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1970 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1971 Warning(IDLoc, "dividing zero by zero");
1972 else
1973 Warning(IDLoc, "division by zero");
1975 break;
1976 case Mips::DSDIV:
1977 case Mips::SDIV:
1978 case Mips::UDIV:
1979 case Mips::DUDIV:
1980 case Mips::UDIV_MM:
1981 case Mips::SDIV_MM:
1982 FirstOp = 0;
1983 SecondOp = 1;
1984 LLVM_FALLTHROUGH;
1985 case Mips::SDivMacro:
1986 case Mips::DSDivMacro:
1987 case Mips::UDivMacro:
1988 case Mips::DUDivMacro:
1989 case Mips::DIV:
1990 case Mips::DIVU:
1991 case Mips::DDIV:
1992 case Mips::DDIVU:
1993 case Mips::DIVU_MMR6:
1994 case Mips::DIV_MMR6:
1995 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1996 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1997 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1998 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1999 Warning(IDLoc, "dividing zero by zero");
2000 else
2001 Warning(IDLoc, "division by zero");
2003 break;
2006 // For PIC code convert unconditional jump to unconditional branch.
2007 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2008 inPicMode()) {
2009 MCInst BInst;
2010 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2011 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2012 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2013 BInst.addOperand(Inst.getOperand(0));
2014 Inst = BInst;
2017 // This expansion is not in a function called by tryExpandInstruction()
2018 // because the pseudo-instruction doesn't have a distinct opcode.
2019 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2020 inPicMode()) {
2021 warnIfNoMacro(IDLoc);
2023 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2025 // We can do this expansion if there's only 1 symbol in the argument
2026 // expression.
2027 if (countMCSymbolRefExpr(JalExpr) > 1)
2028 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2030 // FIXME: This is checking the expression can be handled by the later stages
2031 // of the assembler. We ought to leave it to those later stages.
2032 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2034 // FIXME: Add support for label+offset operands (currently causes an error).
2035 // FIXME: Add support for forward-declared local symbols.
2036 // FIXME: Add expansion for when the LargeGOT option is enabled.
2037 if (JalSym->isInSection() || JalSym->isTemporary() ||
2038 (JalSym->isELF() &&
2039 cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2040 if (isABI_O32()) {
2041 // If it's a local symbol and the O32 ABI is being used, we expand to:
2042 // lw $25, 0($gp)
2043 // R_(MICRO)MIPS_GOT16 label
2044 // addiu $25, $25, 0
2045 // R_(MICRO)MIPS_LO16 label
2046 // jalr $25
2047 const MCExpr *Got16RelocExpr =
2048 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2049 const MCExpr *Lo16RelocExpr =
2050 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2052 TOut.emitRRX(Mips::LW, Mips::T9, GPReg,
2053 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2054 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2055 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2056 } else if (isABI_N32() || isABI_N64()) {
2057 // If it's a local symbol and the N32/N64 ABIs are being used,
2058 // we expand to:
2059 // lw/ld $25, 0($gp)
2060 // R_(MICRO)MIPS_GOT_DISP label
2061 // jalr $25
2062 const MCExpr *GotDispRelocExpr =
2063 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2065 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2066 GPReg, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2067 STI);
2069 } else {
2070 // If it's an external/weak symbol, we expand to:
2071 // lw/ld $25, 0($gp)
2072 // R_(MICRO)MIPS_CALL16 label
2073 // jalr $25
2074 const MCExpr *Call16RelocExpr =
2075 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2077 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, GPReg,
2078 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2081 MCInst JalrInst;
2082 if (IsCpRestoreSet && inMicroMipsMode())
2083 JalrInst.setOpcode(Mips::JALRS_MM);
2084 else
2085 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2086 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2087 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2089 if (EmitJalrReloc) {
2090 // As an optimization hint for the linker, before the JALR we add:
2091 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2092 // tmplabel:
2093 MCSymbol *TmpLabel = getContext().createTempSymbol();
2094 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2095 const MCExpr *RelocJalrExpr =
2096 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2097 getContext(), IDLoc);
2099 TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2100 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2101 RelocJalrExpr, IDLoc, *STI);
2102 TOut.getStreamer().EmitLabel(TmpLabel);
2105 Inst = JalrInst;
2106 ExpandedJalSym = true;
2109 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2110 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2111 // Check the offset of memory operand, if it is a symbol
2112 // reference or immediate we may have to expand instructions.
2113 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2114 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2115 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2116 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2117 MCOperand &Op = Inst.getOperand(i);
2118 if (Op.isImm()) {
2119 int64_t MemOffset = Op.getImm();
2120 if (MemOffset < -32768 || MemOffset > 32767) {
2121 // Offset can't exceed 16bit value.
2122 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2123 return getParser().hasPendingError();
2125 } else if (Op.isExpr()) {
2126 const MCExpr *Expr = Op.getExpr();
2127 if (Expr->getKind() == MCExpr::SymbolRef) {
2128 const MCSymbolRefExpr *SR =
2129 static_cast<const MCSymbolRefExpr *>(Expr);
2130 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2131 // Expand symbol.
2132 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2133 return getParser().hasPendingError();
2135 } else if (!isEvaluated(Expr)) {
2136 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2137 return getParser().hasPendingError();
2141 } // for
2142 } // if load/store
2144 if (inMicroMipsMode()) {
2145 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2146 // Try to create 16-bit GP relative load instruction.
2147 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2148 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2149 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2150 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2151 MCOperand &Op = Inst.getOperand(i);
2152 if (Op.isImm()) {
2153 int MemOffset = Op.getImm();
2154 MCOperand &DstReg = Inst.getOperand(0);
2155 MCOperand &BaseReg = Inst.getOperand(1);
2156 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2157 getContext().getRegisterInfo()->getRegClass(
2158 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2159 (BaseReg.getReg() == Mips::GP ||
2160 BaseReg.getReg() == Mips::GP_64)) {
2162 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2163 IDLoc, STI);
2164 return false;
2168 } // for
2169 } // if load
2171 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2173 MCOperand Opnd;
2174 int Imm;
2176 switch (Inst.getOpcode()) {
2177 default:
2178 break;
2179 case Mips::ADDIUSP_MM:
2180 Opnd = Inst.getOperand(0);
2181 if (!Opnd.isImm())
2182 return Error(IDLoc, "expected immediate operand kind");
2183 Imm = Opnd.getImm();
2184 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2185 Imm % 4 != 0)
2186 return Error(IDLoc, "immediate operand value out of range");
2187 break;
2188 case Mips::SLL16_MM:
2189 case Mips::SRL16_MM:
2190 Opnd = Inst.getOperand(2);
2191 if (!Opnd.isImm())
2192 return Error(IDLoc, "expected immediate operand kind");
2193 Imm = Opnd.getImm();
2194 if (Imm < 1 || Imm > 8)
2195 return Error(IDLoc, "immediate operand value out of range");
2196 break;
2197 case Mips::LI16_MM:
2198 Opnd = Inst.getOperand(1);
2199 if (!Opnd.isImm())
2200 return Error(IDLoc, "expected immediate operand kind");
2201 Imm = Opnd.getImm();
2202 if (Imm < -1 || Imm > 126)
2203 return Error(IDLoc, "immediate operand value out of range");
2204 break;
2205 case Mips::ADDIUR2_MM:
2206 Opnd = Inst.getOperand(2);
2207 if (!Opnd.isImm())
2208 return Error(IDLoc, "expected immediate operand kind");
2209 Imm = Opnd.getImm();
2210 if (!(Imm == 1 || Imm == -1 ||
2211 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2212 return Error(IDLoc, "immediate operand value out of range");
2213 break;
2214 case Mips::ANDI16_MM:
2215 Opnd = Inst.getOperand(2);
2216 if (!Opnd.isImm())
2217 return Error(IDLoc, "expected immediate operand kind");
2218 Imm = Opnd.getImm();
2219 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2220 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2221 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2222 return Error(IDLoc, "immediate operand value out of range");
2223 break;
2224 case Mips::LBU16_MM:
2225 Opnd = Inst.getOperand(2);
2226 if (!Opnd.isImm())
2227 return Error(IDLoc, "expected immediate operand kind");
2228 Imm = Opnd.getImm();
2229 if (Imm < -1 || Imm > 14)
2230 return Error(IDLoc, "immediate operand value out of range");
2231 break;
2232 case Mips::SB16_MM:
2233 case Mips::SB16_MMR6:
2234 Opnd = Inst.getOperand(2);
2235 if (!Opnd.isImm())
2236 return Error(IDLoc, "expected immediate operand kind");
2237 Imm = Opnd.getImm();
2238 if (Imm < 0 || Imm > 15)
2239 return Error(IDLoc, "immediate operand value out of range");
2240 break;
2241 case Mips::LHU16_MM:
2242 case Mips::SH16_MM:
2243 case Mips::SH16_MMR6:
2244 Opnd = Inst.getOperand(2);
2245 if (!Opnd.isImm())
2246 return Error(IDLoc, "expected immediate operand kind");
2247 Imm = Opnd.getImm();
2248 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2249 return Error(IDLoc, "immediate operand value out of range");
2250 break;
2251 case Mips::LW16_MM:
2252 case Mips::SW16_MM:
2253 case Mips::SW16_MMR6:
2254 Opnd = Inst.getOperand(2);
2255 if (!Opnd.isImm())
2256 return Error(IDLoc, "expected immediate operand kind");
2257 Imm = Opnd.getImm();
2258 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2259 return Error(IDLoc, "immediate operand value out of range");
2260 break;
2261 case Mips::ADDIUPC_MM:
2262 Opnd = Inst.getOperand(1);
2263 if (!Opnd.isImm())
2264 return Error(IDLoc, "expected immediate operand kind");
2265 Imm = Opnd.getImm();
2266 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2267 return Error(IDLoc, "immediate operand value out of range");
2268 break;
2269 case Mips::LWP_MM:
2270 case Mips::SWP_MM:
2271 if (Inst.getOperand(0).getReg() == Mips::RA)
2272 return Error(IDLoc, "invalid operand for instruction");
2273 break;
2274 case Mips::MOVEP_MM:
2275 case Mips::MOVEP_MMR6: {
2276 unsigned R0 = Inst.getOperand(0).getReg();
2277 unsigned R1 = Inst.getOperand(1).getReg();
2278 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2279 (R0 == Mips::A1 && R1 == Mips::A3) ||
2280 (R0 == Mips::A2 && R1 == Mips::A3) ||
2281 (R0 == Mips::A0 && R1 == Mips::S5) ||
2282 (R0 == Mips::A0 && R1 == Mips::S6) ||
2283 (R0 == Mips::A0 && R1 == Mips::A1) ||
2284 (R0 == Mips::A0 && R1 == Mips::A2) ||
2285 (R0 == Mips::A0 && R1 == Mips::A3));
2286 if (!RegPair)
2287 return Error(IDLoc, "invalid operand for instruction");
2288 break;
2293 bool FillDelaySlot =
2294 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2295 if (FillDelaySlot)
2296 TOut.emitDirectiveSetNoReorder();
2298 MacroExpanderResultTy ExpandResult =
2299 tryExpandInstruction(Inst, IDLoc, Out, STI);
2300 switch (ExpandResult) {
2301 case MER_NotAMacro:
2302 Out.EmitInstruction(Inst, *STI);
2303 break;
2304 case MER_Success:
2305 break;
2306 case MER_Fail:
2307 return true;
2310 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2311 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2312 if (inMicroMipsMode()) {
2313 TOut.setUsesMicroMips();
2314 TOut.updateABIInfo(*this);
2317 // If this instruction has a delay slot and .set reorder is active,
2318 // emit a NOP after it.
2319 if (FillDelaySlot) {
2320 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2321 TOut.emitDirectiveSetReorder();
2324 if ((Inst.getOpcode() == Mips::JalOneReg ||
2325 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2326 isPicAndNotNxxAbi()) {
2327 if (IsCpRestoreSet) {
2328 // We need a NOP between the JALR and the LW:
2329 // If .set reorder has been used, we've already emitted a NOP.
2330 // If .set noreorder has been used, we need to emit a NOP at this point.
2331 if (!AssemblerOptions.back()->isReorder())
2332 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2333 STI);
2335 // Load the $gp from the stack.
2336 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2337 } else
2338 Warning(IDLoc, "no .cprestore used in PIC mode");
2341 return false;
2344 MipsAsmParser::MacroExpanderResultTy
2345 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2346 const MCSubtargetInfo *STI) {
2347 switch (Inst.getOpcode()) {
2348 default:
2349 return MER_NotAMacro;
2350 case Mips::LoadImm32:
2351 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2352 case Mips::LoadImm64:
2353 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2354 case Mips::LoadAddrImm32:
2355 case Mips::LoadAddrImm64:
2356 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2357 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2358 "expected immediate operand kind");
2360 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2361 Inst.getOperand(1),
2362 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2363 Out, STI)
2364 ? MER_Fail
2365 : MER_Success;
2366 case Mips::LoadAddrReg32:
2367 case Mips::LoadAddrReg64:
2368 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2369 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2370 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2371 "expected immediate operand kind");
2373 return expandLoadAddress(Inst.getOperand(0).getReg(),
2374 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2375 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2376 Out, STI)
2377 ? MER_Fail
2378 : MER_Success;
2379 case Mips::B_MM_Pseudo:
2380 case Mips::B_MMR6_Pseudo:
2381 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2382 : MER_Success;
2383 case Mips::SWM_MM:
2384 case Mips::LWM_MM:
2385 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2386 : MER_Success;
2387 case Mips::JalOneReg:
2388 case Mips::JalTwoReg:
2389 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2390 case Mips::BneImm:
2391 case Mips::BeqImm:
2392 case Mips::BEQLImmMacro:
2393 case Mips::BNELImmMacro:
2394 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2395 case Mips::BLT:
2396 case Mips::BLE:
2397 case Mips::BGE:
2398 case Mips::BGT:
2399 case Mips::BLTU:
2400 case Mips::BLEU:
2401 case Mips::BGEU:
2402 case Mips::BGTU:
2403 case Mips::BLTL:
2404 case Mips::BLEL:
2405 case Mips::BGEL:
2406 case Mips::BGTL:
2407 case Mips::BLTUL:
2408 case Mips::BLEUL:
2409 case Mips::BGEUL:
2410 case Mips::BGTUL:
2411 case Mips::BLTImmMacro:
2412 case Mips::BLEImmMacro:
2413 case Mips::BGEImmMacro:
2414 case Mips::BGTImmMacro:
2415 case Mips::BLTUImmMacro:
2416 case Mips::BLEUImmMacro:
2417 case Mips::BGEUImmMacro:
2418 case Mips::BGTUImmMacro:
2419 case Mips::BLTLImmMacro:
2420 case Mips::BLELImmMacro:
2421 case Mips::BGELImmMacro:
2422 case Mips::BGTLImmMacro:
2423 case Mips::BLTULImmMacro:
2424 case Mips::BLEULImmMacro:
2425 case Mips::BGEULImmMacro:
2426 case Mips::BGTULImmMacro:
2427 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2428 case Mips::SDivMacro:
2429 case Mips::SDivIMacro:
2430 case Mips::SRemMacro:
2431 case Mips::SRemIMacro:
2432 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2433 : MER_Success;
2434 case Mips::DSDivMacro:
2435 case Mips::DSDivIMacro:
2436 case Mips::DSRemMacro:
2437 case Mips::DSRemIMacro:
2438 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2439 : MER_Success;
2440 case Mips::UDivMacro:
2441 case Mips::UDivIMacro:
2442 case Mips::URemMacro:
2443 case Mips::URemIMacro:
2444 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2445 : MER_Success;
2446 case Mips::DUDivMacro:
2447 case Mips::DUDivIMacro:
2448 case Mips::DURemMacro:
2449 case Mips::DURemIMacro:
2450 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2451 : MER_Success;
2452 case Mips::PseudoTRUNC_W_S:
2453 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2454 : MER_Success;
2455 case Mips::PseudoTRUNC_W_D32:
2456 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2457 : MER_Success;
2458 case Mips::PseudoTRUNC_W_D:
2459 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2460 : MER_Success;
2462 case Mips::LoadImmSingleGPR:
2463 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2464 : MER_Success;
2465 case Mips::LoadImmSingleFGR:
2466 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2467 : MER_Success;
2468 case Mips::LoadImmDoubleGPR:
2469 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2470 : MER_Success;
2471 case Mips::LoadImmDoubleFGR:
2472 return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2473 : MER_Success;
2474 case Mips::LoadImmDoubleFGR_32:
2475 return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2476 : MER_Success;
2478 case Mips::Ulh:
2479 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2480 case Mips::Ulhu:
2481 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2482 case Mips::Ush:
2483 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 case Mips::Ulw:
2485 case Mips::Usw:
2486 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2487 case Mips::NORImm:
2488 case Mips::NORImm64:
2489 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 case Mips::SGE:
2491 case Mips::SGEU:
2492 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 case Mips::SGEImm:
2494 case Mips::SGEUImm:
2495 case Mips::SGEImm64:
2496 case Mips::SGEUImm64:
2497 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2498 case Mips::SGTImm:
2499 case Mips::SGTUImm:
2500 case Mips::SGTImm64:
2501 case Mips::SGTUImm64:
2502 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2503 case Mips::SLTImm64:
2504 if (isInt<16>(Inst.getOperand(2).getImm())) {
2505 Inst.setOpcode(Mips::SLTi64);
2506 return MER_NotAMacro;
2508 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2509 case Mips::SLTUImm64:
2510 if (isInt<16>(Inst.getOperand(2).getImm())) {
2511 Inst.setOpcode(Mips::SLTiu64);
2512 return MER_NotAMacro;
2514 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2515 case Mips::ADDi: case Mips::ADDi_MM:
2516 case Mips::ADDiu: case Mips::ADDiu_MM:
2517 case Mips::SLTi: case Mips::SLTi_MM:
2518 case Mips::SLTiu: case Mips::SLTiu_MM:
2519 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2520 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2521 int64_t ImmValue = Inst.getOperand(2).getImm();
2522 if (isInt<16>(ImmValue))
2523 return MER_NotAMacro;
2524 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2525 : MER_Success;
2527 return MER_NotAMacro;
2528 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2529 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2530 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2531 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2532 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2533 int64_t ImmValue = Inst.getOperand(2).getImm();
2534 if (isUInt<16>(ImmValue))
2535 return MER_NotAMacro;
2536 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2537 : MER_Success;
2539 return MER_NotAMacro;
2540 case Mips::ROL:
2541 case Mips::ROR:
2542 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 case Mips::ROLImm:
2544 case Mips::RORImm:
2545 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2546 case Mips::DROL:
2547 case Mips::DROR:
2548 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 case Mips::DROLImm:
2550 case Mips::DRORImm:
2551 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 case Mips::ABSMacro:
2553 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2554 case Mips::MULImmMacro:
2555 case Mips::DMULImmMacro:
2556 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 case Mips::MULOMacro:
2558 case Mips::DMULOMacro:
2559 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2560 case Mips::MULOUMacro:
2561 case Mips::DMULOUMacro:
2562 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2563 case Mips::DMULMacro:
2564 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 case Mips::LDMacro:
2566 case Mips::SDMacro:
2567 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2568 Inst.getOpcode() == Mips::LDMacro)
2569 ? MER_Fail
2570 : MER_Success;
2571 case Mips::SDC1_M1:
2572 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2573 ? MER_Fail
2574 : MER_Success;
2575 case Mips::SEQMacro:
2576 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 case Mips::SEQIMacro:
2578 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 case Mips::MFTC0: case Mips::MTTC0:
2580 case Mips::MFTGPR: case Mips::MTTGPR:
2581 case Mips::MFTLO: case Mips::MTTLO:
2582 case Mips::MFTHI: case Mips::MTTHI:
2583 case Mips::MFTACX: case Mips::MTTACX:
2584 case Mips::MFTDSP: case Mips::MTTDSP:
2585 case Mips::MFTC1: case Mips::MTTC1:
2586 case Mips::MFTHC1: case Mips::MTTHC1:
2587 case Mips::CFTC1: case Mips::CTTC1:
2588 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2592 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2593 MCStreamer &Out,
2594 const MCSubtargetInfo *STI) {
2595 MipsTargetStreamer &TOut = getTargetStreamer();
2597 // Create a JALR instruction which is going to replace the pseudo-JAL.
2598 MCInst JalrInst;
2599 JalrInst.setLoc(IDLoc);
2600 const MCOperand FirstRegOp = Inst.getOperand(0);
2601 const unsigned Opcode = Inst.getOpcode();
2603 if (Opcode == Mips::JalOneReg) {
2604 // jal $rs => jalr $rs
2605 if (IsCpRestoreSet && inMicroMipsMode()) {
2606 JalrInst.setOpcode(Mips::JALRS16_MM);
2607 JalrInst.addOperand(FirstRegOp);
2608 } else if (inMicroMipsMode()) {
2609 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2610 JalrInst.addOperand(FirstRegOp);
2611 } else {
2612 JalrInst.setOpcode(Mips::JALR);
2613 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2614 JalrInst.addOperand(FirstRegOp);
2616 } else if (Opcode == Mips::JalTwoReg) {
2617 // jal $rd, $rs => jalr $rd, $rs
2618 if (IsCpRestoreSet && inMicroMipsMode())
2619 JalrInst.setOpcode(Mips::JALRS_MM);
2620 else
2621 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2622 JalrInst.addOperand(FirstRegOp);
2623 const MCOperand SecondRegOp = Inst.getOperand(1);
2624 JalrInst.addOperand(SecondRegOp);
2626 Out.EmitInstruction(JalrInst, *STI);
2628 // If .set reorder is active and branch instruction has a delay slot,
2629 // emit a NOP after it.
2630 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2631 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2632 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2633 STI);
2635 return false;
2638 /// Can the value be represented by a unsigned N-bit value and a shift left?
2639 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2640 unsigned BitNum = findFirstSet(x);
2642 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2645 /// Load (or add) an immediate into a register.
2647 /// @param ImmValue The immediate to load.
2648 /// @param DstReg The register that will hold the immediate.
2649 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2650 /// for a simple initialization.
2651 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2652 /// @param IsAddress True if the immediate represents an address. False if it
2653 /// is an integer.
2654 /// @param IDLoc Location of the immediate in the source file.
2655 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2656 unsigned SrcReg, bool Is32BitImm,
2657 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2658 const MCSubtargetInfo *STI) {
2659 MipsTargetStreamer &TOut = getTargetStreamer();
2661 if (!Is32BitImm && !isGP64bit()) {
2662 Error(IDLoc, "instruction requires a 64-bit architecture");
2663 return true;
2666 if (Is32BitImm) {
2667 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2668 // Sign extend up to 64-bit so that the predicates match the hardware
2669 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2670 // true.
2671 ImmValue = SignExtend64<32>(ImmValue);
2672 } else {
2673 Error(IDLoc, "instruction requires a 32-bit immediate");
2674 return true;
2678 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2679 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2681 bool UseSrcReg = false;
2682 if (SrcReg != Mips::NoRegister)
2683 UseSrcReg = true;
2685 unsigned TmpReg = DstReg;
2686 if (UseSrcReg &&
2687 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2688 // At this point we need AT to perform the expansions and we exit if it is
2689 // not available.
2690 unsigned ATReg = getATReg(IDLoc);
2691 if (!ATReg)
2692 return true;
2693 TmpReg = ATReg;
2696 if (isInt<16>(ImmValue)) {
2697 if (!UseSrcReg)
2698 SrcReg = ZeroReg;
2700 // This doesn't quite follow the usual ABI expectations for N32 but matches
2701 // traditional assembler behaviour. N32 would normally use addiu for both
2702 // integers and addresses.
2703 if (IsAddress && !Is32BitImm) {
2704 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2705 return false;
2708 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2709 return false;
2712 if (isUInt<16>(ImmValue)) {
2713 unsigned TmpReg = DstReg;
2714 if (SrcReg == DstReg) {
2715 TmpReg = getATReg(IDLoc);
2716 if (!TmpReg)
2717 return true;
2720 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2721 if (UseSrcReg)
2722 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2723 return false;
2726 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2727 warnIfNoMacro(IDLoc);
2729 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2730 uint16_t Bits15To0 = ImmValue & 0xffff;
2731 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2732 // Traditional behaviour seems to special case this particular value. It's
2733 // not clear why other masks are handled differently.
2734 if (ImmValue == 0xffffffff) {
2735 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2736 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2737 if (UseSrcReg)
2738 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2739 return false;
2742 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2743 // upper 32 bits.
2744 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2745 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2746 if (Bits15To0)
2747 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2748 if (UseSrcReg)
2749 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2750 return false;
2753 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2754 if (Bits15To0)
2755 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2756 if (UseSrcReg)
2757 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2758 return false;
2761 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2762 if (Is32BitImm) {
2763 Error(IDLoc, "instruction requires a 32-bit immediate");
2764 return true;
2767 // Traditionally, these immediates are shifted as little as possible and as
2768 // such we align the most significant bit to bit 15 of our temporary.
2769 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2770 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2771 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2772 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2773 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2774 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2776 if (UseSrcReg)
2777 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2779 return false;
2782 warnIfNoMacro(IDLoc);
2784 // The remaining case is packed with a sequence of dsll and ori with zeros
2785 // being omitted and any neighbouring dsll's being coalesced.
2786 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2788 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2789 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2790 IDLoc, Out, STI))
2791 return false;
2793 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2794 // skip it and defer the shift to the next chunk.
2795 unsigned ShiftCarriedForwards = 16;
2796 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2797 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2799 if (ImmChunk != 0) {
2800 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2801 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2802 ShiftCarriedForwards = 0;
2805 ShiftCarriedForwards += 16;
2807 ShiftCarriedForwards -= 16;
2809 // Finish any remaining shifts left by trailing zeros.
2810 if (ShiftCarriedForwards)
2811 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2813 if (UseSrcReg)
2814 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2816 return false;
2819 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2820 MCStreamer &Out, const MCSubtargetInfo *STI) {
2821 const MCOperand &ImmOp = Inst.getOperand(1);
2822 assert(ImmOp.isImm() && "expected immediate operand kind");
2823 const MCOperand &DstRegOp = Inst.getOperand(0);
2824 assert(DstRegOp.isReg() && "expected register operand kind");
2826 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2827 Is32BitImm, false, IDLoc, Out, STI))
2828 return true;
2830 return false;
2833 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2834 const MCOperand &Offset,
2835 bool Is32BitAddress, SMLoc IDLoc,
2836 MCStreamer &Out,
2837 const MCSubtargetInfo *STI) {
2838 // la can't produce a usable address when addresses are 64-bit.
2839 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2840 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2841 // We currently can't do this because we depend on the equality
2842 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2843 Error(IDLoc, "la used to load 64-bit address");
2844 // Continue as if we had 'dla' instead.
2845 Is32BitAddress = false;
2846 return true;
2849 // dla requires 64-bit addresses.
2850 if (!Is32BitAddress && !hasMips3()) {
2851 Error(IDLoc, "instruction requires a 64-bit architecture");
2852 return true;
2855 if (!Offset.isImm())
2856 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2857 Is32BitAddress, IDLoc, Out, STI);
2859 if (!ABI.ArePtrs64bit()) {
2860 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2861 Is32BitAddress = true;
2864 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2865 IDLoc, Out, STI);
2868 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2869 unsigned DstReg, unsigned SrcReg,
2870 bool Is32BitSym, SMLoc IDLoc,
2871 MCStreamer &Out,
2872 const MCSubtargetInfo *STI) {
2873 MipsTargetStreamer &TOut = getTargetStreamer();
2874 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2875 SrcReg != Mips::ZERO_64;
2876 warnIfNoMacro(IDLoc);
2878 if (inPicMode()) {
2879 MCValue Res;
2880 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2881 Error(IDLoc, "expected relocatable expression");
2882 return true;
2884 if (Res.getSymB() != nullptr) {
2885 Error(IDLoc, "expected relocatable expression with only one symbol");
2886 return true;
2889 bool IsPtr64 = ABI.ArePtrs64bit();
2890 bool IsLocalSym =
2891 Res.getSymA()->getSymbol().isInSection() ||
2892 Res.getSymA()->getSymbol().isTemporary() ||
2893 (Res.getSymA()->getSymbol().isELF() &&
2894 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2895 ELF::STB_LOCAL);
2896 bool UseXGOT = STI->getFeatureBits()[Mips::FeatureXGOT] && !IsLocalSym;
2898 // The case where the result register is $25 is somewhat special. If the
2899 // symbol in the final relocation is external and not modified with a
2900 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2901 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2902 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2903 Res.getConstant() == 0 && !IsLocalSym) {
2904 if (UseXGOT) {
2905 const MCExpr *CallHiExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16,
2906 SymExpr, getContext());
2907 const MCExpr *CallLoExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16,
2908 SymExpr, getContext());
2909 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2910 STI);
2911 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2912 IDLoc, STI);
2913 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2914 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2915 } else {
2916 const MCExpr *CallExpr =
2917 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2918 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2919 MCOperand::createExpr(CallExpr), IDLoc, STI);
2921 return false;
2924 unsigned TmpReg = DstReg;
2925 if (UseSrcReg &&
2926 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2927 SrcReg)) {
2928 // If $rs is the same as $rd, we need to use AT.
2929 // If it is not available we exit.
2930 unsigned ATReg = getATReg(IDLoc);
2931 if (!ATReg)
2932 return true;
2933 TmpReg = ATReg;
2936 if (UseXGOT) {
2937 // Loading address from XGOT
2938 // External GOT: lui $tmp, %got_hi(symbol)($gp)
2939 // addu $tmp, $tmp, $gp
2940 // lw $tmp, %got_lo(symbol)($tmp)
2941 // >addiu $tmp, $tmp, offset
2942 // >addiu $rd, $tmp, $rs
2943 // The addiu's marked with a '>' may be omitted if they are redundant. If
2944 // this happens then the last instruction must use $rd as the result
2945 // register.
2946 const MCExpr *CallHiExpr =
2947 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
2948 const MCExpr *CallLoExpr = MipsMCExpr::create(
2949 MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
2951 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2952 STI);
2953 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2954 IDLoc, STI);
2955 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
2956 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2958 if (Res.getConstant() != 0)
2959 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
2960 MCOperand::createExpr(MCConstantExpr::create(
2961 Res.getConstant(), getContext())),
2962 IDLoc, STI);
2964 if (UseSrcReg)
2965 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
2966 IDLoc, STI);
2967 return false;
2970 const MipsMCExpr *GotExpr = nullptr;
2971 const MCExpr *LoExpr = nullptr;
2972 if (IsPtr64) {
2973 // The remaining cases are:
2974 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2975 // >daddiu $tmp, $tmp, offset
2976 // >daddu $rd, $tmp, $rs
2977 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2978 // this happens then the last instruction must use $rd as the result
2979 // register.
2980 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, Res.getSymA(),
2981 getContext());
2982 if (Res.getConstant() != 0) {
2983 // Symbols fully resolve with just the %got_disp(symbol) but we
2984 // must still account for any offset to the symbol for
2985 // expressions like symbol+8.
2986 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2988 // FIXME: Offsets greater than 16 bits are not yet implemented.
2989 // FIXME: The correct range is a 32-bit sign-extended number.
2990 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2991 Error(IDLoc, "macro instruction uses large offset, which is not "
2992 "currently supported");
2993 return true;
2996 } else {
2997 // The remaining cases are:
2998 // External GOT: lw $tmp, %got(symbol)($gp)
2999 // >addiu $tmp, $tmp, offset
3000 // >addiu $rd, $tmp, $rs
3001 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3002 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3003 // >addiu $rd, $tmp, $rs
3004 // The addiu's marked with a '>' may be omitted if they are redundant. If
3005 // this happens then the last instruction must use $rd as the result
3006 // register.
3007 if (IsLocalSym) {
3008 GotExpr =
3009 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3010 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3011 } else {
3012 // External symbols fully resolve the symbol with just the %got(symbol)
3013 // but we must still account for any offset to the symbol for
3014 // expressions like symbol+8.
3015 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, Res.getSymA(),
3016 getContext());
3017 if (Res.getConstant() != 0)
3018 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3022 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3023 MCOperand::createExpr(GotExpr), IDLoc, STI);
3025 if (LoExpr)
3026 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3027 MCOperand::createExpr(LoExpr), IDLoc, STI);
3029 if (UseSrcReg)
3030 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3031 IDLoc, STI);
3033 return false;
3036 const MipsMCExpr *HiExpr =
3037 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3038 const MipsMCExpr *LoExpr =
3039 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3041 // This is the 64-bit symbol address expansion.
3042 if (ABI.ArePtrs64bit() && isGP64bit()) {
3043 // We need AT for the 64-bit expansion in the cases where the optional
3044 // source register is the destination register and for the superscalar
3045 // scheduled form.
3047 // If it is not available we exit if the destination is the same as the
3048 // source register.
3050 const MipsMCExpr *HighestExpr =
3051 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3052 const MipsMCExpr *HigherExpr =
3053 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3055 bool RdRegIsRsReg =
3056 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3058 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3059 unsigned ATReg = getATReg(IDLoc);
3061 // If $rs is the same as $rd:
3062 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3063 // daddiu $at, $at, %higher(sym)
3064 // dsll $at, $at, 16
3065 // daddiu $at, $at, %hi(sym)
3066 // dsll $at, $at, 16
3067 // daddiu $at, $at, %lo(sym)
3068 // daddu $rd, $at, $rd
3069 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3070 STI);
3071 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3072 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3073 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3074 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3075 IDLoc, STI);
3076 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3077 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3078 IDLoc, STI);
3079 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3081 return false;
3082 } else if (canUseATReg() && !RdRegIsRsReg) {
3083 unsigned ATReg = getATReg(IDLoc);
3085 // If the $rs is different from $rd or if $rs isn't specified and we
3086 // have $at available:
3087 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3088 // lui $at, %hi(sym)
3089 // daddiu $rd, $rd, %higher(sym)
3090 // daddiu $at, $at, %lo(sym)
3091 // dsll32 $rd, $rd, 0
3092 // daddu $rd, $rd, $at
3093 // (daddu $rd, $rd, $rs)
3095 // Which is preferred for superscalar issue.
3096 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3097 STI);
3098 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3099 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3100 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3101 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3102 IDLoc, STI);
3103 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3104 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3105 if (UseSrcReg)
3106 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3108 return false;
3109 } else if (!canUseATReg() && !RdRegIsRsReg) {
3110 // Otherwise, synthesize the address in the destination register
3111 // serially:
3112 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3113 // daddiu $rd, $rd, %higher(sym)
3114 // dsll $rd, $rd, 16
3115 // daddiu $rd, $rd, %hi(sym)
3116 // dsll $rd, $rd, 16
3117 // daddiu $rd, $rd, %lo(sym)
3118 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3119 STI);
3120 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3121 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3122 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3123 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3124 MCOperand::createExpr(HiExpr), IDLoc, STI);
3125 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3126 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3127 MCOperand::createExpr(LoExpr), IDLoc, STI);
3128 if (UseSrcReg)
3129 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3131 return false;
3132 } else {
3133 // We have a case where SrcReg == DstReg and we don't have $at
3134 // available. We can't expand this case, so error out appropriately.
3135 assert(SrcReg == DstReg && !canUseATReg() &&
3136 "Could have expanded dla but didn't?");
3137 reportParseError(IDLoc,
3138 "pseudo-instruction requires $at, which is not available");
3139 return true;
3143 // And now, the 32-bit symbol address expansion:
3144 // If $rs is the same as $rd:
3145 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3146 // ori $at, $at, %lo(sym)
3147 // addu $rd, $at, $rd
3148 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3149 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3150 // ori $rd, $rd, %lo(sym)
3151 // (addu $rd, $rd, $rs)
3152 unsigned TmpReg = DstReg;
3153 if (UseSrcReg &&
3154 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3155 // If $rs is the same as $rd, we need to use AT.
3156 // If it is not available we exit.
3157 unsigned ATReg = getATReg(IDLoc);
3158 if (!ATReg)
3159 return true;
3160 TmpReg = ATReg;
3163 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3164 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3165 IDLoc, STI);
3167 if (UseSrcReg)
3168 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3169 else
3170 assert(
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3173 return false;
3176 // Each double-precision register DO-D15 overlaps with two of the single
3177 // precision registers F0-F31. As an example, all of the following hold true:
3178 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3179 static unsigned nextReg(unsigned Reg) {
3180 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3181 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3182 switch (Reg) {
3183 default: llvm_unreachable("Unknown register in assembly macro expansion!");
3184 case Mips::ZERO: return Mips::AT;
3185 case Mips::AT: return Mips::V0;
3186 case Mips::V0: return Mips::V1;
3187 case Mips::V1: return Mips::A0;
3188 case Mips::A0: return Mips::A1;
3189 case Mips::A1: return Mips::A2;
3190 case Mips::A2: return Mips::A3;
3191 case Mips::A3: return Mips::T0;
3192 case Mips::T0: return Mips::T1;
3193 case Mips::T1: return Mips::T2;
3194 case Mips::T2: return Mips::T3;
3195 case Mips::T3: return Mips::T4;
3196 case Mips::T4: return Mips::T5;
3197 case Mips::T5: return Mips::T6;
3198 case Mips::T6: return Mips::T7;
3199 case Mips::T7: return Mips::S0;
3200 case Mips::S0: return Mips::S1;
3201 case Mips::S1: return Mips::S2;
3202 case Mips::S2: return Mips::S3;
3203 case Mips::S3: return Mips::S4;
3204 case Mips::S4: return Mips::S5;
3205 case Mips::S5: return Mips::S6;
3206 case Mips::S6: return Mips::S7;
3207 case Mips::S7: return Mips::T8;
3208 case Mips::T8: return Mips::T9;
3209 case Mips::T9: return Mips::K0;
3210 case Mips::K0: return Mips::K1;
3211 case Mips::K1: return Mips::GP;
3212 case Mips::GP: return Mips::SP;
3213 case Mips::SP: return Mips::FP;
3214 case Mips::FP: return Mips::RA;
3215 case Mips::RA: return Mips::ZERO;
3216 case Mips::D0: return Mips::F1;
3217 case Mips::D1: return Mips::F3;
3218 case Mips::D2: return Mips::F5;
3219 case Mips::D3: return Mips::F7;
3220 case Mips::D4: return Mips::F9;
3221 case Mips::D5: return Mips::F11;
3222 case Mips::D6: return Mips::F13;
3223 case Mips::D7: return Mips::F15;
3224 case Mips::D8: return Mips::F17;
3225 case Mips::D9: return Mips::F19;
3226 case Mips::D10: return Mips::F21;
3227 case Mips::D11: return Mips::F23;
3228 case Mips::D12: return Mips::F25;
3229 case Mips::D13: return Mips::F27;
3230 case Mips::D14: return Mips::F29;
3231 case Mips::D15: return Mips::F31;
3235 // FIXME: This method is too general. In principle we should compute the number
3236 // of instructions required to synthesize the immediate inline compared to
3237 // synthesizing the address inline and relying on non .text sections.
3238 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3239 // likely to yield a much larger benefit as we have to synthesize a 64bit
3240 // address to load a 64 bit value.
3241 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3242 MCSymbol *Sym) {
3243 unsigned ATReg = getATReg(IDLoc);
3244 if (!ATReg)
3245 return true;
3247 if(IsPicEnabled) {
3248 const MCExpr *GotSym =
3249 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3250 const MipsMCExpr *GotExpr =
3251 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3253 if(isABI_O32() || isABI_N32()) {
3254 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3255 IDLoc, STI);
3256 } else { //isABI_N64()
3257 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3258 IDLoc, STI);
3260 } else { //!IsPicEnabled
3261 const MCExpr *HiSym =
3262 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3263 const MipsMCExpr *HiExpr =
3264 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3266 // FIXME: This is technically correct but gives a different result to gas,
3267 // but gas is incomplete there (it has a fixme noting it doesn't work with
3268 // 64-bit addresses).
3269 // FIXME: With -msym32 option, the address expansion for N64 should probably
3270 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3271 // symbol's value is considered sign extended.
3272 if(isABI_O32() || isABI_N32()) {
3273 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3274 } else { //isABI_N64()
3275 const MCExpr *HighestSym =
3276 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3277 const MipsMCExpr *HighestExpr =
3278 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3279 const MCExpr *HigherSym =
3280 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3281 const MipsMCExpr *HigherExpr =
3282 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3284 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3285 STI);
3286 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3287 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3288 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3289 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3290 IDLoc, STI);
3291 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3294 return false;
3297 static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) {
3298 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3299 // exponent field), convert it to double (e.g. 1 to 1.0)
3300 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3301 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3302 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3304 return ImmOp64;
3307 static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) {
3308 // Conversion of a double in an uint64_t to a float in a uint32_t,
3309 // retaining the bit pattern of a float.
3310 double DoubleImm = BitsToDouble(ImmOp64);
3311 float TmpFloat = static_cast<float>(DoubleImm);
3312 return FloatToBits(TmpFloat);
3315 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3316 MCStreamer &Out,
3317 const MCSubtargetInfo *STI) {
3318 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3319 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3320 "Invalid instruction operand.");
3322 unsigned FirstReg = Inst.getOperand(0).getReg();
3323 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3325 uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3327 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3328 Out, STI);
3331 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3332 MCStreamer &Out,
3333 const MCSubtargetInfo *STI) {
3334 MipsTargetStreamer &TOut = getTargetStreamer();
3335 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3336 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3337 "Invalid instruction operand.");
3339 unsigned FirstReg = Inst.getOperand(0).getReg();
3340 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3342 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3344 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3346 unsigned TmpReg = Mips::ZERO;
3347 if (ImmOp32 != 0) {
3348 TmpReg = getATReg(IDLoc);
3349 if (!TmpReg)
3350 return true;
3353 if (Lo_32(ImmOp64) == 0) {
3354 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3355 true, false, IDLoc, Out, STI))
3356 return true;
3357 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3358 return false;
3361 MCSection *CS = getStreamer().getCurrentSectionOnly();
3362 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3363 // where appropriate.
3364 MCSection *ReadOnlySection =
3365 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3367 MCSymbol *Sym = getContext().createTempSymbol();
3368 const MCExpr *LoSym =
3369 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3370 const MipsMCExpr *LoExpr =
3371 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3373 getStreamer().SwitchSection(ReadOnlySection);
3374 getStreamer().EmitLabel(Sym, IDLoc);
3375 getStreamer().EmitIntValue(ImmOp32, 4);
3376 getStreamer().SwitchSection(CS);
3378 if (emitPartialAddress(TOut, IDLoc, Sym))
3379 return true;
3380 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3381 IDLoc, STI);
3382 return false;
3385 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3386 MCStreamer &Out,
3387 const MCSubtargetInfo *STI) {
3388 MipsTargetStreamer &TOut = getTargetStreamer();
3389 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3390 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3391 "Invalid instruction operand.");
3393 unsigned FirstReg = Inst.getOperand(0).getReg();
3394 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3396 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3398 if (Lo_32(ImmOp64) == 0) {
3399 if (isGP64bit()) {
3400 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3401 IDLoc, Out, STI))
3402 return true;
3403 } else {
3404 if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3405 IDLoc, Out, STI))
3406 return true;
3408 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3409 IDLoc, Out, STI))
3410 return true;
3412 return false;
3415 MCSection *CS = getStreamer().getCurrentSectionOnly();
3416 MCSection *ReadOnlySection =
3417 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3419 MCSymbol *Sym = getContext().createTempSymbol();
3420 const MCExpr *LoSym =
3421 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3422 const MipsMCExpr *LoExpr =
3423 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3425 getStreamer().SwitchSection(ReadOnlySection);
3426 getStreamer().EmitLabel(Sym, IDLoc);
3427 getStreamer().EmitValueToAlignment(8);
3428 getStreamer().EmitIntValue(ImmOp64, 8);
3429 getStreamer().SwitchSection(CS);
3431 unsigned TmpReg = getATReg(IDLoc);
3432 if (!TmpReg)
3433 return true;
3435 if (emitPartialAddress(TOut, IDLoc, Sym))
3436 return true;
3438 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3439 MCOperand::createExpr(LoExpr), IDLoc, STI);
3441 if (isGP64bit())
3442 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3443 else {
3444 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3445 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3447 return false;
3450 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3451 SMLoc IDLoc, MCStreamer &Out,
3452 const MCSubtargetInfo *STI) {
3453 MipsTargetStreamer &TOut = getTargetStreamer();
3454 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3455 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3456 "Invalid instruction operand.");
3458 unsigned FirstReg = Inst.getOperand(0).getReg();
3459 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3461 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3463 unsigned TmpReg = Mips::ZERO;
3464 if (ImmOp64 != 0) {
3465 TmpReg = getATReg(IDLoc);
3466 if (!TmpReg)
3467 return true;
3470 if ((Lo_32(ImmOp64) == 0) &&
3471 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3472 if (isGP64bit()) {
3473 if (TmpReg != Mips::ZERO &&
3474 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3475 Out, STI))
3476 return true;
3477 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3478 return false;
3481 if (TmpReg != Mips::ZERO &&
3482 loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3483 IDLoc, Out, STI))
3484 return true;
3486 if (hasMips32r2()) {
3487 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3488 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3489 } else {
3490 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3491 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3493 return false;
3496 MCSection *CS = getStreamer().getCurrentSectionOnly();
3497 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3498 // where appropriate.
3499 MCSection *ReadOnlySection =
3500 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3502 MCSymbol *Sym = getContext().createTempSymbol();
3503 const MCExpr *LoSym =
3504 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3505 const MipsMCExpr *LoExpr =
3506 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3508 getStreamer().SwitchSection(ReadOnlySection);
3509 getStreamer().EmitLabel(Sym, IDLoc);
3510 getStreamer().EmitValueToAlignment(8);
3511 getStreamer().EmitIntValue(ImmOp64, 8);
3512 getStreamer().SwitchSection(CS);
3514 if (emitPartialAddress(TOut, IDLoc, Sym))
3515 return true;
3517 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3518 MCOperand::createExpr(LoExpr), IDLoc, STI);
3520 return false;
3523 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3524 MCStreamer &Out,
3525 const MCSubtargetInfo *STI) {
3526 MipsTargetStreamer &TOut = getTargetStreamer();
3528 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3529 "unexpected number of operands");
3531 MCOperand Offset = Inst.getOperand(0);
3532 if (Offset.isExpr()) {
3533 Inst.clear();
3534 Inst.setOpcode(Mips::BEQ_MM);
3535 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3536 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3537 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3538 } else {
3539 assert(Offset.isImm() && "expected immediate operand kind");
3540 if (isInt<11>(Offset.getImm())) {
3541 // If offset fits into 11 bits then this instruction becomes microMIPS
3542 // 16-bit unconditional branch instruction.
3543 if (inMicroMipsMode())
3544 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3545 } else {
3546 if (!isInt<17>(Offset.getImm()))
3547 return Error(IDLoc, "branch target out of range");
3548 if (offsetToAlignment(Offset.getImm(), Align(2)))
3549 return Error(IDLoc, "branch to misaligned address");
3550 Inst.clear();
3551 Inst.setOpcode(Mips::BEQ_MM);
3552 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3553 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3554 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3557 Out.EmitInstruction(Inst, *STI);
3559 // If .set reorder is active and branch instruction has a delay slot,
3560 // emit a NOP after it.
3561 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3562 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3563 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3565 return false;
3568 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3569 const MCSubtargetInfo *STI) {
3570 MipsTargetStreamer &TOut = getTargetStreamer();
3571 const MCOperand &DstRegOp = Inst.getOperand(0);
3572 assert(DstRegOp.isReg() && "expected register operand kind");
3574 const MCOperand &ImmOp = Inst.getOperand(1);
3575 assert(ImmOp.isImm() && "expected immediate operand kind");
3577 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3578 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3579 "expected immediate or expression operand");
3581 bool IsLikely = false;
3583 unsigned OpCode = 0;
3584 switch(Inst.getOpcode()) {
3585 case Mips::BneImm:
3586 OpCode = Mips::BNE;
3587 break;
3588 case Mips::BeqImm:
3589 OpCode = Mips::BEQ;
3590 break;
3591 case Mips::BEQLImmMacro:
3592 OpCode = Mips::BEQL;
3593 IsLikely = true;
3594 break;
3595 case Mips::BNELImmMacro:
3596 OpCode = Mips::BNEL;
3597 IsLikely = true;
3598 break;
3599 default:
3600 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3601 break;
3604 int64_t ImmValue = ImmOp.getImm();
3605 if (ImmValue == 0) {
3606 if (IsLikely) {
3607 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3608 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3609 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3610 } else
3611 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3612 STI);
3613 } else {
3614 warnIfNoMacro(IDLoc);
3616 unsigned ATReg = getATReg(IDLoc);
3617 if (!ATReg)
3618 return true;
3620 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3621 IDLoc, Out, STI))
3622 return true;
3624 if (IsLikely) {
3625 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3626 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3627 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3628 } else
3629 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3631 return false;
3634 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3635 const MCSubtargetInfo *STI, bool IsLoad) {
3636 const MCOperand &DstRegOp = Inst.getOperand(0);
3637 assert(DstRegOp.isReg() && "expected register operand kind");
3638 const MCOperand &BaseRegOp = Inst.getOperand(1);
3639 assert(BaseRegOp.isReg() && "expected register operand kind");
3641 MipsTargetStreamer &TOut = getTargetStreamer();
3642 unsigned DstReg = DstRegOp.getReg();
3643 unsigned BaseReg = BaseRegOp.getReg();
3644 unsigned TmpReg = DstReg;
3646 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3647 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3648 unsigned DstRegClassID =
3649 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3650 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3651 (DstRegClassID == Mips::GPR64RegClassID);
3653 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3654 // At this point we need AT to perform the expansions
3655 // and we exit if it is not available.
3656 TmpReg = getATReg(IDLoc);
3657 if (!TmpReg)
3658 return;
3661 if (Inst.getNumOperands() > 3) {
3662 const MCOperand &BaseRegOp = Inst.getOperand(2);
3663 assert(BaseRegOp.isReg() && "expected register operand kind");
3664 const MCOperand &ExprOp = Inst.getOperand(3);
3665 assert(ExprOp.isExpr() && "expected expression oprand kind");
3667 unsigned BaseReg = BaseRegOp.getReg();
3668 const MCExpr *ExprOffset = ExprOp.getExpr();
3670 MCOperand LoOperand = MCOperand::createExpr(
3671 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3672 MCOperand HiOperand = MCOperand::createExpr(
3673 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3674 TOut.emitSCWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3675 LoOperand, TmpReg, IDLoc, STI);
3676 return;
3679 const MCOperand &OffsetOp = Inst.getOperand(2);
3681 if (OffsetOp.isImm()) {
3682 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3683 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3685 // If msb of LoOffset is 1(negative number) we must increment
3686 // HiOffset to account for the sign-extension of the low part.
3687 if (LoOffset & 0x8000)
3688 HiOffset += 0x10000;
3690 bool IsLargeOffset = HiOffset != 0;
3692 if (IsLargeOffset) {
3693 bool Is32BitImm = (HiOffset >> 32) == 0;
3694 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3695 IDLoc, Out, STI))
3696 return;
3699 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3700 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3701 BaseReg, IDLoc, STI);
3702 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3703 return;
3706 if (OffsetOp.isExpr()) {
3707 if (inPicMode()) {
3708 // FIXME:
3709 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3710 // do not exceed 16-bit.
3711 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3712 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3713 // of GOT entries.
3714 MCValue Res;
3715 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3716 Error(IDLoc, "expected relocatable expression");
3717 return;
3719 if (Res.getSymB() != nullptr) {
3720 Error(IDLoc, "expected relocatable expression with only one symbol");
3721 return;
3724 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3725 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3726 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, Res.getConstant(), IDLoc,
3727 STI);
3728 } else {
3729 // FIXME: Implement 64-bit case.
3730 // 1) lw $8, sym => lui $8, %hi(sym)
3731 // lw $8, %lo(sym)($8)
3732 // 2) sw $8, sym => lui $at, %hi(sym)
3733 // sw $8, %lo(sym)($at)
3734 const MCExpr *ExprOffset = OffsetOp.getExpr();
3735 MCOperand LoOperand = MCOperand::createExpr(
3736 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3737 MCOperand HiOperand = MCOperand::createExpr(
3738 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3740 // Generate the base address in TmpReg.
3741 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3742 if (BaseReg != Mips::ZERO)
3743 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3744 // Emit the load or store with the adjusted base and offset.
3745 TOut.emitRRX(Inst.getOpcode(), DstReg, TmpReg, LoOperand, IDLoc, STI);
3747 return;
3750 llvm_unreachable("unexpected operand type");
3753 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3754 MCStreamer &Out,
3755 const MCSubtargetInfo *STI) {
3756 unsigned OpNum = Inst.getNumOperands();
3757 unsigned Opcode = Inst.getOpcode();
3758 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3760 assert(Inst.getOperand(OpNum - 1).isImm() &&
3761 Inst.getOperand(OpNum - 2).isReg() &&
3762 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3764 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3765 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3766 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3767 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3768 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3769 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3770 // It can be implemented as SWM16 or LWM16 instruction.
3771 if (inMicroMipsMode() && hasMips32r6())
3772 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3773 else
3774 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3777 Inst.setOpcode(NewOpcode);
3778 Out.EmitInstruction(Inst, *STI);
3779 return false;
3782 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3783 MCStreamer &Out,
3784 const MCSubtargetInfo *STI) {
3785 MipsTargetStreamer &TOut = getTargetStreamer();
3786 bool EmittedNoMacroWarning = false;
3787 unsigned PseudoOpcode = Inst.getOpcode();
3788 unsigned SrcReg = Inst.getOperand(0).getReg();
3789 const MCOperand &TrgOp = Inst.getOperand(1);
3790 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3792 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3793 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3795 unsigned TrgReg;
3796 if (TrgOp.isReg())
3797 TrgReg = TrgOp.getReg();
3798 else if (TrgOp.isImm()) {
3799 warnIfNoMacro(IDLoc);
3800 EmittedNoMacroWarning = true;
3802 TrgReg = getATReg(IDLoc);
3803 if (!TrgReg)
3804 return true;
3806 switch(PseudoOpcode) {
3807 default:
3808 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3809 case Mips::BLTImmMacro:
3810 PseudoOpcode = Mips::BLT;
3811 break;
3812 case Mips::BLEImmMacro:
3813 PseudoOpcode = Mips::BLE;
3814 break;
3815 case Mips::BGEImmMacro:
3816 PseudoOpcode = Mips::BGE;
3817 break;
3818 case Mips::BGTImmMacro:
3819 PseudoOpcode = Mips::BGT;
3820 break;
3821 case Mips::BLTUImmMacro:
3822 PseudoOpcode = Mips::BLTU;
3823 break;
3824 case Mips::BLEUImmMacro:
3825 PseudoOpcode = Mips::BLEU;
3826 break;
3827 case Mips::BGEUImmMacro:
3828 PseudoOpcode = Mips::BGEU;
3829 break;
3830 case Mips::BGTUImmMacro:
3831 PseudoOpcode = Mips::BGTU;
3832 break;
3833 case Mips::BLTLImmMacro:
3834 PseudoOpcode = Mips::BLTL;
3835 break;
3836 case Mips::BLELImmMacro:
3837 PseudoOpcode = Mips::BLEL;
3838 break;
3839 case Mips::BGELImmMacro:
3840 PseudoOpcode = Mips::BGEL;
3841 break;
3842 case Mips::BGTLImmMacro:
3843 PseudoOpcode = Mips::BGTL;
3844 break;
3845 case Mips::BLTULImmMacro:
3846 PseudoOpcode = Mips::BLTUL;
3847 break;
3848 case Mips::BLEULImmMacro:
3849 PseudoOpcode = Mips::BLEUL;
3850 break;
3851 case Mips::BGEULImmMacro:
3852 PseudoOpcode = Mips::BGEUL;
3853 break;
3854 case Mips::BGTULImmMacro:
3855 PseudoOpcode = Mips::BGTUL;
3856 break;
3859 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3860 false, IDLoc, Out, STI))
3861 return true;
3864 switch (PseudoOpcode) {
3865 case Mips::BLT:
3866 case Mips::BLTU:
3867 case Mips::BLTL:
3868 case Mips::BLTUL:
3869 AcceptsEquality = false;
3870 ReverseOrderSLT = false;
3871 IsUnsigned =
3872 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3873 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3874 ZeroSrcOpcode = Mips::BGTZ;
3875 ZeroTrgOpcode = Mips::BLTZ;
3876 break;
3877 case Mips::BLE:
3878 case Mips::BLEU:
3879 case Mips::BLEL:
3880 case Mips::BLEUL:
3881 AcceptsEquality = true;
3882 ReverseOrderSLT = true;
3883 IsUnsigned =
3884 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3885 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3886 ZeroSrcOpcode = Mips::BGEZ;
3887 ZeroTrgOpcode = Mips::BLEZ;
3888 break;
3889 case Mips::BGE:
3890 case Mips::BGEU:
3891 case Mips::BGEL:
3892 case Mips::BGEUL:
3893 AcceptsEquality = true;
3894 ReverseOrderSLT = false;
3895 IsUnsigned =
3896 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3897 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3898 ZeroSrcOpcode = Mips::BLEZ;
3899 ZeroTrgOpcode = Mips::BGEZ;
3900 break;
3901 case Mips::BGT:
3902 case Mips::BGTU:
3903 case Mips::BGTL:
3904 case Mips::BGTUL:
3905 AcceptsEquality = false;
3906 ReverseOrderSLT = true;
3907 IsUnsigned =
3908 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3909 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3910 ZeroSrcOpcode = Mips::BLTZ;
3911 ZeroTrgOpcode = Mips::BGTZ;
3912 break;
3913 default:
3914 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3917 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3918 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3919 if (IsSrcRegZero && IsTrgRegZero) {
3920 // FIXME: All of these Opcode-specific if's are needed for compatibility
3921 // with GAS' behaviour. However, they may not generate the most efficient
3922 // code in some circumstances.
3923 if (PseudoOpcode == Mips::BLT) {
3924 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3925 IDLoc, STI);
3926 return false;
3928 if (PseudoOpcode == Mips::BLE) {
3929 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3930 IDLoc, STI);
3931 Warning(IDLoc, "branch is always taken");
3932 return false;
3934 if (PseudoOpcode == Mips::BGE) {
3935 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3936 IDLoc, STI);
3937 Warning(IDLoc, "branch is always taken");
3938 return false;
3940 if (PseudoOpcode == Mips::BGT) {
3941 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3942 IDLoc, STI);
3943 return false;
3945 if (PseudoOpcode == Mips::BGTU) {
3946 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3947 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3948 return false;
3950 if (AcceptsEquality) {
3951 // If both registers are $0 and the pseudo-branch accepts equality, it
3952 // will always be taken, so we emit an unconditional branch.
3953 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3954 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3955 Warning(IDLoc, "branch is always taken");
3956 return false;
3958 // If both registers are $0 and the pseudo-branch does not accept
3959 // equality, it will never be taken, so we don't have to emit anything.
3960 return false;
3962 if (IsSrcRegZero || IsTrgRegZero) {
3963 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3964 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3965 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3966 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3967 // the pseudo-branch will never be taken, so we don't emit anything.
3968 // This only applies to unsigned pseudo-branches.
3969 return false;
3971 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3972 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3973 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3974 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3975 // the pseudo-branch will always be taken, so we emit an unconditional
3976 // branch.
3977 // This only applies to unsigned pseudo-branches.
3978 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3979 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3980 Warning(IDLoc, "branch is always taken");
3981 return false;
3983 if (IsUnsigned) {
3984 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3985 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3986 // the pseudo-branch will be taken only when the non-zero register is
3987 // different from 0, so we emit a BNEZ.
3989 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3990 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3991 // the pseudo-branch will be taken only when the non-zero register is
3992 // equal to 0, so we emit a BEQZ.
3994 // Because only BLEU and BGEU branch on equality, we can use the
3995 // AcceptsEquality variable to decide when to emit the BEQZ.
3996 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3997 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3998 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3999 return false;
4001 // If we have a signed pseudo-branch and one of the registers is $0,
4002 // we can use an appropriate compare-to-zero branch. We select which one
4003 // to use in the switch statement above.
4004 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4005 IsSrcRegZero ? TrgReg : SrcReg,
4006 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4007 return false;
4010 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4011 // expansions. If it is not available, we return.
4012 unsigned ATRegNum = getATReg(IDLoc);
4013 if (!ATRegNum)
4014 return true;
4016 if (!EmittedNoMacroWarning)
4017 warnIfNoMacro(IDLoc);
4019 // SLT fits well with 2 of our 4 pseudo-branches:
4020 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4021 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4022 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4023 // This is accomplished by using a BNEZ with the result of the SLT.
4025 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4026 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4027 // Because only BGE and BLE branch on equality, we can use the
4028 // AcceptsEquality variable to decide when to emit the BEQZ.
4029 // Note that the order of the SLT arguments doesn't change between
4030 // opposites.
4032 // The same applies to the unsigned variants, except that SLTu is used
4033 // instead of SLT.
4034 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4035 ReverseOrderSLT ? TrgReg : SrcReg,
4036 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4038 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4039 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4040 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4041 STI);
4042 return false;
4045 // Expand a integer division macro.
4047 // Notably we don't have to emit a warning when encountering $rt as the $zero
4048 // register, or 0 as an immediate. processInstruction() has already done that.
4050 // The destination register can only be $zero when expanding (S)DivIMacro or
4051 // D(S)DivMacro.
4053 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4054 const MCSubtargetInfo *STI, const bool IsMips64,
4055 const bool Signed) {
4056 MipsTargetStreamer &TOut = getTargetStreamer();
4058 warnIfNoMacro(IDLoc);
4060 const MCOperand &RdRegOp = Inst.getOperand(0);
4061 assert(RdRegOp.isReg() && "expected register operand kind");
4062 unsigned RdReg = RdRegOp.getReg();
4064 const MCOperand &RsRegOp = Inst.getOperand(1);
4065 assert(RsRegOp.isReg() && "expected register operand kind");
4066 unsigned RsReg = RsRegOp.getReg();
4068 unsigned RtReg;
4069 int64_t ImmValue;
4071 const MCOperand &RtOp = Inst.getOperand(2);
4072 assert((RtOp.isReg() || RtOp.isImm()) &&
4073 "expected register or immediate operand kind");
4074 if (RtOp.isReg())
4075 RtReg = RtOp.getReg();
4076 else
4077 ImmValue = RtOp.getImm();
4079 unsigned DivOp;
4080 unsigned ZeroReg;
4081 unsigned SubOp;
4083 if (IsMips64) {
4084 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4085 ZeroReg = Mips::ZERO_64;
4086 SubOp = Mips::DSUB;
4087 } else {
4088 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4089 ZeroReg = Mips::ZERO;
4090 SubOp = Mips::SUB;
4093 bool UseTraps = useTraps();
4095 unsigned Opcode = Inst.getOpcode();
4096 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4097 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4098 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4099 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4101 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4102 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4103 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4104 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4106 if (RtOp.isImm()) {
4107 unsigned ATReg = getATReg(IDLoc);
4108 if (!ATReg)
4109 return true;
4111 if (ImmValue == 0) {
4112 if (UseTraps)
4113 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4114 else
4115 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4116 return false;
4119 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4120 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4121 return false;
4122 } else if (isDiv && ImmValue == 1) {
4123 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4124 return false;
4125 } else if (isDiv && Signed && ImmValue == -1) {
4126 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4127 return false;
4128 } else {
4129 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4130 false, Inst.getLoc(), Out, STI))
4131 return true;
4132 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4133 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4134 return false;
4136 return true;
4139 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4140 // break, insert the trap/break and exit. This gives a different result to
4141 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4142 // are handled equivalently. As the observed behaviour is the same, we're ok.
4143 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4144 if (UseTraps) {
4145 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4146 return false;
4148 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4149 return false;
4152 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4153 // not expand to macro sequence.
4154 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4155 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4156 return false;
4159 // Temporary label for first branch traget
4160 MCContext &Context = TOut.getStreamer().getContext();
4161 MCSymbol *BrTarget;
4162 MCOperand LabelOp;
4164 if (UseTraps) {
4165 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4166 } else {
4167 // Branch to the li instruction.
4168 BrTarget = Context.createTempSymbol();
4169 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4170 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4173 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4175 if (!UseTraps)
4176 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4178 if (!Signed) {
4179 if (!UseTraps)
4180 TOut.getStreamer().EmitLabel(BrTarget);
4182 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4183 return false;
4186 unsigned ATReg = getATReg(IDLoc);
4187 if (!ATReg)
4188 return true;
4190 if (!UseTraps)
4191 TOut.getStreamer().EmitLabel(BrTarget);
4193 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4195 // Temporary label for the second branch target.
4196 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4197 MCOperand LabelOpEnd =
4198 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4200 // Branch to the mflo instruction.
4201 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4203 if (IsMips64) {
4204 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4205 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4206 } else {
4207 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4210 if (UseTraps)
4211 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4212 else {
4213 // Branch to the mflo instruction.
4214 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4215 TOut.emitNop(IDLoc, STI);
4216 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4219 TOut.getStreamer().EmitLabel(BrTargetEnd);
4220 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4221 return false;
4224 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4225 SMLoc IDLoc, MCStreamer &Out,
4226 const MCSubtargetInfo *STI) {
4227 MipsTargetStreamer &TOut = getTargetStreamer();
4229 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4230 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4231 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4233 unsigned FirstReg = Inst.getOperand(0).getReg();
4234 unsigned SecondReg = Inst.getOperand(1).getReg();
4235 unsigned ThirdReg = Inst.getOperand(2).getReg();
4237 if (hasMips1() && !hasMips2()) {
4238 unsigned ATReg = getATReg(IDLoc);
4239 if (!ATReg)
4240 return true;
4241 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4242 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4243 TOut.emitNop(IDLoc, STI);
4244 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4245 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4246 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4247 TOut.emitNop(IDLoc, STI);
4248 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4249 : Mips::CVT_W_S,
4250 FirstReg, SecondReg, IDLoc, STI);
4251 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4252 TOut.emitNop(IDLoc, STI);
4253 return false;
4256 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4257 : Mips::TRUNC_W_S,
4258 FirstReg, SecondReg, IDLoc, STI);
4260 return false;
4263 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4264 MCStreamer &Out, const MCSubtargetInfo *STI) {
4265 if (hasMips32r6() || hasMips64r6()) {
4266 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4269 const MCOperand &DstRegOp = Inst.getOperand(0);
4270 assert(DstRegOp.isReg() && "expected register operand kind");
4271 const MCOperand &SrcRegOp = Inst.getOperand(1);
4272 assert(SrcRegOp.isReg() && "expected register operand kind");
4273 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4274 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4276 MipsTargetStreamer &TOut = getTargetStreamer();
4277 unsigned DstReg = DstRegOp.getReg();
4278 unsigned SrcReg = SrcRegOp.getReg();
4279 int64_t OffsetValue = OffsetImmOp.getImm();
4281 // NOTE: We always need AT for ULHU, as it is always used as the source
4282 // register for one of the LBu's.
4283 warnIfNoMacro(IDLoc);
4284 unsigned ATReg = getATReg(IDLoc);
4285 if (!ATReg)
4286 return true;
4288 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4289 if (IsLargeOffset) {
4290 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4291 IDLoc, Out, STI))
4292 return true;
4295 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4296 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4297 if (isLittle())
4298 std::swap(FirstOffset, SecondOffset);
4300 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4301 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4303 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4304 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4306 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4307 FirstOffset, IDLoc, STI);
4308 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4309 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4310 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4312 return false;
4315 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4316 const MCSubtargetInfo *STI) {
4317 if (hasMips32r6() || hasMips64r6()) {
4318 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4321 const MCOperand &DstRegOp = Inst.getOperand(0);
4322 assert(DstRegOp.isReg() && "expected register operand kind");
4323 const MCOperand &SrcRegOp = Inst.getOperand(1);
4324 assert(SrcRegOp.isReg() && "expected register operand kind");
4325 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4326 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4328 MipsTargetStreamer &TOut = getTargetStreamer();
4329 unsigned DstReg = DstRegOp.getReg();
4330 unsigned SrcReg = SrcRegOp.getReg();
4331 int64_t OffsetValue = OffsetImmOp.getImm();
4333 warnIfNoMacro(IDLoc);
4334 unsigned ATReg = getATReg(IDLoc);
4335 if (!ATReg)
4336 return true;
4338 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4339 if (IsLargeOffset) {
4340 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4341 IDLoc, Out, STI))
4342 return true;
4345 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4346 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4347 if (isLittle())
4348 std::swap(FirstOffset, SecondOffset);
4350 if (IsLargeOffset) {
4351 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4352 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4353 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4354 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4355 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4356 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4357 } else {
4358 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4359 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4360 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4363 return false;
4366 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4367 const MCSubtargetInfo *STI) {
4368 if (hasMips32r6() || hasMips64r6()) {
4369 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4372 const MCOperand &DstRegOp = Inst.getOperand(0);
4373 assert(DstRegOp.isReg() && "expected register operand kind");
4374 const MCOperand &SrcRegOp = Inst.getOperand(1);
4375 assert(SrcRegOp.isReg() && "expected register operand kind");
4376 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4377 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4379 MipsTargetStreamer &TOut = getTargetStreamer();
4380 unsigned DstReg = DstRegOp.getReg();
4381 unsigned SrcReg = SrcRegOp.getReg();
4382 int64_t OffsetValue = OffsetImmOp.getImm();
4384 // Compute left/right load/store offsets.
4385 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4386 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4387 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4388 if (isLittle())
4389 std::swap(LxlOffset, LxrOffset);
4391 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4392 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4393 unsigned TmpReg = SrcReg;
4394 if (IsLargeOffset || DoMove) {
4395 warnIfNoMacro(IDLoc);
4396 TmpReg = getATReg(IDLoc);
4397 if (!TmpReg)
4398 return true;
4401 if (IsLargeOffset) {
4402 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4403 IDLoc, Out, STI))
4404 return true;
4407 if (DoMove)
4408 std::swap(DstReg, TmpReg);
4410 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4411 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4412 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4413 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4415 if (DoMove)
4416 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4418 return false;
4421 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4422 const MCSubtargetInfo *STI) {
4423 MipsTargetStreamer &TOut = getTargetStreamer();
4425 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4426 assert(Inst.getOperand(0).isReg() &&
4427 Inst.getOperand(1).isReg() &&
4428 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4430 unsigned DstReg = Inst.getOperand(0).getReg();
4431 unsigned SrcReg = Inst.getOperand(1).getReg();
4432 unsigned OpReg = Inst.getOperand(2).getReg();
4433 unsigned OpCode;
4435 warnIfNoMacro(IDLoc);
4437 switch (Inst.getOpcode()) {
4438 case Mips::SGE:
4439 OpCode = Mips::SLT;
4440 break;
4441 case Mips::SGEU:
4442 OpCode = Mips::SLTu;
4443 break;
4444 default:
4445 llvm_unreachable("unexpected 'sge' opcode");
4448 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4449 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4450 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4452 return false;
4455 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4456 const MCSubtargetInfo *STI) {
4457 MipsTargetStreamer &TOut = getTargetStreamer();
4459 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4460 assert(Inst.getOperand(0).isReg() &&
4461 Inst.getOperand(1).isReg() &&
4462 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4464 unsigned DstReg = Inst.getOperand(0).getReg();
4465 unsigned SrcReg = Inst.getOperand(1).getReg();
4466 int64_t ImmValue = Inst.getOperand(2).getImm();
4467 unsigned OpRegCode, OpImmCode;
4469 warnIfNoMacro(IDLoc);
4471 switch (Inst.getOpcode()) {
4472 case Mips::SGEImm:
4473 case Mips::SGEImm64:
4474 OpRegCode = Mips::SLT;
4475 OpImmCode = Mips::SLTi;
4476 break;
4477 case Mips::SGEUImm:
4478 case Mips::SGEUImm64:
4479 OpRegCode = Mips::SLTu;
4480 OpImmCode = Mips::SLTiu;
4481 break;
4482 default:
4483 llvm_unreachable("unexpected 'sge' opcode with immediate");
4486 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4487 if (isInt<16>(ImmValue)) {
4488 // Use immediate version of STL.
4489 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4490 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4491 } else {
4492 unsigned ImmReg = DstReg;
4493 if (DstReg == SrcReg) {
4494 unsigned ATReg = getATReg(Inst.getLoc());
4495 if (!ATReg)
4496 return true;
4497 ImmReg = ATReg;
4500 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4501 false, IDLoc, Out, STI))
4502 return true;
4504 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4505 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4508 return false;
4511 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4512 const MCSubtargetInfo *STI) {
4513 MipsTargetStreamer &TOut = getTargetStreamer();
4515 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4516 assert(Inst.getOperand(0).isReg() &&
4517 Inst.getOperand(1).isReg() &&
4518 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4520 unsigned DstReg = Inst.getOperand(0).getReg();
4521 unsigned SrcReg = Inst.getOperand(1).getReg();
4522 unsigned ImmReg = DstReg;
4523 int64_t ImmValue = Inst.getOperand(2).getImm();
4524 unsigned OpCode;
4526 warnIfNoMacro(IDLoc);
4528 switch (Inst.getOpcode()) {
4529 case Mips::SGTImm:
4530 case Mips::SGTImm64:
4531 OpCode = Mips::SLT;
4532 break;
4533 case Mips::SGTUImm:
4534 case Mips::SGTUImm64:
4535 OpCode = Mips::SLTu;
4536 break;
4537 default:
4538 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4541 if (DstReg == SrcReg) {
4542 unsigned ATReg = getATReg(Inst.getLoc());
4543 if (!ATReg)
4544 return true;
4545 ImmReg = ATReg;
4548 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4549 false, IDLoc, Out, STI))
4550 return true;
4552 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4553 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4555 return false;
4558 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4559 MCStreamer &Out,
4560 const MCSubtargetInfo *STI) {
4561 MipsTargetStreamer &TOut = getTargetStreamer();
4563 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4564 assert(Inst.getOperand(0).isReg() &&
4565 Inst.getOperand(1).isReg() &&
4566 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4568 unsigned ATReg = Mips::NoRegister;
4569 unsigned FinalDstReg = Mips::NoRegister;
4570 unsigned DstReg = Inst.getOperand(0).getReg();
4571 unsigned SrcReg = Inst.getOperand(1).getReg();
4572 int64_t ImmValue = Inst.getOperand(2).getImm();
4574 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4576 unsigned FinalOpcode = Inst.getOpcode();
4578 if (DstReg == SrcReg) {
4579 ATReg = getATReg(Inst.getLoc());
4580 if (!ATReg)
4581 return true;
4582 FinalDstReg = DstReg;
4583 DstReg = ATReg;
4586 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4587 Inst.getLoc(), Out, STI)) {
4588 switch (FinalOpcode) {
4589 default:
4590 llvm_unreachable("unimplemented expansion");
4591 case Mips::ADDi:
4592 FinalOpcode = Mips::ADD;
4593 break;
4594 case Mips::ADDiu:
4595 FinalOpcode = Mips::ADDu;
4596 break;
4597 case Mips::ANDi:
4598 FinalOpcode = Mips::AND;
4599 break;
4600 case Mips::NORImm:
4601 FinalOpcode = Mips::NOR;
4602 break;
4603 case Mips::ORi:
4604 FinalOpcode = Mips::OR;
4605 break;
4606 case Mips::SLTi:
4607 FinalOpcode = Mips::SLT;
4608 break;
4609 case Mips::SLTiu:
4610 FinalOpcode = Mips::SLTu;
4611 break;
4612 case Mips::XORi:
4613 FinalOpcode = Mips::XOR;
4614 break;
4615 case Mips::ADDi_MM:
4616 FinalOpcode = Mips::ADD_MM;
4617 break;
4618 case Mips::ADDiu_MM:
4619 FinalOpcode = Mips::ADDu_MM;
4620 break;
4621 case Mips::ANDi_MM:
4622 FinalOpcode = Mips::AND_MM;
4623 break;
4624 case Mips::ORi_MM:
4625 FinalOpcode = Mips::OR_MM;
4626 break;
4627 case Mips::SLTi_MM:
4628 FinalOpcode = Mips::SLT_MM;
4629 break;
4630 case Mips::SLTiu_MM:
4631 FinalOpcode = Mips::SLTu_MM;
4632 break;
4633 case Mips::XORi_MM:
4634 FinalOpcode = Mips::XOR_MM;
4635 break;
4636 case Mips::ANDi64:
4637 FinalOpcode = Mips::AND64;
4638 break;
4639 case Mips::NORImm64:
4640 FinalOpcode = Mips::NOR64;
4641 break;
4642 case Mips::ORi64:
4643 FinalOpcode = Mips::OR64;
4644 break;
4645 case Mips::SLTImm64:
4646 FinalOpcode = Mips::SLT64;
4647 break;
4648 case Mips::SLTUImm64:
4649 FinalOpcode = Mips::SLTu64;
4650 break;
4651 case Mips::XORi64:
4652 FinalOpcode = Mips::XOR64;
4653 break;
4656 if (FinalDstReg == Mips::NoRegister)
4657 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4658 else
4659 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4660 return false;
4662 return true;
4665 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4666 const MCSubtargetInfo *STI) {
4667 MipsTargetStreamer &TOut = getTargetStreamer();
4668 unsigned ATReg = Mips::NoRegister;
4669 unsigned DReg = Inst.getOperand(0).getReg();
4670 unsigned SReg = Inst.getOperand(1).getReg();
4671 unsigned TReg = Inst.getOperand(2).getReg();
4672 unsigned TmpReg = DReg;
4674 unsigned FirstShift = Mips::NOP;
4675 unsigned SecondShift = Mips::NOP;
4677 if (hasMips32r2()) {
4678 if (DReg == SReg) {
4679 TmpReg = getATReg(Inst.getLoc());
4680 if (!TmpReg)
4681 return true;
4684 if (Inst.getOpcode() == Mips::ROL) {
4685 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4686 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4687 return false;
4690 if (Inst.getOpcode() == Mips::ROR) {
4691 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4692 return false;
4695 return true;
4698 if (hasMips32()) {
4699 switch (Inst.getOpcode()) {
4700 default:
4701 llvm_unreachable("unexpected instruction opcode");
4702 case Mips::ROL:
4703 FirstShift = Mips::SRLV;
4704 SecondShift = Mips::SLLV;
4705 break;
4706 case Mips::ROR:
4707 FirstShift = Mips::SLLV;
4708 SecondShift = Mips::SRLV;
4709 break;
4712 ATReg = getATReg(Inst.getLoc());
4713 if (!ATReg)
4714 return true;
4716 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4717 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4718 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4719 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4721 return false;
4724 return true;
4727 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4728 MCStreamer &Out,
4729 const MCSubtargetInfo *STI) {
4730 MipsTargetStreamer &TOut = getTargetStreamer();
4731 unsigned ATReg = Mips::NoRegister;
4732 unsigned DReg = Inst.getOperand(0).getReg();
4733 unsigned SReg = Inst.getOperand(1).getReg();
4734 int64_t ImmValue = Inst.getOperand(2).getImm();
4736 unsigned FirstShift = Mips::NOP;
4737 unsigned SecondShift = Mips::NOP;
4739 if (hasMips32r2()) {
4740 if (Inst.getOpcode() == Mips::ROLImm) {
4741 uint64_t MaxShift = 32;
4742 uint64_t ShiftValue = ImmValue;
4743 if (ImmValue != 0)
4744 ShiftValue = MaxShift - ImmValue;
4745 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4746 return false;
4749 if (Inst.getOpcode() == Mips::RORImm) {
4750 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4751 return false;
4754 return true;
4757 if (hasMips32()) {
4758 if (ImmValue == 0) {
4759 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4760 return false;
4763 switch (Inst.getOpcode()) {
4764 default:
4765 llvm_unreachable("unexpected instruction opcode");
4766 case Mips::ROLImm:
4767 FirstShift = Mips::SLL;
4768 SecondShift = Mips::SRL;
4769 break;
4770 case Mips::RORImm:
4771 FirstShift = Mips::SRL;
4772 SecondShift = Mips::SLL;
4773 break;
4776 ATReg = getATReg(Inst.getLoc());
4777 if (!ATReg)
4778 return true;
4780 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4781 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4782 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4784 return false;
4787 return true;
4790 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4791 const MCSubtargetInfo *STI) {
4792 MipsTargetStreamer &TOut = getTargetStreamer();
4793 unsigned ATReg = Mips::NoRegister;
4794 unsigned DReg = Inst.getOperand(0).getReg();
4795 unsigned SReg = Inst.getOperand(1).getReg();
4796 unsigned TReg = Inst.getOperand(2).getReg();
4797 unsigned TmpReg = DReg;
4799 unsigned FirstShift = Mips::NOP;
4800 unsigned SecondShift = Mips::NOP;
4802 if (hasMips64r2()) {
4803 if (TmpReg == SReg) {
4804 TmpReg = getATReg(Inst.getLoc());
4805 if (!TmpReg)
4806 return true;
4809 if (Inst.getOpcode() == Mips::DROL) {
4810 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4811 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4812 return false;
4815 if (Inst.getOpcode() == Mips::DROR) {
4816 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4817 return false;
4820 return true;
4823 if (hasMips64()) {
4824 switch (Inst.getOpcode()) {
4825 default:
4826 llvm_unreachable("unexpected instruction opcode");
4827 case Mips::DROL:
4828 FirstShift = Mips::DSRLV;
4829 SecondShift = Mips::DSLLV;
4830 break;
4831 case Mips::DROR:
4832 FirstShift = Mips::DSLLV;
4833 SecondShift = Mips::DSRLV;
4834 break;
4837 ATReg = getATReg(Inst.getLoc());
4838 if (!ATReg)
4839 return true;
4841 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4842 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4843 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4844 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4846 return false;
4849 return true;
4852 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4853 MCStreamer &Out,
4854 const MCSubtargetInfo *STI) {
4855 MipsTargetStreamer &TOut = getTargetStreamer();
4856 unsigned ATReg = Mips::NoRegister;
4857 unsigned DReg = Inst.getOperand(0).getReg();
4858 unsigned SReg = Inst.getOperand(1).getReg();
4859 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4861 unsigned FirstShift = Mips::NOP;
4862 unsigned SecondShift = Mips::NOP;
4864 MCInst TmpInst;
4866 if (hasMips64r2()) {
4867 unsigned FinalOpcode = Mips::NOP;
4868 if (ImmValue == 0)
4869 FinalOpcode = Mips::DROTR;
4870 else if (ImmValue % 32 == 0)
4871 FinalOpcode = Mips::DROTR32;
4872 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4873 if (Inst.getOpcode() == Mips::DROLImm)
4874 FinalOpcode = Mips::DROTR32;
4875 else
4876 FinalOpcode = Mips::DROTR;
4877 } else if (ImmValue >= 33) {
4878 if (Inst.getOpcode() == Mips::DROLImm)
4879 FinalOpcode = Mips::DROTR;
4880 else
4881 FinalOpcode = Mips::DROTR32;
4884 uint64_t ShiftValue = ImmValue % 32;
4885 if (Inst.getOpcode() == Mips::DROLImm)
4886 ShiftValue = (32 - ImmValue % 32) % 32;
4888 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4890 return false;
4893 if (hasMips64()) {
4894 if (ImmValue == 0) {
4895 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4896 return false;
4899 switch (Inst.getOpcode()) {
4900 default:
4901 llvm_unreachable("unexpected instruction opcode");
4902 case Mips::DROLImm:
4903 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4904 FirstShift = Mips::DSLL;
4905 SecondShift = Mips::DSRL32;
4907 if (ImmValue == 32) {
4908 FirstShift = Mips::DSLL32;
4909 SecondShift = Mips::DSRL32;
4911 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4912 FirstShift = Mips::DSLL32;
4913 SecondShift = Mips::DSRL;
4915 break;
4916 case Mips::DRORImm:
4917 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4918 FirstShift = Mips::DSRL;
4919 SecondShift = Mips::DSLL32;
4921 if (ImmValue == 32) {
4922 FirstShift = Mips::DSRL32;
4923 SecondShift = Mips::DSLL32;
4925 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4926 FirstShift = Mips::DSRL32;
4927 SecondShift = Mips::DSLL;
4929 break;
4932 ATReg = getATReg(Inst.getLoc());
4933 if (!ATReg)
4934 return true;
4936 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4937 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4938 Inst.getLoc(), STI);
4939 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4941 return false;
4944 return true;
4947 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4948 const MCSubtargetInfo *STI) {
4949 MipsTargetStreamer &TOut = getTargetStreamer();
4950 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4951 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4953 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4954 if (FirstRegOp != SecondRegOp)
4955 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4956 else
4957 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4958 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4960 return false;
4963 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4964 const MCSubtargetInfo *STI) {
4965 MipsTargetStreamer &TOut = getTargetStreamer();
4966 unsigned ATReg = Mips::NoRegister;
4967 unsigned DstReg = Inst.getOperand(0).getReg();
4968 unsigned SrcReg = Inst.getOperand(1).getReg();
4969 int32_t ImmValue = Inst.getOperand(2).getImm();
4971 ATReg = getATReg(IDLoc);
4972 if (!ATReg)
4973 return true;
4975 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4976 STI);
4978 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4979 SrcReg, ATReg, IDLoc, STI);
4981 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4983 return false;
4986 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4987 const MCSubtargetInfo *STI) {
4988 MipsTargetStreamer &TOut = getTargetStreamer();
4989 unsigned ATReg = Mips::NoRegister;
4990 unsigned DstReg = Inst.getOperand(0).getReg();
4991 unsigned SrcReg = Inst.getOperand(1).getReg();
4992 unsigned TmpReg = Inst.getOperand(2).getReg();
4994 ATReg = getATReg(Inst.getLoc());
4995 if (!ATReg)
4996 return true;
4998 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4999 SrcReg, TmpReg, IDLoc, STI);
5001 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5003 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5004 DstReg, DstReg, 0x1F, IDLoc, STI);
5006 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5008 if (useTraps()) {
5009 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5010 } else {
5011 MCContext & Context = TOut.getStreamer().getContext();
5012 MCSymbol * BrTarget = Context.createTempSymbol();
5013 MCOperand LabelOp =
5014 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5016 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5017 if (AssemblerOptions.back()->isReorder())
5018 TOut.emitNop(IDLoc, STI);
5019 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5021 TOut.getStreamer().EmitLabel(BrTarget);
5023 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5025 return false;
5028 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5029 const MCSubtargetInfo *STI) {
5030 MipsTargetStreamer &TOut = getTargetStreamer();
5031 unsigned ATReg = Mips::NoRegister;
5032 unsigned DstReg = Inst.getOperand(0).getReg();
5033 unsigned SrcReg = Inst.getOperand(1).getReg();
5034 unsigned TmpReg = Inst.getOperand(2).getReg();
5036 ATReg = getATReg(IDLoc);
5037 if (!ATReg)
5038 return true;
5040 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5041 SrcReg, TmpReg, IDLoc, STI);
5043 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5044 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5045 if (useTraps()) {
5046 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5047 } else {
5048 MCContext & Context = TOut.getStreamer().getContext();
5049 MCSymbol * BrTarget = Context.createTempSymbol();
5050 MCOperand LabelOp =
5051 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5053 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5054 if (AssemblerOptions.back()->isReorder())
5055 TOut.emitNop(IDLoc, STI);
5056 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5058 TOut.getStreamer().EmitLabel(BrTarget);
5061 return false;
5064 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5065 const MCSubtargetInfo *STI) {
5066 MipsTargetStreamer &TOut = getTargetStreamer();
5067 unsigned DstReg = Inst.getOperand(0).getReg();
5068 unsigned SrcReg = Inst.getOperand(1).getReg();
5069 unsigned TmpReg = Inst.getOperand(2).getReg();
5071 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5072 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5074 return false;
5077 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5078 // lw $<reg+1>>, offset+4($reg2)'
5079 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5080 // sw $<reg+1>>, offset+4($reg2)'
5081 // for O32.
5082 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5083 MCStreamer &Out,
5084 const MCSubtargetInfo *STI,
5085 bool IsLoad) {
5086 if (!isABI_O32())
5087 return true;
5089 warnIfNoMacro(IDLoc);
5091 MipsTargetStreamer &TOut = getTargetStreamer();
5092 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5093 unsigned FirstReg = Inst.getOperand(0).getReg();
5094 unsigned SecondReg = nextReg(FirstReg);
5095 unsigned BaseReg = Inst.getOperand(1).getReg();
5096 if (!SecondReg)
5097 return true;
5099 warnIfRegIndexIsAT(FirstReg, IDLoc);
5101 assert(Inst.getOperand(2).isImm() &&
5102 "Offset for load macro is not immediate!");
5104 MCOperand &FirstOffset = Inst.getOperand(2);
5105 signed NextOffset = FirstOffset.getImm() + 4;
5106 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5108 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5109 return true;
5111 // For loads, clobber the base register with the second load instead of the
5112 // first if the BaseReg == FirstReg.
5113 if (FirstReg != BaseReg || !IsLoad) {
5114 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5115 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5116 } else {
5117 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5118 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5121 return false;
5125 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5126 // swc1 $<reg>, offset+4($reg2)'
5127 // or if little endian to 'swc1 $<reg>, offset($reg2);
5128 // swc1 $<reg+1>, offset+4($reg2)'
5129 // for Mips1.
5130 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5131 MCStreamer &Out,
5132 const MCSubtargetInfo *STI) {
5133 if (!isABI_O32())
5134 return true;
5136 warnIfNoMacro(IDLoc);
5138 MipsTargetStreamer &TOut = getTargetStreamer();
5139 unsigned Opcode = Mips::SWC1;
5140 unsigned FirstReg = Inst.getOperand(0).getReg();
5141 unsigned SecondReg = nextReg(FirstReg);
5142 unsigned BaseReg = Inst.getOperand(1).getReg();
5143 if (!SecondReg)
5144 return true;
5146 warnIfRegIndexIsAT(FirstReg, IDLoc);
5148 assert(Inst.getOperand(2).isImm() &&
5149 "Offset for macro is not immediate!");
5151 MCOperand &FirstOffset = Inst.getOperand(2);
5152 signed NextOffset = FirstOffset.getImm() + 4;
5153 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5155 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5156 return true;
5158 if (!IsLittleEndian)
5159 std::swap(FirstReg, SecondReg);
5161 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5162 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5164 return false;
5167 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5168 const MCSubtargetInfo *STI) {
5169 MipsTargetStreamer &TOut = getTargetStreamer();
5171 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5172 assert(Inst.getOperand(0).isReg() &&
5173 Inst.getOperand(1).isReg() &&
5174 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5176 unsigned DstReg = Inst.getOperand(0).getReg();
5177 unsigned SrcReg = Inst.getOperand(1).getReg();
5178 unsigned OpReg = Inst.getOperand(2).getReg();
5180 warnIfNoMacro(IDLoc);
5182 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5183 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5184 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5185 return false;
5188 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5189 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5190 return false;
5193 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5194 const MCSubtargetInfo *STI) {
5195 MipsTargetStreamer &TOut = getTargetStreamer();
5197 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5198 assert(Inst.getOperand(0).isReg() &&
5199 Inst.getOperand(1).isReg() &&
5200 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5202 unsigned DstReg = Inst.getOperand(0).getReg();
5203 unsigned SrcReg = Inst.getOperand(1).getReg();
5204 int64_t Imm = Inst.getOperand(2).getImm();
5206 warnIfNoMacro(IDLoc);
5208 if (Imm == 0) {
5209 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5210 return false;
5213 if (SrcReg == Mips::ZERO) {
5214 Warning(IDLoc, "comparison is always false");
5215 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5216 DstReg, SrcReg, SrcReg, IDLoc, STI);
5217 return false;
5220 unsigned Opc;
5221 if (Imm > -0x8000 && Imm < 0) {
5222 Imm = -Imm;
5223 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5224 } else {
5225 Opc = Mips::XORi;
5228 if (!isUInt<16>(Imm)) {
5229 unsigned ATReg = getATReg(IDLoc);
5230 if (!ATReg)
5231 return true;
5233 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5234 Out, STI))
5235 return true;
5237 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5238 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5239 return false;
5242 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5243 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5244 return false;
5247 // Map the DSP accumulator and control register to the corresponding gpr
5248 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5249 // do not map the DSP registers contigously to gpr registers.
5250 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5251 switch (Inst.getOpcode()) {
5252 case Mips::MFTLO:
5253 case Mips::MTTLO:
5254 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5255 case Mips::AC0:
5256 return Mips::ZERO;
5257 case Mips::AC1:
5258 return Mips::A0;
5259 case Mips::AC2:
5260 return Mips::T0;
5261 case Mips::AC3:
5262 return Mips::T4;
5263 default:
5264 llvm_unreachable("Unknown register for 'mttr' alias!");
5266 case Mips::MFTHI:
5267 case Mips::MTTHI:
5268 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5269 case Mips::AC0:
5270 return Mips::AT;
5271 case Mips::AC1:
5272 return Mips::A1;
5273 case Mips::AC2:
5274 return Mips::T1;
5275 case Mips::AC3:
5276 return Mips::T5;
5277 default:
5278 llvm_unreachable("Unknown register for 'mttr' alias!");
5280 case Mips::MFTACX:
5281 case Mips::MTTACX:
5282 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5283 case Mips::AC0:
5284 return Mips::V0;
5285 case Mips::AC1:
5286 return Mips::A2;
5287 case Mips::AC2:
5288 return Mips::T2;
5289 case Mips::AC3:
5290 return Mips::T6;
5291 default:
5292 llvm_unreachable("Unknown register for 'mttr' alias!");
5294 case Mips::MFTDSP:
5295 case Mips::MTTDSP:
5296 return Mips::S0;
5297 default:
5298 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5302 // Map the floating point register operand to the corresponding register
5303 // operand.
5304 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5305 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5306 case Mips::F0: return Mips::ZERO;
5307 case Mips::F1: return Mips::AT;
5308 case Mips::F2: return Mips::V0;
5309 case Mips::F3: return Mips::V1;
5310 case Mips::F4: return Mips::A0;
5311 case Mips::F5: return Mips::A1;
5312 case Mips::F6: return Mips::A2;
5313 case Mips::F7: return Mips::A3;
5314 case Mips::F8: return Mips::T0;
5315 case Mips::F9: return Mips::T1;
5316 case Mips::F10: return Mips::T2;
5317 case Mips::F11: return Mips::T3;
5318 case Mips::F12: return Mips::T4;
5319 case Mips::F13: return Mips::T5;
5320 case Mips::F14: return Mips::T6;
5321 case Mips::F15: return Mips::T7;
5322 case Mips::F16: return Mips::S0;
5323 case Mips::F17: return Mips::S1;
5324 case Mips::F18: return Mips::S2;
5325 case Mips::F19: return Mips::S3;
5326 case Mips::F20: return Mips::S4;
5327 case Mips::F21: return Mips::S5;
5328 case Mips::F22: return Mips::S6;
5329 case Mips::F23: return Mips::S7;
5330 case Mips::F24: return Mips::T8;
5331 case Mips::F25: return Mips::T9;
5332 case Mips::F26: return Mips::K0;
5333 case Mips::F27: return Mips::K1;
5334 case Mips::F28: return Mips::GP;
5335 case Mips::F29: return Mips::SP;
5336 case Mips::F30: return Mips::FP;
5337 case Mips::F31: return Mips::RA;
5338 default: llvm_unreachable("Unknown register for mttc1 alias!");
5342 // Map the coprocessor operand the corresponding gpr register operand.
5343 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5344 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5345 case Mips::COP00: return Mips::ZERO;
5346 case Mips::COP01: return Mips::AT;
5347 case Mips::COP02: return Mips::V0;
5348 case Mips::COP03: return Mips::V1;
5349 case Mips::COP04: return Mips::A0;
5350 case Mips::COP05: return Mips::A1;
5351 case Mips::COP06: return Mips::A2;
5352 case Mips::COP07: return Mips::A3;
5353 case Mips::COP08: return Mips::T0;
5354 case Mips::COP09: return Mips::T1;
5355 case Mips::COP010: return Mips::T2;
5356 case Mips::COP011: return Mips::T3;
5357 case Mips::COP012: return Mips::T4;
5358 case Mips::COP013: return Mips::T5;
5359 case Mips::COP014: return Mips::T6;
5360 case Mips::COP015: return Mips::T7;
5361 case Mips::COP016: return Mips::S0;
5362 case Mips::COP017: return Mips::S1;
5363 case Mips::COP018: return Mips::S2;
5364 case Mips::COP019: return Mips::S3;
5365 case Mips::COP020: return Mips::S4;
5366 case Mips::COP021: return Mips::S5;
5367 case Mips::COP022: return Mips::S6;
5368 case Mips::COP023: return Mips::S7;
5369 case Mips::COP024: return Mips::T8;
5370 case Mips::COP025: return Mips::T9;
5371 case Mips::COP026: return Mips::K0;
5372 case Mips::COP027: return Mips::K1;
5373 case Mips::COP028: return Mips::GP;
5374 case Mips::COP029: return Mips::SP;
5375 case Mips::COP030: return Mips::FP;
5376 case Mips::COP031: return Mips::RA;
5377 default: llvm_unreachable("Unknown register for mttc0 alias!");
5381 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5382 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5383 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5384 const MCSubtargetInfo *STI) {
5385 MipsTargetStreamer &TOut = getTargetStreamer();
5386 unsigned rd = 0;
5387 unsigned u = 1;
5388 unsigned sel = 0;
5389 unsigned h = 0;
5390 bool IsMFTR = false;
5391 switch (Inst.getOpcode()) {
5392 case Mips::MFTC0:
5393 IsMFTR = true;
5394 LLVM_FALLTHROUGH;
5395 case Mips::MTTC0:
5396 u = 0;
5397 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5398 sel = Inst.getOperand(2).getImm();
5399 break;
5400 case Mips::MFTGPR:
5401 IsMFTR = true;
5402 LLVM_FALLTHROUGH;
5403 case Mips::MTTGPR:
5404 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5405 break;
5406 case Mips::MFTLO:
5407 case Mips::MFTHI:
5408 case Mips::MFTACX:
5409 case Mips::MFTDSP:
5410 IsMFTR = true;
5411 LLVM_FALLTHROUGH;
5412 case Mips::MTTLO:
5413 case Mips::MTTHI:
5414 case Mips::MTTACX:
5415 case Mips::MTTDSP:
5416 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5417 sel = 1;
5418 break;
5419 case Mips::MFTHC1:
5420 h = 1;
5421 LLVM_FALLTHROUGH;
5422 case Mips::MFTC1:
5423 IsMFTR = true;
5424 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5425 sel = 2;
5426 break;
5427 case Mips::MTTHC1:
5428 h = 1;
5429 LLVM_FALLTHROUGH;
5430 case Mips::MTTC1:
5431 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5432 sel = 2;
5433 break;
5434 case Mips::CFTC1:
5435 IsMFTR = true;
5436 LLVM_FALLTHROUGH;
5437 case Mips::CTTC1:
5438 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5439 sel = 3;
5440 break;
5442 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5443 unsigned Op1 =
5444 IsMFTR ? rd
5445 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5446 : Inst.getOperand(0).getReg());
5448 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5449 STI);
5450 return false;
5453 unsigned
5454 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5455 const OperandVector &Operands) {
5456 switch (Inst.getOpcode()) {
5457 default:
5458 return Match_Success;
5459 case Mips::DATI:
5460 case Mips::DAHI:
5461 if (static_cast<MipsOperand &>(*Operands[1])
5462 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5463 return Match_Success;
5464 return Match_RequiresSameSrcAndDst;
5468 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5469 switch (Inst.getOpcode()) {
5470 // As described by the MIPSR6 spec, daui must not use the zero operand for
5471 // its source operand.
5472 case Mips::DAUI:
5473 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5474 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5475 return Match_RequiresNoZeroRegister;
5476 return Match_Success;
5477 // As described by the Mips32r2 spec, the registers Rd and Rs for
5478 // jalr.hb must be different.
5479 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5480 // and registers Rd and Base for microMIPS lwp instruction
5481 case Mips::JALR_HB:
5482 case Mips::JALR_HB64:
5483 case Mips::JALRC_HB_MMR6:
5484 case Mips::JALRC_MMR6:
5485 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5486 return Match_RequiresDifferentSrcAndDst;
5487 return Match_Success;
5488 case Mips::LWP_MM:
5489 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5490 return Match_RequiresDifferentSrcAndDst;
5491 return Match_Success;
5492 case Mips::SYNC:
5493 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5494 return Match_NonZeroOperandForSync;
5495 return Match_Success;
5496 case Mips::MFC0:
5497 case Mips::MTC0:
5498 case Mips::MTC2:
5499 case Mips::MFC2:
5500 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5501 return Match_NonZeroOperandForMTCX;
5502 return Match_Success;
5503 // As described the MIPSR6 spec, the compact branches that compare registers
5504 // must:
5505 // a) Not use the zero register.
5506 // b) Not use the same register twice.
5507 // c) rs < rt for bnec, beqc.
5508 // NB: For this case, the encoding will swap the operands as their
5509 // ordering doesn't matter. GAS performs this transformation too.
5510 // Hence, that constraint does not have to be enforced.
5512 // The compact branches that branch iff the signed addition of two registers
5513 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5514 // operand swapping. They do not have restriction of using the zero register.
5515 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5516 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5517 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5518 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5519 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5520 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5521 case Mips::BLEZC64:
5522 case Mips::BGEZC64:
5523 case Mips::BGTZC64:
5524 case Mips::BLTZC64:
5525 case Mips::BEQZC64:
5526 case Mips::BNEZC64:
5527 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5528 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5529 return Match_RequiresNoZeroRegister;
5530 return Match_Success;
5531 case Mips::BGEC: case Mips::BGEC_MMR6:
5532 case Mips::BLTC: case Mips::BLTC_MMR6:
5533 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5534 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5535 case Mips::BEQC: case Mips::BEQC_MMR6:
5536 case Mips::BNEC: case Mips::BNEC_MMR6:
5537 case Mips::BGEC64:
5538 case Mips::BLTC64:
5539 case Mips::BGEUC64:
5540 case Mips::BLTUC64:
5541 case Mips::BEQC64:
5542 case Mips::BNEC64:
5543 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5544 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5545 return Match_RequiresNoZeroRegister;
5546 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5547 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5548 return Match_RequiresNoZeroRegister;
5549 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5550 return Match_RequiresDifferentOperands;
5551 return Match_Success;
5552 case Mips::DINS: {
5553 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5554 "Operands must be immediates for dins!");
5555 const signed Pos = Inst.getOperand(2).getImm();
5556 const signed Size = Inst.getOperand(3).getImm();
5557 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5558 return Match_RequiresPosSizeRange0_32;
5559 return Match_Success;
5561 case Mips::DINSM:
5562 case Mips::DINSU: {
5563 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5564 "Operands must be immediates for dinsm/dinsu!");
5565 const signed Pos = Inst.getOperand(2).getImm();
5566 const signed Size = Inst.getOperand(3).getImm();
5567 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5568 return Match_RequiresPosSizeRange33_64;
5569 return Match_Success;
5571 case Mips::DEXT: {
5572 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5573 "Operands must be immediates for DEXTM!");
5574 const signed Pos = Inst.getOperand(2).getImm();
5575 const signed Size = Inst.getOperand(3).getImm();
5576 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5577 return Match_RequiresPosSizeUImm6;
5578 return Match_Success;
5580 case Mips::DEXTM:
5581 case Mips::DEXTU: {
5582 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5583 "Operands must be immediates for dextm/dextu!");
5584 const signed Pos = Inst.getOperand(2).getImm();
5585 const signed Size = Inst.getOperand(3).getImm();
5586 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5587 return Match_RequiresPosSizeRange33_64;
5588 return Match_Success;
5590 case Mips::CRC32B: case Mips::CRC32CB:
5591 case Mips::CRC32H: case Mips::CRC32CH:
5592 case Mips::CRC32W: case Mips::CRC32CW:
5593 case Mips::CRC32D: case Mips::CRC32CD:
5594 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5595 return Match_RequiresSameSrcAndDst;
5596 return Match_Success;
5599 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5600 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5601 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5602 return Match_NoFCCRegisterForCurrentISA;
5604 return Match_Success;
5608 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5609 uint64_t ErrorInfo) {
5610 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5611 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5612 if (ErrorLoc == SMLoc())
5613 return Loc;
5614 return ErrorLoc;
5616 return Loc;
5619 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5620 OperandVector &Operands,
5621 MCStreamer &Out,
5622 uint64_t &ErrorInfo,
5623 bool MatchingInlineAsm) {
5624 MCInst Inst;
5625 unsigned MatchResult =
5626 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5628 switch (MatchResult) {
5629 case Match_Success:
5630 if (processInstruction(Inst, IDLoc, Out, STI))
5631 return true;
5632 return false;
5633 case Match_MissingFeature:
5634 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5635 return true;
5636 case Match_InvalidOperand: {
5637 SMLoc ErrorLoc = IDLoc;
5638 if (ErrorInfo != ~0ULL) {
5639 if (ErrorInfo >= Operands.size())
5640 return Error(IDLoc, "too few operands for instruction");
5642 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5643 if (ErrorLoc == SMLoc())
5644 ErrorLoc = IDLoc;
5647 return Error(ErrorLoc, "invalid operand for instruction");
5649 case Match_NonZeroOperandForSync:
5650 return Error(IDLoc,
5651 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5652 case Match_NonZeroOperandForMTCX:
5653 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5654 case Match_MnemonicFail:
5655 return Error(IDLoc, "invalid instruction");
5656 case Match_RequiresDifferentSrcAndDst:
5657 return Error(IDLoc, "source and destination must be different");
5658 case Match_RequiresDifferentOperands:
5659 return Error(IDLoc, "registers must be different");
5660 case Match_RequiresNoZeroRegister:
5661 return Error(IDLoc, "invalid operand ($zero) for instruction");
5662 case Match_RequiresSameSrcAndDst:
5663 return Error(IDLoc, "source and destination must match");
5664 case Match_NoFCCRegisterForCurrentISA:
5665 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5666 "non-zero fcc register doesn't exist in current ISA level");
5667 case Match_Immz:
5668 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5669 case Match_UImm1_0:
5670 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5671 "expected 1-bit unsigned immediate");
5672 case Match_UImm2_0:
5673 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5674 "expected 2-bit unsigned immediate");
5675 case Match_UImm2_1:
5676 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5677 "expected immediate in range 1 .. 4");
5678 case Match_UImm3_0:
5679 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5680 "expected 3-bit unsigned immediate");
5681 case Match_UImm4_0:
5682 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5683 "expected 4-bit unsigned immediate");
5684 case Match_SImm4_0:
5685 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5686 "expected 4-bit signed immediate");
5687 case Match_UImm5_0:
5688 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5689 "expected 5-bit unsigned immediate");
5690 case Match_SImm5_0:
5691 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5692 "expected 5-bit signed immediate");
5693 case Match_UImm5_1:
5694 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5695 "expected immediate in range 1 .. 32");
5696 case Match_UImm5_32:
5697 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5698 "expected immediate in range 32 .. 63");
5699 case Match_UImm5_33:
5700 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5701 "expected immediate in range 33 .. 64");
5702 case Match_UImm5_0_Report_UImm6:
5703 // This is used on UImm5 operands that have a corresponding UImm5_32
5704 // operand to avoid confusing the user.
5705 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5706 "expected 6-bit unsigned immediate");
5707 case Match_UImm5_Lsl2:
5708 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5709 "expected both 7-bit unsigned immediate and multiple of 4");
5710 case Match_UImmRange2_64:
5711 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5712 "expected immediate in range 2 .. 64");
5713 case Match_UImm6_0:
5714 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5715 "expected 6-bit unsigned immediate");
5716 case Match_UImm6_Lsl2:
5717 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5718 "expected both 8-bit unsigned immediate and multiple of 4");
5719 case Match_SImm6_0:
5720 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5721 "expected 6-bit signed immediate");
5722 case Match_UImm7_0:
5723 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5724 "expected 7-bit unsigned immediate");
5725 case Match_UImm7_N1:
5726 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5727 "expected immediate in range -1 .. 126");
5728 case Match_SImm7_Lsl2:
5729 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5730 "expected both 9-bit signed immediate and multiple of 4");
5731 case Match_UImm8_0:
5732 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5733 "expected 8-bit unsigned immediate");
5734 case Match_UImm10_0:
5735 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5736 "expected 10-bit unsigned immediate");
5737 case Match_SImm10_0:
5738 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5739 "expected 10-bit signed immediate");
5740 case Match_SImm11_0:
5741 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5742 "expected 11-bit signed immediate");
5743 case Match_UImm16:
5744 case Match_UImm16_Relaxed:
5745 case Match_UImm16_AltRelaxed:
5746 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5747 "expected 16-bit unsigned immediate");
5748 case Match_SImm16:
5749 case Match_SImm16_Relaxed:
5750 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5751 "expected 16-bit signed immediate");
5752 case Match_SImm19_Lsl2:
5753 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5754 "expected both 19-bit signed immediate and multiple of 4");
5755 case Match_UImm20_0:
5756 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5757 "expected 20-bit unsigned immediate");
5758 case Match_UImm26_0:
5759 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5760 "expected 26-bit unsigned immediate");
5761 case Match_SImm32:
5762 case Match_SImm32_Relaxed:
5763 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5764 "expected 32-bit signed immediate");
5765 case Match_UImm32_Coerced:
5766 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5767 "expected 32-bit immediate");
5768 case Match_MemSImm9:
5769 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5770 "expected memory with 9-bit signed offset");
5771 case Match_MemSImm10:
5772 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5773 "expected memory with 10-bit signed offset");
5774 case Match_MemSImm10Lsl1:
5775 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5776 "expected memory with 11-bit signed offset and multiple of 2");
5777 case Match_MemSImm10Lsl2:
5778 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5779 "expected memory with 12-bit signed offset and multiple of 4");
5780 case Match_MemSImm10Lsl3:
5781 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5782 "expected memory with 13-bit signed offset and multiple of 8");
5783 case Match_MemSImm11:
5784 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5785 "expected memory with 11-bit signed offset");
5786 case Match_MemSImm12:
5787 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5788 "expected memory with 12-bit signed offset");
5789 case Match_MemSImm16:
5790 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5791 "expected memory with 16-bit signed offset");
5792 case Match_MemSImmPtr:
5793 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5794 "expected memory with 32-bit signed offset");
5795 case Match_RequiresPosSizeRange0_32: {
5796 SMLoc ErrorStart = Operands[3]->getStartLoc();
5797 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5798 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5799 SMRange(ErrorStart, ErrorEnd));
5801 case Match_RequiresPosSizeUImm6: {
5802 SMLoc ErrorStart = Operands[3]->getStartLoc();
5803 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5804 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5805 SMRange(ErrorStart, ErrorEnd));
5807 case Match_RequiresPosSizeRange33_64: {
5808 SMLoc ErrorStart = Operands[3]->getStartLoc();
5809 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5810 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5811 SMRange(ErrorStart, ErrorEnd));
5815 llvm_unreachable("Implement any new match types added!");
5818 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5819 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5820 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5821 ") without \".set noat\"");
5824 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5825 if (!AssemblerOptions.back()->isMacro())
5826 Warning(Loc, "macro instruction expanded into multiple instructions");
5829 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5830 const OperandVector &Operands) {
5831 assert(
5832 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
5833 "Unexpected instruction!");
5834 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5835 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5836 Inst.addOperand(MCOperand::createReg(NextReg));
5837 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5840 void
5841 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5842 SMRange Range, bool ShowColors) {
5843 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5844 Range, SMFixIt(Range, FixMsg),
5845 ShowColors);
5848 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5849 int CC;
5851 CC = StringSwitch<unsigned>(Name)
5852 .Case("zero", 0)
5853 .Cases("at", "AT", 1)
5854 .Case("a0", 4)
5855 .Case("a1", 5)
5856 .Case("a2", 6)
5857 .Case("a3", 7)
5858 .Case("v0", 2)
5859 .Case("v1", 3)
5860 .Case("s0", 16)
5861 .Case("s1", 17)
5862 .Case("s2", 18)
5863 .Case("s3", 19)
5864 .Case("s4", 20)
5865 .Case("s5", 21)
5866 .Case("s6", 22)
5867 .Case("s7", 23)
5868 .Case("k0", 26)
5869 .Case("k1", 27)
5870 .Case("gp", 28)
5871 .Case("sp", 29)
5872 .Case("fp", 30)
5873 .Case("s8", 30)
5874 .Case("ra", 31)
5875 .Case("t0", 8)
5876 .Case("t1", 9)
5877 .Case("t2", 10)
5878 .Case("t3", 11)
5879 .Case("t4", 12)
5880 .Case("t5", 13)
5881 .Case("t6", 14)
5882 .Case("t7", 15)
5883 .Case("t8", 24)
5884 .Case("t9", 25)
5885 .Default(-1);
5887 if (!(isABI_N32() || isABI_N64()))
5888 return CC;
5890 if (12 <= CC && CC <= 15) {
5891 // Name is one of t4-t7
5892 AsmToken RegTok = getLexer().peekTok();
5893 SMRange RegRange = RegTok.getLocRange();
5895 StringRef FixedName = StringSwitch<StringRef>(Name)
5896 .Case("t4", "t0")
5897 .Case("t5", "t1")
5898 .Case("t6", "t2")
5899 .Case("t7", "t3")
5900 .Default("");
5901 assert(FixedName != "" && "Register name is not one of t4-t7.");
5903 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5904 "Did you mean $" + FixedName + "?", RegRange);
5907 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5908 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5909 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5910 if (8 <= CC && CC <= 11)
5911 CC += 4;
5913 if (CC == -1)
5914 CC = StringSwitch<unsigned>(Name)
5915 .Case("a4", 8)
5916 .Case("a5", 9)
5917 .Case("a6", 10)
5918 .Case("a7", 11)
5919 .Case("kt0", 26)
5920 .Case("kt1", 27)
5921 .Default(-1);
5923 return CC;
5926 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5927 int CC;
5929 CC = StringSwitch<unsigned>(Name)
5930 .Case("hwr_cpunum", 0)
5931 .Case("hwr_synci_step", 1)
5932 .Case("hwr_cc", 2)
5933 .Case("hwr_ccres", 3)
5934 .Case("hwr_ulr", 29)
5935 .Default(-1);
5937 return CC;
5940 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5941 if (Name[0] == 'f') {
5942 StringRef NumString = Name.substr(1);
5943 unsigned IntVal;
5944 if (NumString.getAsInteger(10, IntVal))
5945 return -1; // This is not an integer.
5946 if (IntVal > 31) // Maximum index for fpu register.
5947 return -1;
5948 return IntVal;
5950 return -1;
5953 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5954 if (Name.startswith("fcc")) {
5955 StringRef NumString = Name.substr(3);
5956 unsigned IntVal;
5957 if (NumString.getAsInteger(10, IntVal))
5958 return -1; // This is not an integer.
5959 if (IntVal > 7) // There are only 8 fcc registers.
5960 return -1;
5961 return IntVal;
5963 return -1;
5966 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5967 if (Name.startswith("ac")) {
5968 StringRef NumString = Name.substr(2);
5969 unsigned IntVal;
5970 if (NumString.getAsInteger(10, IntVal))
5971 return -1; // This is not an integer.
5972 if (IntVal > 3) // There are only 3 acc registers.
5973 return -1;
5974 return IntVal;
5976 return -1;
5979 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5980 unsigned IntVal;
5982 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5983 return -1;
5985 if (IntVal > 31)
5986 return -1;
5988 return IntVal;
5991 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5992 int CC;
5994 CC = StringSwitch<unsigned>(Name)
5995 .Case("msair", 0)
5996 .Case("msacsr", 1)
5997 .Case("msaaccess", 2)
5998 .Case("msasave", 3)
5999 .Case("msamodify", 4)
6000 .Case("msarequest", 5)
6001 .Case("msamap", 6)
6002 .Case("msaunmap", 7)
6003 .Default(-1);
6005 return CC;
6008 bool MipsAsmParser::canUseATReg() {
6009 return AssemblerOptions.back()->getATRegIndex() != 0;
6012 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
6013 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6014 if (ATIndex == 0) {
6015 reportParseError(Loc,
6016 "pseudo-instruction requires $at, which is not available");
6017 return 0;
6019 unsigned AT = getReg(
6020 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6021 return AT;
6024 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
6025 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6028 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6029 MCAsmParser &Parser = getParser();
6030 LLVM_DEBUG(dbgs() << "parseOperand\n");
6032 // Check if the current operand has a custom associated parser, if so, try to
6033 // custom parse the operand, or fallback to the general approach.
6034 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6035 if (ResTy == MatchOperand_Success)
6036 return false;
6037 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6038 // there was a match, but an error occurred, in which case, just return that
6039 // the operand parsing failed.
6040 if (ResTy == MatchOperand_ParseFail)
6041 return true;
6043 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6045 switch (getLexer().getKind()) {
6046 case AsmToken::Dollar: {
6047 // Parse the register.
6048 SMLoc S = Parser.getTok().getLoc();
6050 // Almost all registers have been parsed by custom parsers. There is only
6051 // one exception to this. $zero (and it's alias $0) will reach this point
6052 // for div, divu, and similar instructions because it is not an operand
6053 // to the instruction definition but an explicit register. Special case
6054 // this situation for now.
6055 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
6056 return false;
6058 // Maybe it is a symbol reference.
6059 StringRef Identifier;
6060 if (Parser.parseIdentifier(Identifier))
6061 return true;
6063 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6064 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
6065 // Otherwise create a symbol reference.
6066 const MCExpr *Res =
6067 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
6069 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
6070 return false;
6072 default: {
6073 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6075 const MCExpr *Expr;
6076 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6077 if (getParser().parseExpression(Expr))
6078 return true;
6080 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6082 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6083 return false;
6085 } // switch(getLexer().getKind())
6086 return true;
6089 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
6090 switch (Expr->getKind()) {
6091 case MCExpr::Constant:
6092 return true;
6093 case MCExpr::SymbolRef:
6094 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
6095 case MCExpr::Binary: {
6096 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
6097 if (!isEvaluated(BE->getLHS()))
6098 return false;
6099 return isEvaluated(BE->getRHS());
6101 case MCExpr::Unary:
6102 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
6103 case MCExpr::Target:
6104 return true;
6106 return false;
6109 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
6110 SMLoc &EndLoc) {
6111 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6112 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6113 if (ResTy == MatchOperand_Success) {
6114 assert(Operands.size() == 1);
6115 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6116 StartLoc = Operand.getStartLoc();
6117 EndLoc = Operand.getEndLoc();
6119 // AFAIK, we only support numeric registers and named GPR's in CFI
6120 // directives.
6121 // Don't worry about eating tokens before failing. Using an unrecognised
6122 // register is a parse error.
6123 if (Operand.isGPRAsmReg()) {
6124 // Resolve to GPR32 or GPR64 appropriately.
6125 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6128 return (RegNo == (unsigned)-1);
6131 assert(Operands.size() == 0);
6132 return (RegNo == (unsigned)-1);
6135 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
6136 SMLoc S;
6138 if (isParenExpr)
6139 return getParser().parseParenExprOfDepth(0, Res, S);
6140 return getParser().parseExpression(Res);
6143 OperandMatchResultTy
6144 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6145 MCAsmParser &Parser = getParser();
6146 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6147 const MCExpr *IdVal = nullptr;
6148 SMLoc S;
6149 bool isParenExpr = false;
6150 OperandMatchResultTy Res = MatchOperand_NoMatch;
6151 // First operand is the offset.
6152 S = Parser.getTok().getLoc();
6154 if (getLexer().getKind() == AsmToken::LParen) {
6155 Parser.Lex();
6156 isParenExpr = true;
6159 if (getLexer().getKind() != AsmToken::Dollar) {
6160 if (parseMemOffset(IdVal, isParenExpr))
6161 return MatchOperand_ParseFail;
6163 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6164 if (Tok.isNot(AsmToken::LParen)) {
6165 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6166 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6167 SMLoc E =
6168 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6169 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6170 return MatchOperand_Success;
6172 if (Tok.is(AsmToken::EndOfStatement)) {
6173 SMLoc E =
6174 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6176 // Zero register assumed, add a memory operand with ZERO as its base.
6177 // "Base" will be managed by k_Memory.
6178 auto Base = MipsOperand::createGPRReg(
6179 0, "0", getContext().getRegisterInfo(), S, E, *this);
6180 Operands.push_back(
6181 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6182 return MatchOperand_Success;
6184 MCBinaryExpr::Opcode Opcode;
6185 // GAS and LLVM treat comparison operators different. GAS will generate -1
6186 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6187 // highly unlikely to be found in a memory offset expression, we don't
6188 // handle them.
6189 switch (Tok.getKind()) {
6190 case AsmToken::Plus:
6191 Opcode = MCBinaryExpr::Add;
6192 Parser.Lex();
6193 break;
6194 case AsmToken::Minus:
6195 Opcode = MCBinaryExpr::Sub;
6196 Parser.Lex();
6197 break;
6198 case AsmToken::Star:
6199 Opcode = MCBinaryExpr::Mul;
6200 Parser.Lex();
6201 break;
6202 case AsmToken::Pipe:
6203 Opcode = MCBinaryExpr::Or;
6204 Parser.Lex();
6205 break;
6206 case AsmToken::Amp:
6207 Opcode = MCBinaryExpr::And;
6208 Parser.Lex();
6209 break;
6210 case AsmToken::LessLess:
6211 Opcode = MCBinaryExpr::Shl;
6212 Parser.Lex();
6213 break;
6214 case AsmToken::GreaterGreater:
6215 Opcode = MCBinaryExpr::LShr;
6216 Parser.Lex();
6217 break;
6218 case AsmToken::Caret:
6219 Opcode = MCBinaryExpr::Xor;
6220 Parser.Lex();
6221 break;
6222 case AsmToken::Slash:
6223 Opcode = MCBinaryExpr::Div;
6224 Parser.Lex();
6225 break;
6226 case AsmToken::Percent:
6227 Opcode = MCBinaryExpr::Mod;
6228 Parser.Lex();
6229 break;
6230 default:
6231 Error(Parser.getTok().getLoc(), "'(' or expression expected");
6232 return MatchOperand_ParseFail;
6234 const MCExpr * NextExpr;
6235 if (getParser().parseExpression(NextExpr))
6236 return MatchOperand_ParseFail;
6237 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6240 Parser.Lex(); // Eat the '(' token.
6243 Res = parseAnyRegister(Operands);
6244 if (Res != MatchOperand_Success)
6245 return Res;
6247 if (Parser.getTok().isNot(AsmToken::RParen)) {
6248 Error(Parser.getTok().getLoc(), "')' expected");
6249 return MatchOperand_ParseFail;
6252 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6254 Parser.Lex(); // Eat the ')' token.
6256 if (!IdVal)
6257 IdVal = MCConstantExpr::create(0, getContext());
6259 // Replace the register operand with the memory operand.
6260 std::unique_ptr<MipsOperand> op(
6261 static_cast<MipsOperand *>(Operands.back().release()));
6262 // Remove the register from the operands.
6263 // "op" will be managed by k_Memory.
6264 Operands.pop_back();
6265 // Add the memory operand.
6266 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6267 int64_t Imm;
6268 if (IdVal->evaluateAsAbsolute(Imm))
6269 IdVal = MCConstantExpr::create(Imm, getContext());
6270 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6271 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6272 getContext());
6275 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6276 return MatchOperand_Success;
6279 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6280 MCAsmParser &Parser = getParser();
6281 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6282 if (!Sym)
6283 return false;
6285 SMLoc S = Parser.getTok().getLoc();
6286 if (Sym->isVariable()) {
6287 const MCExpr *Expr = Sym->getVariableValue();
6288 if (Expr->getKind() == MCExpr::SymbolRef) {
6289 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6290 StringRef DefSymbol = Ref->getSymbol().getName();
6291 if (DefSymbol.startswith("$")) {
6292 OperandMatchResultTy ResTy =
6293 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6294 if (ResTy == MatchOperand_Success) {
6295 Parser.Lex();
6296 return true;
6298 if (ResTy == MatchOperand_ParseFail)
6299 llvm_unreachable("Should never ParseFail");
6302 } else if (Sym->isUnset()) {
6303 // If symbol is unset, it might be created in the `parseSetAssignment`
6304 // routine as an alias for a numeric register name.
6305 // Lookup in the aliases list.
6306 auto Entry = RegisterSets.find(Sym->getName());
6307 if (Entry != RegisterSets.end()) {
6308 OperandMatchResultTy ResTy =
6309 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6310 if (ResTy == MatchOperand_Success) {
6311 Parser.Lex();
6312 return true;
6317 return false;
6320 OperandMatchResultTy
6321 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6322 StringRef Identifier,
6323 SMLoc S) {
6324 int Index = matchCPURegisterName(Identifier);
6325 if (Index != -1) {
6326 Operands.push_back(MipsOperand::createGPRReg(
6327 Index, Identifier, getContext().getRegisterInfo(), S,
6328 getLexer().getLoc(), *this));
6329 return MatchOperand_Success;
6332 Index = matchHWRegsRegisterName(Identifier);
6333 if (Index != -1) {
6334 Operands.push_back(MipsOperand::createHWRegsReg(
6335 Index, Identifier, getContext().getRegisterInfo(), S,
6336 getLexer().getLoc(), *this));
6337 return MatchOperand_Success;
6340 Index = matchFPURegisterName(Identifier);
6341 if (Index != -1) {
6342 Operands.push_back(MipsOperand::createFGRReg(
6343 Index, Identifier, getContext().getRegisterInfo(), S,
6344 getLexer().getLoc(), *this));
6345 return MatchOperand_Success;
6348 Index = matchFCCRegisterName(Identifier);
6349 if (Index != -1) {
6350 Operands.push_back(MipsOperand::createFCCReg(
6351 Index, Identifier, getContext().getRegisterInfo(), S,
6352 getLexer().getLoc(), *this));
6353 return MatchOperand_Success;
6356 Index = matchACRegisterName(Identifier);
6357 if (Index != -1) {
6358 Operands.push_back(MipsOperand::createACCReg(
6359 Index, Identifier, getContext().getRegisterInfo(), S,
6360 getLexer().getLoc(), *this));
6361 return MatchOperand_Success;
6364 Index = matchMSA128RegisterName(Identifier);
6365 if (Index != -1) {
6366 Operands.push_back(MipsOperand::createMSA128Reg(
6367 Index, Identifier, getContext().getRegisterInfo(), S,
6368 getLexer().getLoc(), *this));
6369 return MatchOperand_Success;
6372 Index = matchMSA128CtrlRegisterName(Identifier);
6373 if (Index != -1) {
6374 Operands.push_back(MipsOperand::createMSACtrlReg(
6375 Index, Identifier, getContext().getRegisterInfo(), S,
6376 getLexer().getLoc(), *this));
6377 return MatchOperand_Success;
6380 return MatchOperand_NoMatch;
6383 OperandMatchResultTy
6384 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6385 const AsmToken &Token, SMLoc S) {
6386 if (Token.is(AsmToken::Identifier)) {
6387 LLVM_DEBUG(dbgs() << ".. identifier\n");
6388 StringRef Identifier = Token.getIdentifier();
6389 OperandMatchResultTy ResTy =
6390 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6391 return ResTy;
6392 } else if (Token.is(AsmToken::Integer)) {
6393 LLVM_DEBUG(dbgs() << ".. integer\n");
6394 int64_t RegNum = Token.getIntVal();
6395 if (RegNum < 0 || RegNum > 31) {
6396 // Show the error, but treat invalid register
6397 // number as a normal one to continue parsing
6398 // and catch other possible errors.
6399 Error(getLexer().getLoc(), "invalid register number");
6401 Operands.push_back(MipsOperand::createNumericReg(
6402 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6403 Token.getLoc(), *this));
6404 return MatchOperand_Success;
6407 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6409 return MatchOperand_NoMatch;
6412 OperandMatchResultTy
6413 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6414 auto Token = getLexer().peekTok(false);
6415 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6418 OperandMatchResultTy
6419 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6420 MCAsmParser &Parser = getParser();
6421 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6423 auto Token = Parser.getTok();
6425 SMLoc S = Token.getLoc();
6427 if (Token.isNot(AsmToken::Dollar)) {
6428 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6429 if (Token.is(AsmToken::Identifier)) {
6430 if (searchSymbolAlias(Operands))
6431 return MatchOperand_Success;
6433 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6434 return MatchOperand_NoMatch;
6436 LLVM_DEBUG(dbgs() << ".. $\n");
6438 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6439 if (ResTy == MatchOperand_Success) {
6440 Parser.Lex(); // $
6441 Parser.Lex(); // identifier
6443 return ResTy;
6446 OperandMatchResultTy
6447 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6448 MCAsmParser &Parser = getParser();
6449 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6451 SMLoc S = getLexer().getLoc();
6453 // Registers are a valid target and have priority over symbols.
6454 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6455 if (ResTy != MatchOperand_NoMatch)
6456 return ResTy;
6458 // Integers and expressions are acceptable
6459 const MCExpr *Expr = nullptr;
6460 if (Parser.parseExpression(Expr)) {
6461 // We have no way of knowing if a symbol was consumed so we must ParseFail
6462 return MatchOperand_ParseFail;
6464 Operands.push_back(
6465 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6466 return MatchOperand_Success;
6469 OperandMatchResultTy
6470 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6471 MCAsmParser &Parser = getParser();
6472 const MCExpr *IdVal;
6473 // If the first token is '$' we may have register operand. We have to reject
6474 // cases where it is not a register. Complicating the matter is that
6475 // register names are not reserved across all ABIs.
6476 // Peek past the dollar to see if it's a register name for this ABI.
6477 SMLoc S = Parser.getTok().getLoc();
6478 if (Parser.getTok().is(AsmToken::Dollar)) {
6479 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6480 ? MatchOperand_ParseFail
6481 : MatchOperand_NoMatch;
6483 if (getParser().parseExpression(IdVal))
6484 return MatchOperand_ParseFail;
6485 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6486 if (!MCE)
6487 return MatchOperand_NoMatch;
6488 int64_t Val = MCE->getValue();
6489 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6490 Operands.push_back(MipsOperand::CreateImm(
6491 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6492 return MatchOperand_Success;
6495 OperandMatchResultTy
6496 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6497 MCAsmParser &Parser = getParser();
6498 SmallVector<unsigned, 10> Regs;
6499 unsigned RegNo;
6500 unsigned PrevReg = Mips::NoRegister;
6501 bool RegRange = false;
6502 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6504 if (Parser.getTok().isNot(AsmToken::Dollar))
6505 return MatchOperand_ParseFail;
6507 SMLoc S = Parser.getTok().getLoc();
6508 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6509 SMLoc E = getLexer().getLoc();
6510 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6511 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6512 if (RegRange) {
6513 // Remove last register operand because registers from register range
6514 // should be inserted first.
6515 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6516 (!isGP64bit() && RegNo == Mips::RA)) {
6517 Regs.push_back(RegNo);
6518 } else {
6519 unsigned TmpReg = PrevReg + 1;
6520 while (TmpReg <= RegNo) {
6521 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6522 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6523 isGP64bit())) {
6524 Error(E, "invalid register operand");
6525 return MatchOperand_ParseFail;
6528 PrevReg = TmpReg;
6529 Regs.push_back(TmpReg++);
6533 RegRange = false;
6534 } else {
6535 if ((PrevReg == Mips::NoRegister) &&
6536 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6537 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6538 Error(E, "$16 or $31 expected");
6539 return MatchOperand_ParseFail;
6540 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6541 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6542 !isGP64bit()) ||
6543 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6544 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6545 isGP64bit()))) {
6546 Error(E, "invalid register operand");
6547 return MatchOperand_ParseFail;
6548 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6549 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6550 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6551 isGP64bit()))) {
6552 Error(E, "consecutive register numbers expected");
6553 return MatchOperand_ParseFail;
6556 Regs.push_back(RegNo);
6559 if (Parser.getTok().is(AsmToken::Minus))
6560 RegRange = true;
6562 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6563 !Parser.getTok().isNot(AsmToken::Comma)) {
6564 Error(E, "',' or '-' expected");
6565 return MatchOperand_ParseFail;
6568 Lex(); // Consume comma or minus
6569 if (Parser.getTok().isNot(AsmToken::Dollar))
6570 break;
6572 PrevReg = RegNo;
6575 SMLoc E = Parser.getTok().getLoc();
6576 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6577 parseMemOperand(Operands);
6578 return MatchOperand_Success;
6581 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6582 /// either this.
6583 /// ::= '(', register, ')'
6584 /// handle it before we iterate so we don't get tripped up by the lack of
6585 /// a comma.
6586 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6587 MCAsmParser &Parser = getParser();
6588 if (getLexer().is(AsmToken::LParen)) {
6589 Operands.push_back(
6590 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6591 Parser.Lex();
6592 if (parseOperand(Operands, Name)) {
6593 SMLoc Loc = getLexer().getLoc();
6594 return Error(Loc, "unexpected token in argument list");
6596 if (Parser.getTok().isNot(AsmToken::RParen)) {
6597 SMLoc Loc = getLexer().getLoc();
6598 return Error(Loc, "unexpected token, expected ')'");
6600 Operands.push_back(
6601 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6602 Parser.Lex();
6604 return false;
6607 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6608 /// either one of these.
6609 /// ::= '[', register, ']'
6610 /// ::= '[', integer, ']'
6611 /// handle it before we iterate so we don't get tripped up by the lack of
6612 /// a comma.
6613 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6614 OperandVector &Operands) {
6615 MCAsmParser &Parser = getParser();
6616 if (getLexer().is(AsmToken::LBrac)) {
6617 Operands.push_back(
6618 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6619 Parser.Lex();
6620 if (parseOperand(Operands, Name)) {
6621 SMLoc Loc = getLexer().getLoc();
6622 return Error(Loc, "unexpected token in argument list");
6624 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6625 SMLoc Loc = getLexer().getLoc();
6626 return Error(Loc, "unexpected token, expected ']'");
6628 Operands.push_back(
6629 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6630 Parser.Lex();
6632 return false;
6635 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6636 unsigned VariantID = 0);
6638 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6639 SMLoc NameLoc, OperandVector &Operands) {
6640 MCAsmParser &Parser = getParser();
6641 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6643 // We have reached first instruction, module directive are now forbidden.
6644 getTargetStreamer().forbidModuleDirective();
6646 // Check if we have valid mnemonic
6647 if (!mnemonicIsValid(Name, 0)) {
6648 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6649 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6650 return Error(NameLoc, "unknown instruction" + Suggestion);
6652 // First operand in MCInst is instruction mnemonic.
6653 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6655 // Read the remaining operands.
6656 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6657 // Read the first operand.
6658 if (parseOperand(Operands, Name)) {
6659 SMLoc Loc = getLexer().getLoc();
6660 return Error(Loc, "unexpected token in argument list");
6662 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6663 return true;
6664 // AFAIK, parenthesis suffixes are never on the first operand
6666 while (getLexer().is(AsmToken::Comma)) {
6667 Parser.Lex(); // Eat the comma.
6668 // Parse and remember the operand.
6669 if (parseOperand(Operands, Name)) {
6670 SMLoc Loc = getLexer().getLoc();
6671 return Error(Loc, "unexpected token in argument list");
6673 // Parse bracket and parenthesis suffixes before we iterate
6674 if (getLexer().is(AsmToken::LBrac)) {
6675 if (parseBracketSuffix(Name, Operands))
6676 return true;
6677 } else if (getLexer().is(AsmToken::LParen) &&
6678 parseParenSuffix(Name, Operands))
6679 return true;
6682 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6683 SMLoc Loc = getLexer().getLoc();
6684 return Error(Loc, "unexpected token in argument list");
6686 Parser.Lex(); // Consume the EndOfStatement.
6687 return false;
6690 // FIXME: Given that these have the same name, these should both be
6691 // consistent on affecting the Parser.
6692 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6693 SMLoc Loc = getLexer().getLoc();
6694 return Error(Loc, ErrorMsg);
6697 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6698 return Error(Loc, ErrorMsg);
6701 bool MipsAsmParser::parseSetNoAtDirective() {
6702 MCAsmParser &Parser = getParser();
6703 // Line should look like: ".set noat".
6705 // Set the $at register to $0.
6706 AssemblerOptions.back()->setATRegIndex(0);
6708 Parser.Lex(); // Eat "noat".
6710 // If this is not the end of the statement, report an error.
6711 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6712 reportParseError("unexpected token, expected end of statement");
6713 return false;
6716 getTargetStreamer().emitDirectiveSetNoAt();
6717 Parser.Lex(); // Consume the EndOfStatement.
6718 return false;
6721 bool MipsAsmParser::parseSetAtDirective() {
6722 // Line can be: ".set at", which sets $at to $1
6723 // or ".set at=$reg", which sets $at to $reg.
6724 MCAsmParser &Parser = getParser();
6725 Parser.Lex(); // Eat "at".
6727 if (getLexer().is(AsmToken::EndOfStatement)) {
6728 // No register was specified, so we set $at to $1.
6729 AssemblerOptions.back()->setATRegIndex(1);
6731 getTargetStreamer().emitDirectiveSetAt();
6732 Parser.Lex(); // Consume the EndOfStatement.
6733 return false;
6736 if (getLexer().isNot(AsmToken::Equal)) {
6737 reportParseError("unexpected token, expected equals sign");
6738 return false;
6740 Parser.Lex(); // Eat "=".
6742 if (getLexer().isNot(AsmToken::Dollar)) {
6743 if (getLexer().is(AsmToken::EndOfStatement)) {
6744 reportParseError("no register specified");
6745 return false;
6746 } else {
6747 reportParseError("unexpected token, expected dollar sign '$'");
6748 return false;
6751 Parser.Lex(); // Eat "$".
6753 // Find out what "reg" is.
6754 unsigned AtRegNo;
6755 const AsmToken &Reg = Parser.getTok();
6756 if (Reg.is(AsmToken::Identifier)) {
6757 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6758 } else if (Reg.is(AsmToken::Integer)) {
6759 AtRegNo = Reg.getIntVal();
6760 } else {
6761 reportParseError("unexpected token, expected identifier or integer");
6762 return false;
6765 // Check if $reg is a valid register. If it is, set $at to $reg.
6766 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6767 reportParseError("invalid register");
6768 return false;
6770 Parser.Lex(); // Eat "reg".
6772 // If this is not the end of the statement, report an error.
6773 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6774 reportParseError("unexpected token, expected end of statement");
6775 return false;
6778 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6780 Parser.Lex(); // Consume the EndOfStatement.
6781 return false;
6784 bool MipsAsmParser::parseSetReorderDirective() {
6785 MCAsmParser &Parser = getParser();
6786 Parser.Lex();
6787 // If this is not the end of the statement, report an error.
6788 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6789 reportParseError("unexpected token, expected end of statement");
6790 return false;
6792 AssemblerOptions.back()->setReorder();
6793 getTargetStreamer().emitDirectiveSetReorder();
6794 Parser.Lex(); // Consume the EndOfStatement.
6795 return false;
6798 bool MipsAsmParser::parseSetNoReorderDirective() {
6799 MCAsmParser &Parser = getParser();
6800 Parser.Lex();
6801 // If this is not the end of the statement, report an error.
6802 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6803 reportParseError("unexpected token, expected end of statement");
6804 return false;
6806 AssemblerOptions.back()->setNoReorder();
6807 getTargetStreamer().emitDirectiveSetNoReorder();
6808 Parser.Lex(); // Consume the EndOfStatement.
6809 return false;
6812 bool MipsAsmParser::parseSetMacroDirective() {
6813 MCAsmParser &Parser = getParser();
6814 Parser.Lex();
6815 // If this is not the end of the statement, report an error.
6816 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6817 reportParseError("unexpected token, expected end of statement");
6818 return false;
6820 AssemblerOptions.back()->setMacro();
6821 getTargetStreamer().emitDirectiveSetMacro();
6822 Parser.Lex(); // Consume the EndOfStatement.
6823 return false;
6826 bool MipsAsmParser::parseSetNoMacroDirective() {
6827 MCAsmParser &Parser = getParser();
6828 Parser.Lex();
6829 // If this is not the end of the statement, report an error.
6830 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6831 reportParseError("unexpected token, expected end of statement");
6832 return false;
6834 if (AssemblerOptions.back()->isReorder()) {
6835 reportParseError("`noreorder' must be set before `nomacro'");
6836 return false;
6838 AssemblerOptions.back()->setNoMacro();
6839 getTargetStreamer().emitDirectiveSetNoMacro();
6840 Parser.Lex(); // Consume the EndOfStatement.
6841 return false;
6844 bool MipsAsmParser::parseSetMsaDirective() {
6845 MCAsmParser &Parser = getParser();
6846 Parser.Lex();
6848 // If this is not the end of the statement, report an error.
6849 if (getLexer().isNot(AsmToken::EndOfStatement))
6850 return reportParseError("unexpected token, expected end of statement");
6852 setFeatureBits(Mips::FeatureMSA, "msa");
6853 getTargetStreamer().emitDirectiveSetMsa();
6854 return false;
6857 bool MipsAsmParser::parseSetNoMsaDirective() {
6858 MCAsmParser &Parser = getParser();
6859 Parser.Lex();
6861 // If this is not the end of the statement, report an error.
6862 if (getLexer().isNot(AsmToken::EndOfStatement))
6863 return reportParseError("unexpected token, expected end of statement");
6865 clearFeatureBits(Mips::FeatureMSA, "msa");
6866 getTargetStreamer().emitDirectiveSetNoMsa();
6867 return false;
6870 bool MipsAsmParser::parseSetNoDspDirective() {
6871 MCAsmParser &Parser = getParser();
6872 Parser.Lex(); // Eat "nodsp".
6874 // If this is not the end of the statement, report an error.
6875 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6876 reportParseError("unexpected token, expected end of statement");
6877 return false;
6880 clearFeatureBits(Mips::FeatureDSP, "dsp");
6881 getTargetStreamer().emitDirectiveSetNoDsp();
6882 return false;
6885 bool MipsAsmParser::parseSetMips16Directive() {
6886 MCAsmParser &Parser = getParser();
6887 Parser.Lex(); // Eat "mips16".
6889 // If this is not the end of the statement, report an error.
6890 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6891 reportParseError("unexpected token, expected end of statement");
6892 return false;
6895 setFeatureBits(Mips::FeatureMips16, "mips16");
6896 getTargetStreamer().emitDirectiveSetMips16();
6897 Parser.Lex(); // Consume the EndOfStatement.
6898 return false;
6901 bool MipsAsmParser::parseSetNoMips16Directive() {
6902 MCAsmParser &Parser = getParser();
6903 Parser.Lex(); // Eat "nomips16".
6905 // If this is not the end of the statement, report an error.
6906 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6907 reportParseError("unexpected token, expected end of statement");
6908 return false;
6911 clearFeatureBits(Mips::FeatureMips16, "mips16");
6912 getTargetStreamer().emitDirectiveSetNoMips16();
6913 Parser.Lex(); // Consume the EndOfStatement.
6914 return false;
6917 bool MipsAsmParser::parseSetFpDirective() {
6918 MCAsmParser &Parser = getParser();
6919 MipsABIFlagsSection::FpABIKind FpAbiVal;
6920 // Line can be: .set fp=32
6921 // .set fp=xx
6922 // .set fp=64
6923 Parser.Lex(); // Eat fp token
6924 AsmToken Tok = Parser.getTok();
6925 if (Tok.isNot(AsmToken::Equal)) {
6926 reportParseError("unexpected token, expected equals sign '='");
6927 return false;
6929 Parser.Lex(); // Eat '=' token.
6930 Tok = Parser.getTok();
6932 if (!parseFpABIValue(FpAbiVal, ".set"))
6933 return false;
6935 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6936 reportParseError("unexpected token, expected end of statement");
6937 return false;
6939 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6940 Parser.Lex(); // Consume the EndOfStatement.
6941 return false;
6944 bool MipsAsmParser::parseSetOddSPRegDirective() {
6945 MCAsmParser &Parser = getParser();
6947 Parser.Lex(); // Eat "oddspreg".
6948 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6949 reportParseError("unexpected token, expected end of statement");
6950 return false;
6953 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6954 getTargetStreamer().emitDirectiveSetOddSPReg();
6955 return false;
6958 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6959 MCAsmParser &Parser = getParser();
6961 Parser.Lex(); // Eat "nooddspreg".
6962 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6963 reportParseError("unexpected token, expected end of statement");
6964 return false;
6967 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6968 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6969 return false;
6972 bool MipsAsmParser::parseSetMtDirective() {
6973 MCAsmParser &Parser = getParser();
6974 Parser.Lex(); // Eat "mt".
6976 // If this is not the end of the statement, report an error.
6977 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6978 reportParseError("unexpected token, expected end of statement");
6979 return false;
6982 setFeatureBits(Mips::FeatureMT, "mt");
6983 getTargetStreamer().emitDirectiveSetMt();
6984 Parser.Lex(); // Consume the EndOfStatement.
6985 return false;
6988 bool MipsAsmParser::parseSetNoMtDirective() {
6989 MCAsmParser &Parser = getParser();
6990 Parser.Lex(); // Eat "nomt".
6992 // If this is not the end of the statement, report an error.
6993 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6994 reportParseError("unexpected token, expected end of statement");
6995 return false;
6998 clearFeatureBits(Mips::FeatureMT, "mt");
7000 getTargetStreamer().emitDirectiveSetNoMt();
7001 Parser.Lex(); // Consume the EndOfStatement.
7002 return false;
7005 bool MipsAsmParser::parseSetNoCRCDirective() {
7006 MCAsmParser &Parser = getParser();
7007 Parser.Lex(); // Eat "nocrc".
7009 // If this is not the end of the statement, report an error.
7010 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7011 reportParseError("unexpected token, expected end of statement");
7012 return false;
7015 clearFeatureBits(Mips::FeatureCRC, "crc");
7017 getTargetStreamer().emitDirectiveSetNoCRC();
7018 Parser.Lex(); // Consume the EndOfStatement.
7019 return false;
7022 bool MipsAsmParser::parseSetNoVirtDirective() {
7023 MCAsmParser &Parser = getParser();
7024 Parser.Lex(); // Eat "novirt".
7026 // If this is not the end of the statement, report an error.
7027 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7028 reportParseError("unexpected token, expected end of statement");
7029 return false;
7032 clearFeatureBits(Mips::FeatureVirt, "virt");
7034 getTargetStreamer().emitDirectiveSetNoVirt();
7035 Parser.Lex(); // Consume the EndOfStatement.
7036 return false;
7039 bool MipsAsmParser::parseSetNoGINVDirective() {
7040 MCAsmParser &Parser = getParser();
7041 Parser.Lex(); // Eat "noginv".
7043 // If this is not the end of the statement, report an error.
7044 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7045 reportParseError("unexpected token, expected end of statement");
7046 return false;
7049 clearFeatureBits(Mips::FeatureGINV, "ginv");
7051 getTargetStreamer().emitDirectiveSetNoGINV();
7052 Parser.Lex(); // Consume the EndOfStatement.
7053 return false;
7056 bool MipsAsmParser::parseSetPopDirective() {
7057 MCAsmParser &Parser = getParser();
7058 SMLoc Loc = getLexer().getLoc();
7060 Parser.Lex();
7061 if (getLexer().isNot(AsmToken::EndOfStatement))
7062 return reportParseError("unexpected token, expected end of statement");
7064 // Always keep an element on the options "stack" to prevent the user
7065 // from changing the initial options. This is how we remember them.
7066 if (AssemblerOptions.size() == 2)
7067 return reportParseError(Loc, ".set pop with no .set push");
7069 MCSubtargetInfo &STI = copySTI();
7070 AssemblerOptions.pop_back();
7071 setAvailableFeatures(
7072 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7073 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7075 getTargetStreamer().emitDirectiveSetPop();
7076 return false;
7079 bool MipsAsmParser::parseSetPushDirective() {
7080 MCAsmParser &Parser = getParser();
7081 Parser.Lex();
7082 if (getLexer().isNot(AsmToken::EndOfStatement))
7083 return reportParseError("unexpected token, expected end of statement");
7085 // Create a copy of the current assembler options environment and push it.
7086 AssemblerOptions.push_back(
7087 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7089 getTargetStreamer().emitDirectiveSetPush();
7090 return false;
7093 bool MipsAsmParser::parseSetSoftFloatDirective() {
7094 MCAsmParser &Parser = getParser();
7095 Parser.Lex();
7096 if (getLexer().isNot(AsmToken::EndOfStatement))
7097 return reportParseError("unexpected token, expected end of statement");
7099 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7100 getTargetStreamer().emitDirectiveSetSoftFloat();
7101 return false;
7104 bool MipsAsmParser::parseSetHardFloatDirective() {
7105 MCAsmParser &Parser = getParser();
7106 Parser.Lex();
7107 if (getLexer().isNot(AsmToken::EndOfStatement))
7108 return reportParseError("unexpected token, expected end of statement");
7110 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7111 getTargetStreamer().emitDirectiveSetHardFloat();
7112 return false;
7115 bool MipsAsmParser::parseSetAssignment() {
7116 StringRef Name;
7117 MCAsmParser &Parser = getParser();
7119 if (Parser.parseIdentifier(Name))
7120 return reportParseError("expected identifier after .set");
7122 if (getLexer().isNot(AsmToken::Comma))
7123 return reportParseError("unexpected token, expected comma");
7124 Lex(); // Eat comma
7126 if (getLexer().is(AsmToken::Dollar) &&
7127 getLexer().peekTok().is(AsmToken::Integer)) {
7128 // Parse assignment of a numeric register:
7129 // .set r1,$1
7130 Parser.Lex(); // Eat $.
7131 RegisterSets[Name] = Parser.getTok();
7132 Parser.Lex(); // Eat identifier.
7133 getContext().getOrCreateSymbol(Name);
7134 return false;
7137 MCSymbol *Sym;
7138 const MCExpr *Value;
7139 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7140 Parser, Sym, Value))
7141 return true;
7142 Sym->setVariableValue(Value);
7144 return false;
7147 bool MipsAsmParser::parseSetMips0Directive() {
7148 MCAsmParser &Parser = getParser();
7149 Parser.Lex();
7150 if (getLexer().isNot(AsmToken::EndOfStatement))
7151 return reportParseError("unexpected token, expected end of statement");
7153 // Reset assembler options to their initial values.
7154 MCSubtargetInfo &STI = copySTI();
7155 setAvailableFeatures(
7156 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7157 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7158 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7160 getTargetStreamer().emitDirectiveSetMips0();
7161 return false;
7164 bool MipsAsmParser::parseSetArchDirective() {
7165 MCAsmParser &Parser = getParser();
7166 Parser.Lex();
7167 if (getLexer().isNot(AsmToken::Equal))
7168 return reportParseError("unexpected token, expected equals sign");
7170 Parser.Lex();
7171 StringRef Arch;
7172 if (Parser.parseIdentifier(Arch))
7173 return reportParseError("expected arch identifier");
7175 StringRef ArchFeatureName =
7176 StringSwitch<StringRef>(Arch)
7177 .Case("mips1", "mips1")
7178 .Case("mips2", "mips2")
7179 .Case("mips3", "mips3")
7180 .Case("mips4", "mips4")
7181 .Case("mips5", "mips5")
7182 .Case("mips32", "mips32")
7183 .Case("mips32r2", "mips32r2")
7184 .Case("mips32r3", "mips32r3")
7185 .Case("mips32r5", "mips32r5")
7186 .Case("mips32r6", "mips32r6")
7187 .Case("mips64", "mips64")
7188 .Case("mips64r2", "mips64r2")
7189 .Case("mips64r3", "mips64r3")
7190 .Case("mips64r5", "mips64r5")
7191 .Case("mips64r6", "mips64r6")
7192 .Case("octeon", "cnmips")
7193 .Case("r4000", "mips3") // This is an implementation of Mips3.
7194 .Default("");
7196 if (ArchFeatureName.empty())
7197 return reportParseError("unsupported architecture");
7199 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7200 return reportParseError("mips64r6 does not support microMIPS");
7202 selectArch(ArchFeatureName);
7203 getTargetStreamer().emitDirectiveSetArch(Arch);
7204 return false;
7207 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7208 MCAsmParser &Parser = getParser();
7209 Parser.Lex();
7210 if (getLexer().isNot(AsmToken::EndOfStatement))
7211 return reportParseError("unexpected token, expected end of statement");
7213 switch (Feature) {
7214 default:
7215 llvm_unreachable("Unimplemented feature");
7216 case Mips::FeatureDSP:
7217 setFeatureBits(Mips::FeatureDSP, "dsp");
7218 getTargetStreamer().emitDirectiveSetDsp();
7219 break;
7220 case Mips::FeatureDSPR2:
7221 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7222 getTargetStreamer().emitDirectiveSetDspr2();
7223 break;
7224 case Mips::FeatureMicroMips:
7225 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7226 getTargetStreamer().emitDirectiveSetMicroMips();
7227 break;
7228 case Mips::FeatureMips1:
7229 selectArch("mips1");
7230 getTargetStreamer().emitDirectiveSetMips1();
7231 break;
7232 case Mips::FeatureMips2:
7233 selectArch("mips2");
7234 getTargetStreamer().emitDirectiveSetMips2();
7235 break;
7236 case Mips::FeatureMips3:
7237 selectArch("mips3");
7238 getTargetStreamer().emitDirectiveSetMips3();
7239 break;
7240 case Mips::FeatureMips4:
7241 selectArch("mips4");
7242 getTargetStreamer().emitDirectiveSetMips4();
7243 break;
7244 case Mips::FeatureMips5:
7245 selectArch("mips5");
7246 getTargetStreamer().emitDirectiveSetMips5();
7247 break;
7248 case Mips::FeatureMips32:
7249 selectArch("mips32");
7250 getTargetStreamer().emitDirectiveSetMips32();
7251 break;
7252 case Mips::FeatureMips32r2:
7253 selectArch("mips32r2");
7254 getTargetStreamer().emitDirectiveSetMips32R2();
7255 break;
7256 case Mips::FeatureMips32r3:
7257 selectArch("mips32r3");
7258 getTargetStreamer().emitDirectiveSetMips32R3();
7259 break;
7260 case Mips::FeatureMips32r5:
7261 selectArch("mips32r5");
7262 getTargetStreamer().emitDirectiveSetMips32R5();
7263 break;
7264 case Mips::FeatureMips32r6:
7265 selectArch("mips32r6");
7266 getTargetStreamer().emitDirectiveSetMips32R6();
7267 break;
7268 case Mips::FeatureMips64:
7269 selectArch("mips64");
7270 getTargetStreamer().emitDirectiveSetMips64();
7271 break;
7272 case Mips::FeatureMips64r2:
7273 selectArch("mips64r2");
7274 getTargetStreamer().emitDirectiveSetMips64R2();
7275 break;
7276 case Mips::FeatureMips64r3:
7277 selectArch("mips64r3");
7278 getTargetStreamer().emitDirectiveSetMips64R3();
7279 break;
7280 case Mips::FeatureMips64r5:
7281 selectArch("mips64r5");
7282 getTargetStreamer().emitDirectiveSetMips64R5();
7283 break;
7284 case Mips::FeatureMips64r6:
7285 selectArch("mips64r6");
7286 getTargetStreamer().emitDirectiveSetMips64R6();
7287 break;
7288 case Mips::FeatureCRC:
7289 setFeatureBits(Mips::FeatureCRC, "crc");
7290 getTargetStreamer().emitDirectiveSetCRC();
7291 break;
7292 case Mips::FeatureVirt:
7293 setFeatureBits(Mips::FeatureVirt, "virt");
7294 getTargetStreamer().emitDirectiveSetVirt();
7295 break;
7296 case Mips::FeatureGINV:
7297 setFeatureBits(Mips::FeatureGINV, "ginv");
7298 getTargetStreamer().emitDirectiveSetGINV();
7299 break;
7301 return false;
7304 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7305 MCAsmParser &Parser = getParser();
7306 if (getLexer().isNot(AsmToken::Comma)) {
7307 SMLoc Loc = getLexer().getLoc();
7308 return Error(Loc, ErrorStr);
7311 Parser.Lex(); // Eat the comma.
7312 return true;
7315 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7316 // In this class, it is only used for .cprestore.
7317 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7318 // MipsTargetELFStreamer and MipsAsmParser.
7319 bool MipsAsmParser::isPicAndNotNxxAbi() {
7320 return inPicMode() && !(isABI_N32() || isABI_N64());
7323 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7324 if (AssemblerOptions.back()->isReorder())
7325 Warning(Loc, ".cpload should be inside a noreorder section");
7327 if (inMips16Mode()) {
7328 reportParseError(".cpload is not supported in Mips16 mode");
7329 return false;
7332 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7333 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7334 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7335 reportParseError("expected register containing function address");
7336 return false;
7339 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7340 if (!RegOpnd.isGPRAsmReg()) {
7341 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7342 return false;
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;
7351 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7352 return false;
7355 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7356 if (!isABI_N32() && !isABI_N64()) {
7357 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7358 return false;
7361 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7362 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7363 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7364 reportParseError("expected register containing global pointer");
7365 return false;
7368 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7369 if (!RegOpnd.isGPRAsmReg()) {
7370 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7371 return false;
7374 // If this is not the end of the statement, report an error.
7375 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7376 reportParseError("unexpected token, expected end of statement");
7377 return false;
7379 getParser().Lex(); // Consume the EndOfStatement.
7381 unsigned NewReg = RegOpnd.getGPR32Reg();
7382 if (IsPicEnabled)
7383 GPReg = NewReg;
7385 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7386 return false;
7389 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7390 MCAsmParser &Parser = getParser();
7392 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7393 // is used in non-PIC mode.
7395 if (inMips16Mode()) {
7396 reportParseError(".cprestore is not supported in Mips16 mode");
7397 return false;
7400 // Get the stack offset value.
7401 const MCExpr *StackOffset;
7402 int64_t StackOffsetVal;
7403 if (Parser.parseExpression(StackOffset)) {
7404 reportParseError("expected stack offset value");
7405 return false;
7408 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7409 reportParseError("stack offset is not an absolute expression");
7410 return false;
7413 if (StackOffsetVal < 0) {
7414 Warning(Loc, ".cprestore with negative stack offset has no effect");
7415 IsCpRestoreSet = false;
7416 } else {
7417 IsCpRestoreSet = true;
7418 CpRestoreOffset = StackOffsetVal;
7421 // If this is not the end of the statement, report an error.
7422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7423 reportParseError("unexpected token, expected end of statement");
7424 return false;
7427 if (!getTargetStreamer().emitDirectiveCpRestore(
7428 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7429 return true;
7430 Parser.Lex(); // Consume the EndOfStatement.
7431 return false;
7434 bool MipsAsmParser::parseDirectiveCPSetup() {
7435 MCAsmParser &Parser = getParser();
7436 unsigned FuncReg;
7437 unsigned Save;
7438 bool SaveIsReg = true;
7440 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7441 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7442 if (ResTy == MatchOperand_NoMatch) {
7443 reportParseError("expected register containing function address");
7444 return false;
7447 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7448 if (!FuncRegOpnd.isGPRAsmReg()) {
7449 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7450 return false;
7453 FuncReg = FuncRegOpnd.getGPR32Reg();
7454 TmpReg.clear();
7456 if (!eatComma("unexpected token, expected comma"))
7457 return true;
7459 ResTy = parseAnyRegister(TmpReg);
7460 if (ResTy == MatchOperand_NoMatch) {
7461 const MCExpr *OffsetExpr;
7462 int64_t OffsetVal;
7463 SMLoc ExprLoc = getLexer().getLoc();
7465 if (Parser.parseExpression(OffsetExpr) ||
7466 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7467 reportParseError(ExprLoc, "expected save register or stack offset");
7468 return false;
7471 Save = OffsetVal;
7472 SaveIsReg = false;
7473 } else {
7474 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7475 if (!SaveOpnd.isGPRAsmReg()) {
7476 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7477 return false;
7479 Save = SaveOpnd.getGPR32Reg();
7482 if (!eatComma("unexpected token, expected comma"))
7483 return true;
7485 const MCExpr *Expr;
7486 if (Parser.parseExpression(Expr)) {
7487 reportParseError("expected expression");
7488 return false;
7491 if (Expr->getKind() != MCExpr::SymbolRef) {
7492 reportParseError("expected symbol");
7493 return false;
7495 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7497 CpSaveLocation = Save;
7498 CpSaveLocationIsRegister = SaveIsReg;
7500 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7501 SaveIsReg);
7502 return false;
7505 bool MipsAsmParser::parseDirectiveCPReturn() {
7506 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7507 CpSaveLocationIsRegister);
7508 return false;
7511 bool MipsAsmParser::parseDirectiveNaN() {
7512 MCAsmParser &Parser = getParser();
7513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7514 const AsmToken &Tok = Parser.getTok();
7516 if (Tok.getString() == "2008") {
7517 Parser.Lex();
7518 getTargetStreamer().emitDirectiveNaN2008();
7519 return false;
7520 } else if (Tok.getString() == "legacy") {
7521 Parser.Lex();
7522 getTargetStreamer().emitDirectiveNaNLegacy();
7523 return false;
7526 // If we don't recognize the option passed to the .nan
7527 // directive (e.g. no option or unknown option), emit an error.
7528 reportParseError("invalid option in .nan directive");
7529 return false;
7532 bool MipsAsmParser::parseDirectiveSet() {
7533 const AsmToken &Tok = getParser().getTok();
7534 StringRef IdVal = Tok.getString();
7535 SMLoc Loc = Tok.getLoc();
7537 if (IdVal == "noat")
7538 return parseSetNoAtDirective();
7539 if (IdVal == "at")
7540 return parseSetAtDirective();
7541 if (IdVal == "arch")
7542 return parseSetArchDirective();
7543 if (IdVal == "bopt") {
7544 Warning(Loc, "'bopt' feature is unsupported");
7545 getParser().Lex();
7546 return false;
7548 if (IdVal == "nobopt") {
7549 // We're already running in nobopt mode, so nothing to do.
7550 getParser().Lex();
7551 return false;
7553 if (IdVal == "fp")
7554 return parseSetFpDirective();
7555 if (IdVal == "oddspreg")
7556 return parseSetOddSPRegDirective();
7557 if (IdVal == "nooddspreg")
7558 return parseSetNoOddSPRegDirective();
7559 if (IdVal == "pop")
7560 return parseSetPopDirective();
7561 if (IdVal == "push")
7562 return parseSetPushDirective();
7563 if (IdVal == "reorder")
7564 return parseSetReorderDirective();
7565 if (IdVal == "noreorder")
7566 return parseSetNoReorderDirective();
7567 if (IdVal == "macro")
7568 return parseSetMacroDirective();
7569 if (IdVal == "nomacro")
7570 return parseSetNoMacroDirective();
7571 if (IdVal == "mips16")
7572 return parseSetMips16Directive();
7573 if (IdVal == "nomips16")
7574 return parseSetNoMips16Directive();
7575 if (IdVal == "nomicromips") {
7576 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7577 getTargetStreamer().emitDirectiveSetNoMicroMips();
7578 getParser().eatToEndOfStatement();
7579 return false;
7581 if (IdVal == "micromips") {
7582 if (hasMips64r6()) {
7583 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7584 return false;
7586 return parseSetFeature(Mips::FeatureMicroMips);
7588 if (IdVal == "mips0")
7589 return parseSetMips0Directive();
7590 if (IdVal == "mips1")
7591 return parseSetFeature(Mips::FeatureMips1);
7592 if (IdVal == "mips2")
7593 return parseSetFeature(Mips::FeatureMips2);
7594 if (IdVal == "mips3")
7595 return parseSetFeature(Mips::FeatureMips3);
7596 if (IdVal == "mips4")
7597 return parseSetFeature(Mips::FeatureMips4);
7598 if (IdVal == "mips5")
7599 return parseSetFeature(Mips::FeatureMips5);
7600 if (IdVal == "mips32")
7601 return parseSetFeature(Mips::FeatureMips32);
7602 if (IdVal == "mips32r2")
7603 return parseSetFeature(Mips::FeatureMips32r2);
7604 if (IdVal == "mips32r3")
7605 return parseSetFeature(Mips::FeatureMips32r3);
7606 if (IdVal == "mips32r5")
7607 return parseSetFeature(Mips::FeatureMips32r5);
7608 if (IdVal == "mips32r6")
7609 return parseSetFeature(Mips::FeatureMips32r6);
7610 if (IdVal == "mips64")
7611 return parseSetFeature(Mips::FeatureMips64);
7612 if (IdVal == "mips64r2")
7613 return parseSetFeature(Mips::FeatureMips64r2);
7614 if (IdVal == "mips64r3")
7615 return parseSetFeature(Mips::FeatureMips64r3);
7616 if (IdVal == "mips64r5")
7617 return parseSetFeature(Mips::FeatureMips64r5);
7618 if (IdVal == "mips64r6") {
7619 if (inMicroMipsMode()) {
7620 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7621 return false;
7623 return parseSetFeature(Mips::FeatureMips64r6);
7625 if (IdVal == "dsp")
7626 return parseSetFeature(Mips::FeatureDSP);
7627 if (IdVal == "dspr2")
7628 return parseSetFeature(Mips::FeatureDSPR2);
7629 if (IdVal == "nodsp")
7630 return parseSetNoDspDirective();
7631 if (IdVal == "msa")
7632 return parseSetMsaDirective();
7633 if (IdVal == "nomsa")
7634 return parseSetNoMsaDirective();
7635 if (IdVal == "mt")
7636 return parseSetMtDirective();
7637 if (IdVal == "nomt")
7638 return parseSetNoMtDirective();
7639 if (IdVal == "softfloat")
7640 return parseSetSoftFloatDirective();
7641 if (IdVal == "hardfloat")
7642 return parseSetHardFloatDirective();
7643 if (IdVal == "crc")
7644 return parseSetFeature(Mips::FeatureCRC);
7645 if (IdVal == "nocrc")
7646 return parseSetNoCRCDirective();
7647 if (IdVal == "virt")
7648 return parseSetFeature(Mips::FeatureVirt);
7649 if (IdVal == "novirt")
7650 return parseSetNoVirtDirective();
7651 if (IdVal == "ginv")
7652 return parseSetFeature(Mips::FeatureGINV);
7653 if (IdVal == "noginv")
7654 return parseSetNoGINVDirective();
7656 // It is just an identifier, look for an assignment.
7657 return parseSetAssignment();
7660 /// parseDirectiveGpWord
7661 /// ::= .gpword local_sym
7662 bool MipsAsmParser::parseDirectiveGpWord() {
7663 MCAsmParser &Parser = getParser();
7664 const MCExpr *Value;
7665 // EmitGPRel32Value requires an expression, so we are using base class
7666 // method to evaluate the expression.
7667 if (getParser().parseExpression(Value))
7668 return true;
7669 getParser().getStreamer().EmitGPRel32Value(Value);
7671 if (getLexer().isNot(AsmToken::EndOfStatement))
7672 return Error(getLexer().getLoc(),
7673 "unexpected token, expected end of statement");
7674 Parser.Lex(); // Eat EndOfStatement token.
7675 return false;
7678 /// parseDirectiveGpDWord
7679 /// ::= .gpdword local_sym
7680 bool MipsAsmParser::parseDirectiveGpDWord() {
7681 MCAsmParser &Parser = getParser();
7682 const MCExpr *Value;
7683 // EmitGPRel64Value requires an expression, so we are using base class
7684 // method to evaluate the expression.
7685 if (getParser().parseExpression(Value))
7686 return true;
7687 getParser().getStreamer().EmitGPRel64Value(Value);
7689 if (getLexer().isNot(AsmToken::EndOfStatement))
7690 return Error(getLexer().getLoc(),
7691 "unexpected token, expected end of statement");
7692 Parser.Lex(); // Eat EndOfStatement token.
7693 return false;
7696 /// parseDirectiveDtpRelWord
7697 /// ::= .dtprelword tls_sym
7698 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7699 MCAsmParser &Parser = getParser();
7700 const MCExpr *Value;
7701 // EmitDTPRel32Value requires an expression, so we are using base class
7702 // method to evaluate the expression.
7703 if (getParser().parseExpression(Value))
7704 return true;
7705 getParser().getStreamer().EmitDTPRel32Value(Value);
7707 if (getLexer().isNot(AsmToken::EndOfStatement))
7708 return Error(getLexer().getLoc(),
7709 "unexpected token, expected end of statement");
7710 Parser.Lex(); // Eat EndOfStatement token.
7711 return false;
7714 /// parseDirectiveDtpRelDWord
7715 /// ::= .dtpreldword tls_sym
7716 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7717 MCAsmParser &Parser = getParser();
7718 const MCExpr *Value;
7719 // EmitDTPRel64Value requires an expression, so we are using base class
7720 // method to evaluate the expression.
7721 if (getParser().parseExpression(Value))
7722 return true;
7723 getParser().getStreamer().EmitDTPRel64Value(Value);
7725 if (getLexer().isNot(AsmToken::EndOfStatement))
7726 return Error(getLexer().getLoc(),
7727 "unexpected token, expected end of statement");
7728 Parser.Lex(); // Eat EndOfStatement token.
7729 return false;
7732 /// parseDirectiveTpRelWord
7733 /// ::= .tprelword tls_sym
7734 bool MipsAsmParser::parseDirectiveTpRelWord() {
7735 MCAsmParser &Parser = getParser();
7736 const MCExpr *Value;
7737 // EmitTPRel32Value requires an expression, so we are using base class
7738 // method to evaluate the expression.
7739 if (getParser().parseExpression(Value))
7740 return true;
7741 getParser().getStreamer().EmitTPRel32Value(Value);
7743 if (getLexer().isNot(AsmToken::EndOfStatement))
7744 return Error(getLexer().getLoc(),
7745 "unexpected token, expected end of statement");
7746 Parser.Lex(); // Eat EndOfStatement token.
7747 return false;
7750 /// parseDirectiveTpRelDWord
7751 /// ::= .tpreldword tls_sym
7752 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7753 MCAsmParser &Parser = getParser();
7754 const MCExpr *Value;
7755 // EmitTPRel64Value requires an expression, so we are using base class
7756 // method to evaluate the expression.
7757 if (getParser().parseExpression(Value))
7758 return true;
7759 getParser().getStreamer().EmitTPRel64Value(Value);
7761 if (getLexer().isNot(AsmToken::EndOfStatement))
7762 return Error(getLexer().getLoc(),
7763 "unexpected token, expected end of statement");
7764 Parser.Lex(); // Eat EndOfStatement token.
7765 return false;
7768 bool MipsAsmParser::parseDirectiveOption() {
7769 MCAsmParser &Parser = getParser();
7770 // Get the option token.
7771 AsmToken Tok = Parser.getTok();
7772 // At the moment only identifiers are supported.
7773 if (Tok.isNot(AsmToken::Identifier)) {
7774 return Error(Parser.getTok().getLoc(),
7775 "unexpected token, expected identifier");
7778 StringRef Option = Tok.getIdentifier();
7780 if (Option == "pic0") {
7781 // MipsAsmParser needs to know if the current PIC mode changes.
7782 IsPicEnabled = false;
7784 getTargetStreamer().emitDirectiveOptionPic0();
7785 Parser.Lex();
7786 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7787 return Error(Parser.getTok().getLoc(),
7788 "unexpected token, expected end of statement");
7790 return false;
7793 if (Option == "pic2") {
7794 // MipsAsmParser needs to know if the current PIC mode changes.
7795 IsPicEnabled = true;
7797 getTargetStreamer().emitDirectiveOptionPic2();
7798 Parser.Lex();
7799 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7800 return Error(Parser.getTok().getLoc(),
7801 "unexpected token, expected end of statement");
7803 return false;
7806 // Unknown option.
7807 Warning(Parser.getTok().getLoc(),
7808 "unknown option, expected 'pic0' or 'pic2'");
7809 Parser.eatToEndOfStatement();
7810 return false;
7813 /// parseInsnDirective
7814 /// ::= .insn
7815 bool MipsAsmParser::parseInsnDirective() {
7816 // If this is not the end of the statement, report an error.
7817 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7818 reportParseError("unexpected token, expected end of statement");
7819 return false;
7822 // The actual label marking happens in
7823 // MipsELFStreamer::createPendingLabelRelocs().
7824 getTargetStreamer().emitDirectiveInsn();
7826 getParser().Lex(); // Eat EndOfStatement token.
7827 return false;
7830 /// parseRSectionDirective
7831 /// ::= .rdata
7832 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7833 // If this is not the end of the statement, report an error.
7834 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7835 reportParseError("unexpected token, expected end of statement");
7836 return false;
7839 MCSection *ELFSection = getContext().getELFSection(
7840 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7841 getParser().getStreamer().SwitchSection(ELFSection);
7843 getParser().Lex(); // Eat EndOfStatement token.
7844 return false;
7847 /// parseSSectionDirective
7848 /// ::= .sbss
7849 /// ::= .sdata
7850 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7851 // If this is not the end of the statement, report an error.
7852 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7853 reportParseError("unexpected token, expected end of statement");
7854 return false;
7857 MCSection *ELFSection = getContext().getELFSection(
7858 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7859 getParser().getStreamer().SwitchSection(ELFSection);
7861 getParser().Lex(); // Eat EndOfStatement token.
7862 return false;
7865 /// parseDirectiveModule
7866 /// ::= .module oddspreg
7867 /// ::= .module nooddspreg
7868 /// ::= .module fp=value
7869 /// ::= .module softfloat
7870 /// ::= .module hardfloat
7871 /// ::= .module mt
7872 /// ::= .module crc
7873 /// ::= .module nocrc
7874 /// ::= .module virt
7875 /// ::= .module novirt
7876 /// ::= .module ginv
7877 /// ::= .module noginv
7878 bool MipsAsmParser::parseDirectiveModule() {
7879 MCAsmParser &Parser = getParser();
7880 MCAsmLexer &Lexer = getLexer();
7881 SMLoc L = Lexer.getLoc();
7883 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7884 // TODO : get a better message.
7885 reportParseError(".module directive must appear before any code");
7886 return false;
7889 StringRef Option;
7890 if (Parser.parseIdentifier(Option)) {
7891 reportParseError("expected .module option identifier");
7892 return false;
7895 if (Option == "oddspreg") {
7896 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7898 // Synchronize the abiflags information with the FeatureBits information we
7899 // changed above.
7900 getTargetStreamer().updateABIInfo(*this);
7902 // If printing assembly, use the recently updated abiflags information.
7903 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7904 // emitted at the end).
7905 getTargetStreamer().emitDirectiveModuleOddSPReg();
7907 // If this is not the end of the statement, report an error.
7908 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7909 reportParseError("unexpected token, expected end of statement");
7910 return false;
7913 return false; // parseDirectiveModule has finished successfully.
7914 } else if (Option == "nooddspreg") {
7915 if (!isABI_O32()) {
7916 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7919 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7921 // Synchronize the abiflags information with the FeatureBits information we
7922 // changed above.
7923 getTargetStreamer().updateABIInfo(*this);
7925 // If printing assembly, use the recently updated abiflags information.
7926 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7927 // emitted at the end).
7928 getTargetStreamer().emitDirectiveModuleOddSPReg();
7930 // If this is not the end of the statement, report an error.
7931 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7932 reportParseError("unexpected token, expected end of statement");
7933 return false;
7936 return false; // parseDirectiveModule has finished successfully.
7937 } else if (Option == "fp") {
7938 return parseDirectiveModuleFP();
7939 } else if (Option == "softfloat") {
7940 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7942 // Synchronize the ABI Flags information with the FeatureBits information we
7943 // updated above.
7944 getTargetStreamer().updateABIInfo(*this);
7946 // If printing assembly, use the recently updated ABI Flags information.
7947 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7948 // emitted later).
7949 getTargetStreamer().emitDirectiveModuleSoftFloat();
7951 // If this is not the end of the statement, report an error.
7952 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7953 reportParseError("unexpected token, expected end of statement");
7954 return false;
7957 return false; // parseDirectiveModule has finished successfully.
7958 } else if (Option == "hardfloat") {
7959 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7961 // Synchronize the ABI Flags information with the FeatureBits information we
7962 // updated above.
7963 getTargetStreamer().updateABIInfo(*this);
7965 // If printing assembly, use the recently updated ABI Flags information.
7966 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7967 // emitted later).
7968 getTargetStreamer().emitDirectiveModuleHardFloat();
7970 // If this is not the end of the statement, report an error.
7971 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7972 reportParseError("unexpected token, expected end of statement");
7973 return false;
7976 return false; // parseDirectiveModule has finished successfully.
7977 } else if (Option == "mt") {
7978 setModuleFeatureBits(Mips::FeatureMT, "mt");
7980 // Synchronize the ABI Flags information with the FeatureBits information we
7981 // updated above.
7982 getTargetStreamer().updateABIInfo(*this);
7984 // If printing assembly, use the recently updated ABI Flags information.
7985 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7986 // emitted later).
7987 getTargetStreamer().emitDirectiveModuleMT();
7989 // If this is not the end of the statement, report an error.
7990 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7991 reportParseError("unexpected token, expected end of statement");
7992 return false;
7995 return false; // parseDirectiveModule has finished successfully.
7996 } else if (Option == "crc") {
7997 setModuleFeatureBits(Mips::FeatureCRC, "crc");
7999 // Synchronize the ABI Flags information with the FeatureBits information we
8000 // updated above.
8001 getTargetStreamer().updateABIInfo(*this);
8003 // If printing assembly, use the recently updated ABI Flags information.
8004 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8005 // emitted later).
8006 getTargetStreamer().emitDirectiveModuleCRC();
8008 // If this is not the end of the statement, report an error.
8009 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8010 reportParseError("unexpected token, expected end of statement");
8011 return false;
8014 return false; // parseDirectiveModule has finished successfully.
8015 } else if (Option == "nocrc") {
8016 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8018 // Synchronize the ABI Flags information with the FeatureBits information we
8019 // updated above.
8020 getTargetStreamer().updateABIInfo(*this);
8022 // If printing assembly, use the recently updated ABI Flags information.
8023 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8024 // emitted later).
8025 getTargetStreamer().emitDirectiveModuleNoCRC();
8027 // If this is not the end of the statement, report an error.
8028 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8029 reportParseError("unexpected token, expected end of statement");
8030 return false;
8033 return false; // parseDirectiveModule has finished successfully.
8034 } else if (Option == "virt") {
8035 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8037 // Synchronize the ABI Flags information with the FeatureBits information we
8038 // updated above.
8039 getTargetStreamer().updateABIInfo(*this);
8041 // If printing assembly, use the recently updated ABI Flags information.
8042 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8043 // emitted later).
8044 getTargetStreamer().emitDirectiveModuleVirt();
8046 // If this is not the end of the statement, report an error.
8047 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8048 reportParseError("unexpected token, expected end of statement");
8049 return false;
8052 return false; // parseDirectiveModule has finished successfully.
8053 } else if (Option == "novirt") {
8054 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8056 // Synchronize the ABI Flags information with the FeatureBits information we
8057 // updated above.
8058 getTargetStreamer().updateABIInfo(*this);
8060 // If printing assembly, use the recently updated ABI Flags information.
8061 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8062 // emitted later).
8063 getTargetStreamer().emitDirectiveModuleNoVirt();
8065 // If this is not the end of the statement, report an error.
8066 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8067 reportParseError("unexpected token, expected end of statement");
8068 return false;
8071 return false; // parseDirectiveModule has finished successfully.
8072 } else if (Option == "ginv") {
8073 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8075 // Synchronize the ABI Flags information with the FeatureBits information we
8076 // updated above.
8077 getTargetStreamer().updateABIInfo(*this);
8079 // If printing assembly, use the recently updated ABI Flags information.
8080 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8081 // emitted later).
8082 getTargetStreamer().emitDirectiveModuleGINV();
8084 // If this is not the end of the statement, report an error.
8085 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8086 reportParseError("unexpected token, expected end of statement");
8087 return false;
8090 return false; // parseDirectiveModule has finished successfully.
8091 } else if (Option == "noginv") {
8092 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8094 // Synchronize the ABI Flags information with the FeatureBits information we
8095 // updated above.
8096 getTargetStreamer().updateABIInfo(*this);
8098 // If printing assembly, use the recently updated ABI Flags information.
8099 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8100 // emitted later).
8101 getTargetStreamer().emitDirectiveModuleNoGINV();
8103 // If this is not the end of the statement, report an error.
8104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8105 reportParseError("unexpected token, expected end of statement");
8106 return false;
8109 return false; // parseDirectiveModule has finished successfully.
8110 } else {
8111 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8115 /// parseDirectiveModuleFP
8116 /// ::= =32
8117 /// ::= =xx
8118 /// ::= =64
8119 bool MipsAsmParser::parseDirectiveModuleFP() {
8120 MCAsmParser &Parser = getParser();
8121 MCAsmLexer &Lexer = getLexer();
8123 if (Lexer.isNot(AsmToken::Equal)) {
8124 reportParseError("unexpected token, expected equals sign '='");
8125 return false;
8127 Parser.Lex(); // Eat '=' token.
8129 MipsABIFlagsSection::FpABIKind FpABI;
8130 if (!parseFpABIValue(FpABI, ".module"))
8131 return false;
8133 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8134 reportParseError("unexpected token, expected end of statement");
8135 return false;
8138 // Synchronize the abiflags information with the FeatureBits information we
8139 // changed above.
8140 getTargetStreamer().updateABIInfo(*this);
8142 // If printing assembly, use the recently updated abiflags information.
8143 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8144 // emitted at the end).
8145 getTargetStreamer().emitDirectiveModuleFP();
8147 Parser.Lex(); // Consume the EndOfStatement.
8148 return false;
8151 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8152 StringRef Directive) {
8153 MCAsmParser &Parser = getParser();
8154 MCAsmLexer &Lexer = getLexer();
8155 bool ModuleLevelOptions = Directive == ".module";
8157 if (Lexer.is(AsmToken::Identifier)) {
8158 StringRef Value = Parser.getTok().getString();
8159 Parser.Lex();
8161 if (Value != "xx") {
8162 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8163 return false;
8166 if (!isABI_O32()) {
8167 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8168 return false;
8171 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8172 if (ModuleLevelOptions) {
8173 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8174 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8175 } else {
8176 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8177 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8179 return true;
8182 if (Lexer.is(AsmToken::Integer)) {
8183 unsigned Value = Parser.getTok().getIntVal();
8184 Parser.Lex();
8186 if (Value != 32 && Value != 64) {
8187 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8188 return false;
8191 if (Value == 32) {
8192 if (!isABI_O32()) {
8193 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8194 return false;
8197 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8198 if (ModuleLevelOptions) {
8199 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8200 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8201 } else {
8202 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8203 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8205 } else {
8206 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8207 if (ModuleLevelOptions) {
8208 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8209 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8210 } else {
8211 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8212 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8216 return true;
8219 return false;
8222 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8223 // This returns false if this function recognizes the directive
8224 // regardless of whether it is successfully handles or reports an
8225 // error. Otherwise it returns true to give the generic parser a
8226 // chance at recognizing it.
8228 MCAsmParser &Parser = getParser();
8229 StringRef IDVal = DirectiveID.getString();
8231 if (IDVal == ".cpload") {
8232 parseDirectiveCpLoad(DirectiveID.getLoc());
8233 return false;
8235 if (IDVal == ".cprestore") {
8236 parseDirectiveCpRestore(DirectiveID.getLoc());
8237 return false;
8239 if (IDVal == ".cplocal") {
8240 parseDirectiveCpLocal(DirectiveID.getLoc());
8241 return false;
8243 if (IDVal == ".ent") {
8244 StringRef SymbolName;
8246 if (Parser.parseIdentifier(SymbolName)) {
8247 reportParseError("expected identifier after .ent");
8248 return false;
8251 // There's an undocumented extension that allows an integer to
8252 // follow the name of the procedure which AFAICS is ignored by GAS.
8253 // Example: .ent foo,2
8254 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8255 if (getLexer().isNot(AsmToken::Comma)) {
8256 // Even though we accept this undocumented extension for compatibility
8257 // reasons, the additional integer argument does not actually change
8258 // the behaviour of the '.ent' directive, so we would like to discourage
8259 // its use. We do this by not referring to the extended version in
8260 // error messages which are not directly related to its use.
8261 reportParseError("unexpected token, expected end of statement");
8262 return false;
8264 Parser.Lex(); // Eat the comma.
8265 const MCExpr *DummyNumber;
8266 int64_t DummyNumberVal;
8267 // If the user was explicitly trying to use the extended version,
8268 // we still give helpful extension-related error messages.
8269 if (Parser.parseExpression(DummyNumber)) {
8270 reportParseError("expected number after comma");
8271 return false;
8273 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8274 reportParseError("expected an absolute expression after comma");
8275 return false;
8279 // If this is not the end of the statement, report an error.
8280 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8281 reportParseError("unexpected token, expected end of statement");
8282 return false;
8285 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8287 getTargetStreamer().emitDirectiveEnt(*Sym);
8288 CurrentFn = Sym;
8289 IsCpRestoreSet = false;
8290 return false;
8293 if (IDVal == ".end") {
8294 StringRef SymbolName;
8296 if (Parser.parseIdentifier(SymbolName)) {
8297 reportParseError("expected identifier after .end");
8298 return false;
8301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8302 reportParseError("unexpected token, expected end of statement");
8303 return false;
8306 if (CurrentFn == nullptr) {
8307 reportParseError(".end used without .ent");
8308 return false;
8311 if ((SymbolName != CurrentFn->getName())) {
8312 reportParseError(".end symbol does not match .ent symbol");
8313 return false;
8316 getTargetStreamer().emitDirectiveEnd(SymbolName);
8317 CurrentFn = nullptr;
8318 IsCpRestoreSet = false;
8319 return false;
8322 if (IDVal == ".frame") {
8323 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8324 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8325 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
8326 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8327 reportParseError("expected stack register");
8328 return false;
8331 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8332 if (!StackRegOpnd.isGPRAsmReg()) {
8333 reportParseError(StackRegOpnd.getStartLoc(),
8334 "expected general purpose register");
8335 return false;
8337 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8339 if (Parser.getTok().is(AsmToken::Comma))
8340 Parser.Lex();
8341 else {
8342 reportParseError("unexpected token, expected comma");
8343 return false;
8346 // Parse the frame size.
8347 const MCExpr *FrameSize;
8348 int64_t FrameSizeVal;
8350 if (Parser.parseExpression(FrameSize)) {
8351 reportParseError("expected frame size value");
8352 return false;
8355 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8356 reportParseError("frame size not an absolute expression");
8357 return false;
8360 if (Parser.getTok().is(AsmToken::Comma))
8361 Parser.Lex();
8362 else {
8363 reportParseError("unexpected token, expected comma");
8364 return false;
8367 // Parse the return register.
8368 TmpReg.clear();
8369 ResTy = parseAnyRegister(TmpReg);
8370 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8371 reportParseError("expected return register");
8372 return false;
8375 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8376 if (!ReturnRegOpnd.isGPRAsmReg()) {
8377 reportParseError(ReturnRegOpnd.getStartLoc(),
8378 "expected general purpose register");
8379 return false;
8382 // If this is not the end of the statement, report an error.
8383 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8384 reportParseError("unexpected token, expected end of statement");
8385 return false;
8388 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8389 ReturnRegOpnd.getGPR32Reg());
8390 IsCpRestoreSet = false;
8391 return false;
8394 if (IDVal == ".set") {
8395 parseDirectiveSet();
8396 return false;
8399 if (IDVal == ".mask" || IDVal == ".fmask") {
8400 // .mask bitmask, frame_offset
8401 // bitmask: One bit for each register used.
8402 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8403 // first register is expected to be saved.
8404 // Examples:
8405 // .mask 0x80000000, -4
8406 // .fmask 0x80000000, -4
8409 // Parse the bitmask
8410 const MCExpr *BitMask;
8411 int64_t BitMaskVal;
8413 if (Parser.parseExpression(BitMask)) {
8414 reportParseError("expected bitmask value");
8415 return false;
8418 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8419 reportParseError("bitmask not an absolute expression");
8420 return false;
8423 if (Parser.getTok().is(AsmToken::Comma))
8424 Parser.Lex();
8425 else {
8426 reportParseError("unexpected token, expected comma");
8427 return false;
8430 // Parse the frame_offset
8431 const MCExpr *FrameOffset;
8432 int64_t FrameOffsetVal;
8434 if (Parser.parseExpression(FrameOffset)) {
8435 reportParseError("expected frame offset value");
8436 return false;
8439 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8440 reportParseError("frame offset not an absolute expression");
8441 return false;
8444 // If this is not the end of the statement, report an error.
8445 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8446 reportParseError("unexpected token, expected end of statement");
8447 return false;
8450 if (IDVal == ".mask")
8451 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8452 else
8453 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8454 return false;
8457 if (IDVal == ".nan")
8458 return parseDirectiveNaN();
8460 if (IDVal == ".gpword") {
8461 parseDirectiveGpWord();
8462 return false;
8465 if (IDVal == ".gpdword") {
8466 parseDirectiveGpDWord();
8467 return false;
8470 if (IDVal == ".dtprelword") {
8471 parseDirectiveDtpRelWord();
8472 return false;
8475 if (IDVal == ".dtpreldword") {
8476 parseDirectiveDtpRelDWord();
8477 return false;
8480 if (IDVal == ".tprelword") {
8481 parseDirectiveTpRelWord();
8482 return false;
8485 if (IDVal == ".tpreldword") {
8486 parseDirectiveTpRelDWord();
8487 return false;
8490 if (IDVal == ".option") {
8491 parseDirectiveOption();
8492 return false;
8495 if (IDVal == ".abicalls") {
8496 getTargetStreamer().emitDirectiveAbiCalls();
8497 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8498 Error(Parser.getTok().getLoc(),
8499 "unexpected token, expected end of statement");
8501 return false;
8504 if (IDVal == ".cpsetup") {
8505 parseDirectiveCPSetup();
8506 return false;
8508 if (IDVal == ".cpreturn") {
8509 parseDirectiveCPReturn();
8510 return false;
8512 if (IDVal == ".module") {
8513 parseDirectiveModule();
8514 return false;
8516 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8517 parseInternalDirectiveReallowModule();
8518 return false;
8520 if (IDVal == ".insn") {
8521 parseInsnDirective();
8522 return false;
8524 if (IDVal == ".rdata") {
8525 parseRSectionDirective(".rodata");
8526 return false;
8528 if (IDVal == ".sbss") {
8529 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8530 return false;
8532 if (IDVal == ".sdata") {
8533 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8534 return false;
8537 return true;
8540 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8541 // If this is not the end of the statement, report an error.
8542 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8543 reportParseError("unexpected token, expected end of statement");
8544 return false;
8547 getTargetStreamer().reallowModuleDirective();
8549 getParser().Lex(); // Eat EndOfStatement token.
8550 return false;
8553 extern "C" void LLVMInitializeMipsAsmParser() {
8554 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8555 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8556 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8557 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8560 #define GET_REGISTER_MATCHER
8561 #define GET_MATCHER_IMPLEMENTATION
8562 #define GET_MNEMONIC_SPELL_CHECKER
8563 #include "MipsGenAsmMatcher.inc"
8565 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8566 // Find the appropriate table for this asm variant.
8567 const MatchEntry *Start, *End;
8568 switch (VariantID) {
8569 default: llvm_unreachable("invalid variant!");
8570 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8572 // Search the table.
8573 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8574 return MnemonicRange.first != MnemonicRange.second;