[ARM] VQADD instructions
[llvm-complete.git] / lib / Target / Mips / AsmParser / MipsAsmParser.cpp
blob8d567d42b96979b68a27e0d50c1523d3352d01c3
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 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3327 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3329 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3330 Out, STI);
3333 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3334 MCStreamer &Out,
3335 const MCSubtargetInfo *STI) {
3336 MipsTargetStreamer &TOut = getTargetStreamer();
3337 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3338 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3339 "Invalid instruction operand.");
3341 unsigned FirstReg = Inst.getOperand(0).getReg();
3342 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3344 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3346 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3348 unsigned TmpReg = getATReg(IDLoc);
3349 if (!TmpReg)
3350 return true;
3352 if (Lo_32(ImmOp64) == 0) {
3353 if (loadImmediate(ImmOp32, TmpReg, Mips::NoRegister, true, true, IDLoc, Out,
3354 STI))
3355 return true;
3356 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3357 return false;
3360 MCSection *CS = getStreamer().getCurrentSectionOnly();
3361 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3362 // where appropriate.
3363 MCSection *ReadOnlySection =
3364 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3366 MCSymbol *Sym = getContext().createTempSymbol();
3367 const MCExpr *LoSym =
3368 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3369 const MipsMCExpr *LoExpr =
3370 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3372 getStreamer().SwitchSection(ReadOnlySection);
3373 getStreamer().EmitLabel(Sym, IDLoc);
3374 getStreamer().EmitIntValue(ImmOp32, 4);
3375 getStreamer().SwitchSection(CS);
3377 if (emitPartialAddress(TOut, IDLoc, Sym))
3378 return true;
3379 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3380 IDLoc, STI);
3381 return false;
3384 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3385 MCStreamer &Out,
3386 const MCSubtargetInfo *STI) {
3387 MipsTargetStreamer &TOut = getTargetStreamer();
3388 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3389 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3390 "Invalid instruction operand.");
3392 unsigned FirstReg = Inst.getOperand(0).getReg();
3393 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3395 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3397 uint32_t LoImmOp64 = Lo_32(ImmOp64);
3398 uint32_t HiImmOp64 = Hi_32(ImmOp64);
3400 unsigned TmpReg = getATReg(IDLoc);
3401 if (!TmpReg)
3402 return true;
3404 if (LoImmOp64 == 0) {
3405 if (isABI_N32() || isABI_N64()) {
3406 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3407 IDLoc, Out, STI))
3408 return true;
3409 } else {
3410 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3411 IDLoc, Out, STI))
3412 return true;
3414 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3415 IDLoc, Out, STI))
3416 return true;
3418 return false;
3421 MCSection *CS = getStreamer().getCurrentSectionOnly();
3422 MCSection *ReadOnlySection =
3423 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3425 MCSymbol *Sym = getContext().createTempSymbol();
3426 const MCExpr *LoSym =
3427 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3428 const MipsMCExpr *LoExpr =
3429 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3431 getStreamer().SwitchSection(ReadOnlySection);
3432 getStreamer().EmitLabel(Sym, IDLoc);
3433 getStreamer().EmitIntValue(HiImmOp64, 4);
3434 getStreamer().EmitIntValue(LoImmOp64, 4);
3435 getStreamer().SwitchSection(CS);
3437 if (emitPartialAddress(TOut, IDLoc, Sym))
3438 return true;
3440 if (isABI_N64())
3441 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3442 IDLoc, STI);
3443 else
3444 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3445 IDLoc, STI);
3447 if (isABI_N32() || isABI_N64())
3448 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3449 else {
3450 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3451 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3453 return false;
3456 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3457 SMLoc IDLoc, MCStreamer &Out,
3458 const MCSubtargetInfo *STI) {
3459 MipsTargetStreamer &TOut = getTargetStreamer();
3460 assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3461 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3462 "Invalid instruction operand.");
3464 unsigned FirstReg = Inst.getOperand(0).getReg();
3465 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3467 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3469 uint32_t LoImmOp64 = Lo_32(ImmOp64);
3470 uint32_t HiImmOp64 = Hi_32(ImmOp64);
3472 unsigned TmpReg = getATReg(IDLoc);
3473 if (!TmpReg)
3474 return true;
3476 if ((LoImmOp64 == 0) &&
3477 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3478 // FIXME: In the case where the constant is zero, we can load the
3479 // register directly from the zero register.
3480 if (loadImmediate(HiImmOp64, TmpReg, Mips::NoRegister, true, true, IDLoc,
3481 Out, STI))
3482 return true;
3483 if (isABI_N32() || isABI_N64())
3484 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3485 else if (hasMips32r2()) {
3486 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3487 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3488 } else {
3489 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3490 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3492 return false;
3495 MCSection *CS = getStreamer().getCurrentSectionOnly();
3496 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3497 // where appropriate.
3498 MCSection *ReadOnlySection =
3499 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3501 MCSymbol *Sym = getContext().createTempSymbol();
3502 const MCExpr *LoSym =
3503 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3504 const MipsMCExpr *LoExpr =
3505 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3507 getStreamer().SwitchSection(ReadOnlySection);
3508 getStreamer().EmitLabel(Sym, IDLoc);
3509 getStreamer().EmitIntValue(HiImmOp64, 4);
3510 getStreamer().EmitIntValue(LoImmOp64, 4);
3511 getStreamer().SwitchSection(CS);
3513 if (emitPartialAddress(TOut, IDLoc, Sym))
3514 return true;
3516 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3517 MCOperand::createExpr(LoExpr), IDLoc, STI);
3519 return false;
3522 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3523 MCStreamer &Out,
3524 const MCSubtargetInfo *STI) {
3525 MipsTargetStreamer &TOut = getTargetStreamer();
3527 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3528 "unexpected number of operands");
3530 MCOperand Offset = Inst.getOperand(0);
3531 if (Offset.isExpr()) {
3532 Inst.clear();
3533 Inst.setOpcode(Mips::BEQ_MM);
3534 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3535 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3536 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3537 } else {
3538 assert(Offset.isImm() && "expected immediate operand kind");
3539 if (isInt<11>(Offset.getImm())) {
3540 // If offset fits into 11 bits then this instruction becomes microMIPS
3541 // 16-bit unconditional branch instruction.
3542 if (inMicroMipsMode())
3543 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3544 } else {
3545 if (!isInt<17>(Offset.getImm()))
3546 return Error(IDLoc, "branch target out of range");
3547 if (offsetToAlignment(Offset.getImm(), Align(2)))
3548 return Error(IDLoc, "branch to misaligned address");
3549 Inst.clear();
3550 Inst.setOpcode(Mips::BEQ_MM);
3551 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3552 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3553 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3556 Out.EmitInstruction(Inst, *STI);
3558 // If .set reorder is active and branch instruction has a delay slot,
3559 // emit a NOP after it.
3560 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3561 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3562 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3564 return false;
3567 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3568 const MCSubtargetInfo *STI) {
3569 MipsTargetStreamer &TOut = getTargetStreamer();
3570 const MCOperand &DstRegOp = Inst.getOperand(0);
3571 assert(DstRegOp.isReg() && "expected register operand kind");
3573 const MCOperand &ImmOp = Inst.getOperand(1);
3574 assert(ImmOp.isImm() && "expected immediate operand kind");
3576 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3577 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3578 "expected immediate or expression operand");
3580 bool IsLikely = false;
3582 unsigned OpCode = 0;
3583 switch(Inst.getOpcode()) {
3584 case Mips::BneImm:
3585 OpCode = Mips::BNE;
3586 break;
3587 case Mips::BeqImm:
3588 OpCode = Mips::BEQ;
3589 break;
3590 case Mips::BEQLImmMacro:
3591 OpCode = Mips::BEQL;
3592 IsLikely = true;
3593 break;
3594 case Mips::BNELImmMacro:
3595 OpCode = Mips::BNEL;
3596 IsLikely = true;
3597 break;
3598 default:
3599 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3600 break;
3603 int64_t ImmValue = ImmOp.getImm();
3604 if (ImmValue == 0) {
3605 if (IsLikely) {
3606 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3607 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3608 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3609 } else
3610 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3611 STI);
3612 } else {
3613 warnIfNoMacro(IDLoc);
3615 unsigned ATReg = getATReg(IDLoc);
3616 if (!ATReg)
3617 return true;
3619 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3620 IDLoc, Out, STI))
3621 return true;
3623 if (IsLikely) {
3624 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3625 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3626 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3627 } else
3628 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3630 return false;
3633 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3634 const MCSubtargetInfo *STI, bool IsLoad) {
3635 const MCOperand &DstRegOp = Inst.getOperand(0);
3636 assert(DstRegOp.isReg() && "expected register operand kind");
3637 const MCOperand &BaseRegOp = Inst.getOperand(1);
3638 assert(BaseRegOp.isReg() && "expected register operand kind");
3640 MipsTargetStreamer &TOut = getTargetStreamer();
3641 unsigned DstReg = DstRegOp.getReg();
3642 unsigned BaseReg = BaseRegOp.getReg();
3643 unsigned TmpReg = DstReg;
3645 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3646 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3647 unsigned DstRegClassID =
3648 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3649 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3650 (DstRegClassID == Mips::GPR64RegClassID);
3652 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3653 // At this point we need AT to perform the expansions
3654 // and we exit if it is not available.
3655 TmpReg = getATReg(IDLoc);
3656 if (!TmpReg)
3657 return;
3660 if (Inst.getNumOperands() > 3) {
3661 const MCOperand &BaseRegOp = Inst.getOperand(2);
3662 assert(BaseRegOp.isReg() && "expected register operand kind");
3663 const MCOperand &ExprOp = Inst.getOperand(3);
3664 assert(ExprOp.isExpr() && "expected expression oprand kind");
3666 unsigned BaseReg = BaseRegOp.getReg();
3667 const MCExpr *ExprOffset = ExprOp.getExpr();
3669 MCOperand LoOperand = MCOperand::createExpr(
3670 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3671 MCOperand HiOperand = MCOperand::createExpr(
3672 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3673 TOut.emitSCWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3674 LoOperand, TmpReg, IDLoc, STI);
3675 return;
3678 const MCOperand &OffsetOp = Inst.getOperand(2);
3680 if (OffsetOp.isImm()) {
3681 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3682 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3684 // If msb of LoOffset is 1(negative number) we must increment
3685 // HiOffset to account for the sign-extension of the low part.
3686 if (LoOffset & 0x8000)
3687 HiOffset += 0x10000;
3689 bool IsLargeOffset = HiOffset != 0;
3691 if (IsLargeOffset) {
3692 bool Is32BitImm = (HiOffset >> 32) == 0;
3693 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3694 IDLoc, Out, STI))
3695 return;
3698 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3699 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3700 BaseReg, IDLoc, STI);
3701 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3702 return;
3705 if (OffsetOp.isExpr()) {
3706 if (inPicMode()) {
3707 // FIXME:
3708 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3709 // do not exceed 16-bit.
3710 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3711 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3712 // of GOT entries.
3713 MCValue Res;
3714 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3715 Error(IDLoc, "expected relocatable expression");
3716 return;
3718 if (Res.getSymB() != nullptr) {
3719 Error(IDLoc, "expected relocatable expression with only one symbol");
3720 return;
3723 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3724 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3725 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, Res.getConstant(), IDLoc,
3726 STI);
3727 } else {
3728 // FIXME: Implement 64-bit case.
3729 // 1) lw $8, sym => lui $8, %hi(sym)
3730 // lw $8, %lo(sym)($8)
3731 // 2) sw $8, sym => lui $at, %hi(sym)
3732 // sw $8, %lo(sym)($at)
3733 const MCExpr *ExprOffset = OffsetOp.getExpr();
3734 MCOperand LoOperand = MCOperand::createExpr(
3735 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3736 MCOperand HiOperand = MCOperand::createExpr(
3737 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3739 // Generate the base address in TmpReg.
3740 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3741 if (BaseReg != Mips::ZERO)
3742 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3743 // Emit the load or store with the adjusted base and offset.
3744 TOut.emitRRX(Inst.getOpcode(), DstReg, TmpReg, LoOperand, IDLoc, STI);
3746 return;
3749 llvm_unreachable("unexpected operand type");
3752 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3753 MCStreamer &Out,
3754 const MCSubtargetInfo *STI) {
3755 unsigned OpNum = Inst.getNumOperands();
3756 unsigned Opcode = Inst.getOpcode();
3757 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3759 assert(Inst.getOperand(OpNum - 1).isImm() &&
3760 Inst.getOperand(OpNum - 2).isReg() &&
3761 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3763 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3764 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3765 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3766 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3767 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3768 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3769 // It can be implemented as SWM16 or LWM16 instruction.
3770 if (inMicroMipsMode() && hasMips32r6())
3771 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3772 else
3773 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3776 Inst.setOpcode(NewOpcode);
3777 Out.EmitInstruction(Inst, *STI);
3778 return false;
3781 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3782 MCStreamer &Out,
3783 const MCSubtargetInfo *STI) {
3784 MipsTargetStreamer &TOut = getTargetStreamer();
3785 bool EmittedNoMacroWarning = false;
3786 unsigned PseudoOpcode = Inst.getOpcode();
3787 unsigned SrcReg = Inst.getOperand(0).getReg();
3788 const MCOperand &TrgOp = Inst.getOperand(1);
3789 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3791 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3792 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3794 unsigned TrgReg;
3795 if (TrgOp.isReg())
3796 TrgReg = TrgOp.getReg();
3797 else if (TrgOp.isImm()) {
3798 warnIfNoMacro(IDLoc);
3799 EmittedNoMacroWarning = true;
3801 TrgReg = getATReg(IDLoc);
3802 if (!TrgReg)
3803 return true;
3805 switch(PseudoOpcode) {
3806 default:
3807 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3808 case Mips::BLTImmMacro:
3809 PseudoOpcode = Mips::BLT;
3810 break;
3811 case Mips::BLEImmMacro:
3812 PseudoOpcode = Mips::BLE;
3813 break;
3814 case Mips::BGEImmMacro:
3815 PseudoOpcode = Mips::BGE;
3816 break;
3817 case Mips::BGTImmMacro:
3818 PseudoOpcode = Mips::BGT;
3819 break;
3820 case Mips::BLTUImmMacro:
3821 PseudoOpcode = Mips::BLTU;
3822 break;
3823 case Mips::BLEUImmMacro:
3824 PseudoOpcode = Mips::BLEU;
3825 break;
3826 case Mips::BGEUImmMacro:
3827 PseudoOpcode = Mips::BGEU;
3828 break;
3829 case Mips::BGTUImmMacro:
3830 PseudoOpcode = Mips::BGTU;
3831 break;
3832 case Mips::BLTLImmMacro:
3833 PseudoOpcode = Mips::BLTL;
3834 break;
3835 case Mips::BLELImmMacro:
3836 PseudoOpcode = Mips::BLEL;
3837 break;
3838 case Mips::BGELImmMacro:
3839 PseudoOpcode = Mips::BGEL;
3840 break;
3841 case Mips::BGTLImmMacro:
3842 PseudoOpcode = Mips::BGTL;
3843 break;
3844 case Mips::BLTULImmMacro:
3845 PseudoOpcode = Mips::BLTUL;
3846 break;
3847 case Mips::BLEULImmMacro:
3848 PseudoOpcode = Mips::BLEUL;
3849 break;
3850 case Mips::BGEULImmMacro:
3851 PseudoOpcode = Mips::BGEUL;
3852 break;
3853 case Mips::BGTULImmMacro:
3854 PseudoOpcode = Mips::BGTUL;
3855 break;
3858 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3859 false, IDLoc, Out, STI))
3860 return true;
3863 switch (PseudoOpcode) {
3864 case Mips::BLT:
3865 case Mips::BLTU:
3866 case Mips::BLTL:
3867 case Mips::BLTUL:
3868 AcceptsEquality = false;
3869 ReverseOrderSLT = false;
3870 IsUnsigned =
3871 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3872 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3873 ZeroSrcOpcode = Mips::BGTZ;
3874 ZeroTrgOpcode = Mips::BLTZ;
3875 break;
3876 case Mips::BLE:
3877 case Mips::BLEU:
3878 case Mips::BLEL:
3879 case Mips::BLEUL:
3880 AcceptsEquality = true;
3881 ReverseOrderSLT = true;
3882 IsUnsigned =
3883 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3884 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3885 ZeroSrcOpcode = Mips::BGEZ;
3886 ZeroTrgOpcode = Mips::BLEZ;
3887 break;
3888 case Mips::BGE:
3889 case Mips::BGEU:
3890 case Mips::BGEL:
3891 case Mips::BGEUL:
3892 AcceptsEquality = true;
3893 ReverseOrderSLT = false;
3894 IsUnsigned =
3895 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3896 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3897 ZeroSrcOpcode = Mips::BLEZ;
3898 ZeroTrgOpcode = Mips::BGEZ;
3899 break;
3900 case Mips::BGT:
3901 case Mips::BGTU:
3902 case Mips::BGTL:
3903 case Mips::BGTUL:
3904 AcceptsEquality = false;
3905 ReverseOrderSLT = true;
3906 IsUnsigned =
3907 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3908 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3909 ZeroSrcOpcode = Mips::BLTZ;
3910 ZeroTrgOpcode = Mips::BGTZ;
3911 break;
3912 default:
3913 llvm_unreachable("unknown opcode for branch pseudo-instruction");
3916 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3917 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3918 if (IsSrcRegZero && IsTrgRegZero) {
3919 // FIXME: All of these Opcode-specific if's are needed for compatibility
3920 // with GAS' behaviour. However, they may not generate the most efficient
3921 // code in some circumstances.
3922 if (PseudoOpcode == Mips::BLT) {
3923 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3924 IDLoc, STI);
3925 return false;
3927 if (PseudoOpcode == Mips::BLE) {
3928 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3929 IDLoc, STI);
3930 Warning(IDLoc, "branch is always taken");
3931 return false;
3933 if (PseudoOpcode == Mips::BGE) {
3934 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3935 IDLoc, STI);
3936 Warning(IDLoc, "branch is always taken");
3937 return false;
3939 if (PseudoOpcode == Mips::BGT) {
3940 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3941 IDLoc, STI);
3942 return false;
3944 if (PseudoOpcode == Mips::BGTU) {
3945 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3946 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3947 return false;
3949 if (AcceptsEquality) {
3950 // If both registers are $0 and the pseudo-branch accepts equality, it
3951 // will always be taken, so we emit an unconditional branch.
3952 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3953 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3954 Warning(IDLoc, "branch is always taken");
3955 return false;
3957 // If both registers are $0 and the pseudo-branch does not accept
3958 // equality, it will never be taken, so we don't have to emit anything.
3959 return false;
3961 if (IsSrcRegZero || IsTrgRegZero) {
3962 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3963 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3964 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3965 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3966 // the pseudo-branch will never be taken, so we don't emit anything.
3967 // This only applies to unsigned pseudo-branches.
3968 return false;
3970 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3971 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3972 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3973 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3974 // the pseudo-branch will always be taken, so we emit an unconditional
3975 // branch.
3976 // This only applies to unsigned pseudo-branches.
3977 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3978 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3979 Warning(IDLoc, "branch is always taken");
3980 return false;
3982 if (IsUnsigned) {
3983 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3984 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3985 // the pseudo-branch will be taken only when the non-zero register is
3986 // different from 0, so we emit a BNEZ.
3988 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3989 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3990 // the pseudo-branch will be taken only when the non-zero register is
3991 // equal to 0, so we emit a BEQZ.
3993 // Because only BLEU and BGEU branch on equality, we can use the
3994 // AcceptsEquality variable to decide when to emit the BEQZ.
3995 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3996 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3997 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3998 return false;
4000 // If we have a signed pseudo-branch and one of the registers is $0,
4001 // we can use an appropriate compare-to-zero branch. We select which one
4002 // to use in the switch statement above.
4003 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4004 IsSrcRegZero ? TrgReg : SrcReg,
4005 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4006 return false;
4009 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4010 // expansions. If it is not available, we return.
4011 unsigned ATRegNum = getATReg(IDLoc);
4012 if (!ATRegNum)
4013 return true;
4015 if (!EmittedNoMacroWarning)
4016 warnIfNoMacro(IDLoc);
4018 // SLT fits well with 2 of our 4 pseudo-branches:
4019 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4020 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4021 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4022 // This is accomplished by using a BNEZ with the result of the SLT.
4024 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4025 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4026 // Because only BGE and BLE branch on equality, we can use the
4027 // AcceptsEquality variable to decide when to emit the BEQZ.
4028 // Note that the order of the SLT arguments doesn't change between
4029 // opposites.
4031 // The same applies to the unsigned variants, except that SLTu is used
4032 // instead of SLT.
4033 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4034 ReverseOrderSLT ? TrgReg : SrcReg,
4035 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4037 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4038 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4039 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4040 STI);
4041 return false;
4044 // Expand a integer division macro.
4046 // Notably we don't have to emit a warning when encountering $rt as the $zero
4047 // register, or 0 as an immediate. processInstruction() has already done that.
4049 // The destination register can only be $zero when expanding (S)DivIMacro or
4050 // D(S)DivMacro.
4052 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4053 const MCSubtargetInfo *STI, const bool IsMips64,
4054 const bool Signed) {
4055 MipsTargetStreamer &TOut = getTargetStreamer();
4057 warnIfNoMacro(IDLoc);
4059 const MCOperand &RdRegOp = Inst.getOperand(0);
4060 assert(RdRegOp.isReg() && "expected register operand kind");
4061 unsigned RdReg = RdRegOp.getReg();
4063 const MCOperand &RsRegOp = Inst.getOperand(1);
4064 assert(RsRegOp.isReg() && "expected register operand kind");
4065 unsigned RsReg = RsRegOp.getReg();
4067 unsigned RtReg;
4068 int64_t ImmValue;
4070 const MCOperand &RtOp = Inst.getOperand(2);
4071 assert((RtOp.isReg() || RtOp.isImm()) &&
4072 "expected register or immediate operand kind");
4073 if (RtOp.isReg())
4074 RtReg = RtOp.getReg();
4075 else
4076 ImmValue = RtOp.getImm();
4078 unsigned DivOp;
4079 unsigned ZeroReg;
4080 unsigned SubOp;
4082 if (IsMips64) {
4083 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4084 ZeroReg = Mips::ZERO_64;
4085 SubOp = Mips::DSUB;
4086 } else {
4087 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4088 ZeroReg = Mips::ZERO;
4089 SubOp = Mips::SUB;
4092 bool UseTraps = useTraps();
4094 unsigned Opcode = Inst.getOpcode();
4095 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4096 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4097 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4098 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4100 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4101 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4102 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4103 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4105 if (RtOp.isImm()) {
4106 unsigned ATReg = getATReg(IDLoc);
4107 if (!ATReg)
4108 return true;
4110 if (ImmValue == 0) {
4111 if (UseTraps)
4112 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4113 else
4114 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4115 return false;
4118 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4119 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4120 return false;
4121 } else if (isDiv && ImmValue == 1) {
4122 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4123 return false;
4124 } else if (isDiv && Signed && ImmValue == -1) {
4125 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4126 return false;
4127 } else {
4128 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4129 false, Inst.getLoc(), Out, STI))
4130 return true;
4131 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4132 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4133 return false;
4135 return true;
4138 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4139 // break, insert the trap/break and exit. This gives a different result to
4140 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4141 // are handled equivalently. As the observed behaviour is the same, we're ok.
4142 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4143 if (UseTraps) {
4144 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4145 return false;
4147 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4148 return false;
4151 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4152 // not expand to macro sequence.
4153 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4154 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4155 return false;
4158 // Temporary label for first branch traget
4159 MCContext &Context = TOut.getStreamer().getContext();
4160 MCSymbol *BrTarget;
4161 MCOperand LabelOp;
4163 if (UseTraps) {
4164 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4165 } else {
4166 // Branch to the li instruction.
4167 BrTarget = Context.createTempSymbol();
4168 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4169 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4172 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4174 if (!UseTraps)
4175 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4177 if (!Signed) {
4178 if (!UseTraps)
4179 TOut.getStreamer().EmitLabel(BrTarget);
4181 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4182 return false;
4185 unsigned ATReg = getATReg(IDLoc);
4186 if (!ATReg)
4187 return true;
4189 if (!UseTraps)
4190 TOut.getStreamer().EmitLabel(BrTarget);
4192 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4194 // Temporary label for the second branch target.
4195 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4196 MCOperand LabelOpEnd =
4197 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4199 // Branch to the mflo instruction.
4200 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4202 if (IsMips64) {
4203 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4204 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4205 } else {
4206 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4209 if (UseTraps)
4210 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4211 else {
4212 // Branch to the mflo instruction.
4213 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4214 TOut.emitNop(IDLoc, STI);
4215 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4218 TOut.getStreamer().EmitLabel(BrTargetEnd);
4219 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4220 return false;
4223 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4224 SMLoc IDLoc, MCStreamer &Out,
4225 const MCSubtargetInfo *STI) {
4226 MipsTargetStreamer &TOut = getTargetStreamer();
4228 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4229 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4230 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4232 unsigned FirstReg = Inst.getOperand(0).getReg();
4233 unsigned SecondReg = Inst.getOperand(1).getReg();
4234 unsigned ThirdReg = Inst.getOperand(2).getReg();
4236 if (hasMips1() && !hasMips2()) {
4237 unsigned ATReg = getATReg(IDLoc);
4238 if (!ATReg)
4239 return true;
4240 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4241 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4242 TOut.emitNop(IDLoc, STI);
4243 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4244 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4245 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4246 TOut.emitNop(IDLoc, STI);
4247 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4248 : Mips::CVT_W_S,
4249 FirstReg, SecondReg, IDLoc, STI);
4250 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4251 TOut.emitNop(IDLoc, STI);
4252 return false;
4255 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4256 : Mips::TRUNC_W_S,
4257 FirstReg, SecondReg, IDLoc, STI);
4259 return false;
4262 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4263 MCStreamer &Out, const MCSubtargetInfo *STI) {
4264 if (hasMips32r6() || hasMips64r6()) {
4265 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4268 const MCOperand &DstRegOp = Inst.getOperand(0);
4269 assert(DstRegOp.isReg() && "expected register operand kind");
4270 const MCOperand &SrcRegOp = Inst.getOperand(1);
4271 assert(SrcRegOp.isReg() && "expected register operand kind");
4272 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4273 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4275 MipsTargetStreamer &TOut = getTargetStreamer();
4276 unsigned DstReg = DstRegOp.getReg();
4277 unsigned SrcReg = SrcRegOp.getReg();
4278 int64_t OffsetValue = OffsetImmOp.getImm();
4280 // NOTE: We always need AT for ULHU, as it is always used as the source
4281 // register for one of the LBu's.
4282 warnIfNoMacro(IDLoc);
4283 unsigned ATReg = getATReg(IDLoc);
4284 if (!ATReg)
4285 return true;
4287 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4288 if (IsLargeOffset) {
4289 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4290 IDLoc, Out, STI))
4291 return true;
4294 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4295 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4296 if (isLittle())
4297 std::swap(FirstOffset, SecondOffset);
4299 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4300 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4302 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4303 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4305 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4306 FirstOffset, IDLoc, STI);
4307 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4308 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4309 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4311 return false;
4314 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4315 const MCSubtargetInfo *STI) {
4316 if (hasMips32r6() || hasMips64r6()) {
4317 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4320 const MCOperand &DstRegOp = Inst.getOperand(0);
4321 assert(DstRegOp.isReg() && "expected register operand kind");
4322 const MCOperand &SrcRegOp = Inst.getOperand(1);
4323 assert(SrcRegOp.isReg() && "expected register operand kind");
4324 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4325 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4327 MipsTargetStreamer &TOut = getTargetStreamer();
4328 unsigned DstReg = DstRegOp.getReg();
4329 unsigned SrcReg = SrcRegOp.getReg();
4330 int64_t OffsetValue = OffsetImmOp.getImm();
4332 warnIfNoMacro(IDLoc);
4333 unsigned ATReg = getATReg(IDLoc);
4334 if (!ATReg)
4335 return true;
4337 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4338 if (IsLargeOffset) {
4339 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4340 IDLoc, Out, STI))
4341 return true;
4344 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4345 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4346 if (isLittle())
4347 std::swap(FirstOffset, SecondOffset);
4349 if (IsLargeOffset) {
4350 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4351 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4352 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4353 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4354 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4355 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4356 } else {
4357 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4358 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4359 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4362 return false;
4365 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4366 const MCSubtargetInfo *STI) {
4367 if (hasMips32r6() || hasMips64r6()) {
4368 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4371 const MCOperand &DstRegOp = Inst.getOperand(0);
4372 assert(DstRegOp.isReg() && "expected register operand kind");
4373 const MCOperand &SrcRegOp = Inst.getOperand(1);
4374 assert(SrcRegOp.isReg() && "expected register operand kind");
4375 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4376 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4378 MipsTargetStreamer &TOut = getTargetStreamer();
4379 unsigned DstReg = DstRegOp.getReg();
4380 unsigned SrcReg = SrcRegOp.getReg();
4381 int64_t OffsetValue = OffsetImmOp.getImm();
4383 // Compute left/right load/store offsets.
4384 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4385 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4386 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4387 if (isLittle())
4388 std::swap(LxlOffset, LxrOffset);
4390 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4391 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4392 unsigned TmpReg = SrcReg;
4393 if (IsLargeOffset || DoMove) {
4394 warnIfNoMacro(IDLoc);
4395 TmpReg = getATReg(IDLoc);
4396 if (!TmpReg)
4397 return true;
4400 if (IsLargeOffset) {
4401 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4402 IDLoc, Out, STI))
4403 return true;
4406 if (DoMove)
4407 std::swap(DstReg, TmpReg);
4409 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4410 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4411 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4412 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4414 if (DoMove)
4415 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4417 return false;
4420 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4421 const MCSubtargetInfo *STI) {
4422 MipsTargetStreamer &TOut = getTargetStreamer();
4424 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4425 assert(Inst.getOperand(0).isReg() &&
4426 Inst.getOperand(1).isReg() &&
4427 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4429 unsigned DstReg = Inst.getOperand(0).getReg();
4430 unsigned SrcReg = Inst.getOperand(1).getReg();
4431 unsigned OpReg = Inst.getOperand(2).getReg();
4432 unsigned OpCode;
4434 warnIfNoMacro(IDLoc);
4436 switch (Inst.getOpcode()) {
4437 case Mips::SGE:
4438 OpCode = Mips::SLT;
4439 break;
4440 case Mips::SGEU:
4441 OpCode = Mips::SLTu;
4442 break;
4443 default:
4444 llvm_unreachable("unexpected 'sge' opcode");
4447 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4448 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4449 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4451 return false;
4454 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4455 const MCSubtargetInfo *STI) {
4456 MipsTargetStreamer &TOut = getTargetStreamer();
4458 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4459 assert(Inst.getOperand(0).isReg() &&
4460 Inst.getOperand(1).isReg() &&
4461 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4463 unsigned DstReg = Inst.getOperand(0).getReg();
4464 unsigned SrcReg = Inst.getOperand(1).getReg();
4465 int64_t ImmValue = Inst.getOperand(2).getImm();
4466 unsigned OpRegCode, OpImmCode;
4468 warnIfNoMacro(IDLoc);
4470 switch (Inst.getOpcode()) {
4471 case Mips::SGEImm:
4472 case Mips::SGEImm64:
4473 OpRegCode = Mips::SLT;
4474 OpImmCode = Mips::SLTi;
4475 break;
4476 case Mips::SGEUImm:
4477 case Mips::SGEUImm64:
4478 OpRegCode = Mips::SLTu;
4479 OpImmCode = Mips::SLTiu;
4480 break;
4481 default:
4482 llvm_unreachable("unexpected 'sge' opcode with immediate");
4485 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4486 if (isInt<16>(ImmValue)) {
4487 // Use immediate version of STL.
4488 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4489 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4490 } else {
4491 unsigned ImmReg = DstReg;
4492 if (DstReg == SrcReg) {
4493 unsigned ATReg = getATReg(Inst.getLoc());
4494 if (!ATReg)
4495 return true;
4496 ImmReg = ATReg;
4499 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4500 false, IDLoc, Out, STI))
4501 return true;
4503 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4504 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4507 return false;
4510 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4511 const MCSubtargetInfo *STI) {
4512 MipsTargetStreamer &TOut = getTargetStreamer();
4514 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4515 assert(Inst.getOperand(0).isReg() &&
4516 Inst.getOperand(1).isReg() &&
4517 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4519 unsigned DstReg = Inst.getOperand(0).getReg();
4520 unsigned SrcReg = Inst.getOperand(1).getReg();
4521 unsigned ImmReg = DstReg;
4522 int64_t ImmValue = Inst.getOperand(2).getImm();
4523 unsigned OpCode;
4525 warnIfNoMacro(IDLoc);
4527 switch (Inst.getOpcode()) {
4528 case Mips::SGTImm:
4529 case Mips::SGTImm64:
4530 OpCode = Mips::SLT;
4531 break;
4532 case Mips::SGTUImm:
4533 case Mips::SGTUImm64:
4534 OpCode = Mips::SLTu;
4535 break;
4536 default:
4537 llvm_unreachable("unexpected 'sgt' opcode with immediate");
4540 if (DstReg == SrcReg) {
4541 unsigned ATReg = getATReg(Inst.getLoc());
4542 if (!ATReg)
4543 return true;
4544 ImmReg = ATReg;
4547 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4548 false, IDLoc, Out, STI))
4549 return true;
4551 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4552 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4554 return false;
4557 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4558 MCStreamer &Out,
4559 const MCSubtargetInfo *STI) {
4560 MipsTargetStreamer &TOut = getTargetStreamer();
4562 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4563 assert(Inst.getOperand(0).isReg() &&
4564 Inst.getOperand(1).isReg() &&
4565 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4567 unsigned ATReg = Mips::NoRegister;
4568 unsigned FinalDstReg = Mips::NoRegister;
4569 unsigned DstReg = Inst.getOperand(0).getReg();
4570 unsigned SrcReg = Inst.getOperand(1).getReg();
4571 int64_t ImmValue = Inst.getOperand(2).getImm();
4573 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4575 unsigned FinalOpcode = Inst.getOpcode();
4577 if (DstReg == SrcReg) {
4578 ATReg = getATReg(Inst.getLoc());
4579 if (!ATReg)
4580 return true;
4581 FinalDstReg = DstReg;
4582 DstReg = ATReg;
4585 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4586 Inst.getLoc(), Out, STI)) {
4587 switch (FinalOpcode) {
4588 default:
4589 llvm_unreachable("unimplemented expansion");
4590 case Mips::ADDi:
4591 FinalOpcode = Mips::ADD;
4592 break;
4593 case Mips::ADDiu:
4594 FinalOpcode = Mips::ADDu;
4595 break;
4596 case Mips::ANDi:
4597 FinalOpcode = Mips::AND;
4598 break;
4599 case Mips::NORImm:
4600 FinalOpcode = Mips::NOR;
4601 break;
4602 case Mips::ORi:
4603 FinalOpcode = Mips::OR;
4604 break;
4605 case Mips::SLTi:
4606 FinalOpcode = Mips::SLT;
4607 break;
4608 case Mips::SLTiu:
4609 FinalOpcode = Mips::SLTu;
4610 break;
4611 case Mips::XORi:
4612 FinalOpcode = Mips::XOR;
4613 break;
4614 case Mips::ADDi_MM:
4615 FinalOpcode = Mips::ADD_MM;
4616 break;
4617 case Mips::ADDiu_MM:
4618 FinalOpcode = Mips::ADDu_MM;
4619 break;
4620 case Mips::ANDi_MM:
4621 FinalOpcode = Mips::AND_MM;
4622 break;
4623 case Mips::ORi_MM:
4624 FinalOpcode = Mips::OR_MM;
4625 break;
4626 case Mips::SLTi_MM:
4627 FinalOpcode = Mips::SLT_MM;
4628 break;
4629 case Mips::SLTiu_MM:
4630 FinalOpcode = Mips::SLTu_MM;
4631 break;
4632 case Mips::XORi_MM:
4633 FinalOpcode = Mips::XOR_MM;
4634 break;
4635 case Mips::ANDi64:
4636 FinalOpcode = Mips::AND64;
4637 break;
4638 case Mips::NORImm64:
4639 FinalOpcode = Mips::NOR64;
4640 break;
4641 case Mips::ORi64:
4642 FinalOpcode = Mips::OR64;
4643 break;
4644 case Mips::SLTImm64:
4645 FinalOpcode = Mips::SLT64;
4646 break;
4647 case Mips::SLTUImm64:
4648 FinalOpcode = Mips::SLTu64;
4649 break;
4650 case Mips::XORi64:
4651 FinalOpcode = Mips::XOR64;
4652 break;
4655 if (FinalDstReg == Mips::NoRegister)
4656 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4657 else
4658 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4659 return false;
4661 return true;
4664 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4665 const MCSubtargetInfo *STI) {
4666 MipsTargetStreamer &TOut = getTargetStreamer();
4667 unsigned ATReg = Mips::NoRegister;
4668 unsigned DReg = Inst.getOperand(0).getReg();
4669 unsigned SReg = Inst.getOperand(1).getReg();
4670 unsigned TReg = Inst.getOperand(2).getReg();
4671 unsigned TmpReg = DReg;
4673 unsigned FirstShift = Mips::NOP;
4674 unsigned SecondShift = Mips::NOP;
4676 if (hasMips32r2()) {
4677 if (DReg == SReg) {
4678 TmpReg = getATReg(Inst.getLoc());
4679 if (!TmpReg)
4680 return true;
4683 if (Inst.getOpcode() == Mips::ROL) {
4684 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4685 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4686 return false;
4689 if (Inst.getOpcode() == Mips::ROR) {
4690 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4691 return false;
4694 return true;
4697 if (hasMips32()) {
4698 switch (Inst.getOpcode()) {
4699 default:
4700 llvm_unreachable("unexpected instruction opcode");
4701 case Mips::ROL:
4702 FirstShift = Mips::SRLV;
4703 SecondShift = Mips::SLLV;
4704 break;
4705 case Mips::ROR:
4706 FirstShift = Mips::SLLV;
4707 SecondShift = Mips::SRLV;
4708 break;
4711 ATReg = getATReg(Inst.getLoc());
4712 if (!ATReg)
4713 return true;
4715 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4716 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4717 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4718 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4720 return false;
4723 return true;
4726 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4727 MCStreamer &Out,
4728 const MCSubtargetInfo *STI) {
4729 MipsTargetStreamer &TOut = getTargetStreamer();
4730 unsigned ATReg = Mips::NoRegister;
4731 unsigned DReg = Inst.getOperand(0).getReg();
4732 unsigned SReg = Inst.getOperand(1).getReg();
4733 int64_t ImmValue = Inst.getOperand(2).getImm();
4735 unsigned FirstShift = Mips::NOP;
4736 unsigned SecondShift = Mips::NOP;
4738 if (hasMips32r2()) {
4739 if (Inst.getOpcode() == Mips::ROLImm) {
4740 uint64_t MaxShift = 32;
4741 uint64_t ShiftValue = ImmValue;
4742 if (ImmValue != 0)
4743 ShiftValue = MaxShift - ImmValue;
4744 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4745 return false;
4748 if (Inst.getOpcode() == Mips::RORImm) {
4749 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4750 return false;
4753 return true;
4756 if (hasMips32()) {
4757 if (ImmValue == 0) {
4758 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4759 return false;
4762 switch (Inst.getOpcode()) {
4763 default:
4764 llvm_unreachable("unexpected instruction opcode");
4765 case Mips::ROLImm:
4766 FirstShift = Mips::SLL;
4767 SecondShift = Mips::SRL;
4768 break;
4769 case Mips::RORImm:
4770 FirstShift = Mips::SRL;
4771 SecondShift = Mips::SLL;
4772 break;
4775 ATReg = getATReg(Inst.getLoc());
4776 if (!ATReg)
4777 return true;
4779 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4780 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4781 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4783 return false;
4786 return true;
4789 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4790 const MCSubtargetInfo *STI) {
4791 MipsTargetStreamer &TOut = getTargetStreamer();
4792 unsigned ATReg = Mips::NoRegister;
4793 unsigned DReg = Inst.getOperand(0).getReg();
4794 unsigned SReg = Inst.getOperand(1).getReg();
4795 unsigned TReg = Inst.getOperand(2).getReg();
4796 unsigned TmpReg = DReg;
4798 unsigned FirstShift = Mips::NOP;
4799 unsigned SecondShift = Mips::NOP;
4801 if (hasMips64r2()) {
4802 if (TmpReg == SReg) {
4803 TmpReg = getATReg(Inst.getLoc());
4804 if (!TmpReg)
4805 return true;
4808 if (Inst.getOpcode() == Mips::DROL) {
4809 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4810 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4811 return false;
4814 if (Inst.getOpcode() == Mips::DROR) {
4815 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4816 return false;
4819 return true;
4822 if (hasMips64()) {
4823 switch (Inst.getOpcode()) {
4824 default:
4825 llvm_unreachable("unexpected instruction opcode");
4826 case Mips::DROL:
4827 FirstShift = Mips::DSRLV;
4828 SecondShift = Mips::DSLLV;
4829 break;
4830 case Mips::DROR:
4831 FirstShift = Mips::DSLLV;
4832 SecondShift = Mips::DSRLV;
4833 break;
4836 ATReg = getATReg(Inst.getLoc());
4837 if (!ATReg)
4838 return true;
4840 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4841 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4842 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4843 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4845 return false;
4848 return true;
4851 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4852 MCStreamer &Out,
4853 const MCSubtargetInfo *STI) {
4854 MipsTargetStreamer &TOut = getTargetStreamer();
4855 unsigned ATReg = Mips::NoRegister;
4856 unsigned DReg = Inst.getOperand(0).getReg();
4857 unsigned SReg = Inst.getOperand(1).getReg();
4858 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4860 unsigned FirstShift = Mips::NOP;
4861 unsigned SecondShift = Mips::NOP;
4863 MCInst TmpInst;
4865 if (hasMips64r2()) {
4866 unsigned FinalOpcode = Mips::NOP;
4867 if (ImmValue == 0)
4868 FinalOpcode = Mips::DROTR;
4869 else if (ImmValue % 32 == 0)
4870 FinalOpcode = Mips::DROTR32;
4871 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4872 if (Inst.getOpcode() == Mips::DROLImm)
4873 FinalOpcode = Mips::DROTR32;
4874 else
4875 FinalOpcode = Mips::DROTR;
4876 } else if (ImmValue >= 33) {
4877 if (Inst.getOpcode() == Mips::DROLImm)
4878 FinalOpcode = Mips::DROTR;
4879 else
4880 FinalOpcode = Mips::DROTR32;
4883 uint64_t ShiftValue = ImmValue % 32;
4884 if (Inst.getOpcode() == Mips::DROLImm)
4885 ShiftValue = (32 - ImmValue % 32) % 32;
4887 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4889 return false;
4892 if (hasMips64()) {
4893 if (ImmValue == 0) {
4894 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4895 return false;
4898 switch (Inst.getOpcode()) {
4899 default:
4900 llvm_unreachable("unexpected instruction opcode");
4901 case Mips::DROLImm:
4902 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4903 FirstShift = Mips::DSLL;
4904 SecondShift = Mips::DSRL32;
4906 if (ImmValue == 32) {
4907 FirstShift = Mips::DSLL32;
4908 SecondShift = Mips::DSRL32;
4910 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4911 FirstShift = Mips::DSLL32;
4912 SecondShift = Mips::DSRL;
4914 break;
4915 case Mips::DRORImm:
4916 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4917 FirstShift = Mips::DSRL;
4918 SecondShift = Mips::DSLL32;
4920 if (ImmValue == 32) {
4921 FirstShift = Mips::DSRL32;
4922 SecondShift = Mips::DSLL32;
4924 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4925 FirstShift = Mips::DSRL32;
4926 SecondShift = Mips::DSLL;
4928 break;
4931 ATReg = getATReg(Inst.getLoc());
4932 if (!ATReg)
4933 return true;
4935 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4936 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4937 Inst.getLoc(), STI);
4938 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4940 return false;
4943 return true;
4946 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4947 const MCSubtargetInfo *STI) {
4948 MipsTargetStreamer &TOut = getTargetStreamer();
4949 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4950 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4952 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4953 if (FirstRegOp != SecondRegOp)
4954 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4955 else
4956 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4957 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4959 return false;
4962 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4963 const MCSubtargetInfo *STI) {
4964 MipsTargetStreamer &TOut = getTargetStreamer();
4965 unsigned ATReg = Mips::NoRegister;
4966 unsigned DstReg = Inst.getOperand(0).getReg();
4967 unsigned SrcReg = Inst.getOperand(1).getReg();
4968 int32_t ImmValue = Inst.getOperand(2).getImm();
4970 ATReg = getATReg(IDLoc);
4971 if (!ATReg)
4972 return true;
4974 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4975 STI);
4977 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4978 SrcReg, ATReg, IDLoc, STI);
4980 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4982 return false;
4985 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4986 const MCSubtargetInfo *STI) {
4987 MipsTargetStreamer &TOut = getTargetStreamer();
4988 unsigned ATReg = Mips::NoRegister;
4989 unsigned DstReg = Inst.getOperand(0).getReg();
4990 unsigned SrcReg = Inst.getOperand(1).getReg();
4991 unsigned TmpReg = Inst.getOperand(2).getReg();
4993 ATReg = getATReg(Inst.getLoc());
4994 if (!ATReg)
4995 return true;
4997 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4998 SrcReg, TmpReg, IDLoc, STI);
5000 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5002 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5003 DstReg, DstReg, 0x1F, IDLoc, STI);
5005 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5007 if (useTraps()) {
5008 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5009 } else {
5010 MCContext & Context = TOut.getStreamer().getContext();
5011 MCSymbol * BrTarget = Context.createTempSymbol();
5012 MCOperand LabelOp =
5013 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5015 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5016 if (AssemblerOptions.back()->isReorder())
5017 TOut.emitNop(IDLoc, STI);
5018 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5020 TOut.getStreamer().EmitLabel(BrTarget);
5022 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5024 return false;
5027 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5028 const MCSubtargetInfo *STI) {
5029 MipsTargetStreamer &TOut = getTargetStreamer();
5030 unsigned ATReg = Mips::NoRegister;
5031 unsigned DstReg = Inst.getOperand(0).getReg();
5032 unsigned SrcReg = Inst.getOperand(1).getReg();
5033 unsigned TmpReg = Inst.getOperand(2).getReg();
5035 ATReg = getATReg(IDLoc);
5036 if (!ATReg)
5037 return true;
5039 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5040 SrcReg, TmpReg, IDLoc, STI);
5042 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5043 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5044 if (useTraps()) {
5045 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5046 } else {
5047 MCContext & Context = TOut.getStreamer().getContext();
5048 MCSymbol * BrTarget = Context.createTempSymbol();
5049 MCOperand LabelOp =
5050 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5052 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5053 if (AssemblerOptions.back()->isReorder())
5054 TOut.emitNop(IDLoc, STI);
5055 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5057 TOut.getStreamer().EmitLabel(BrTarget);
5060 return false;
5063 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5064 const MCSubtargetInfo *STI) {
5065 MipsTargetStreamer &TOut = getTargetStreamer();
5066 unsigned DstReg = Inst.getOperand(0).getReg();
5067 unsigned SrcReg = Inst.getOperand(1).getReg();
5068 unsigned TmpReg = Inst.getOperand(2).getReg();
5070 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5071 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5073 return false;
5076 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5077 // lw $<reg+1>>, offset+4($reg2)'
5078 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5079 // sw $<reg+1>>, offset+4($reg2)'
5080 // for O32.
5081 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5082 MCStreamer &Out,
5083 const MCSubtargetInfo *STI,
5084 bool IsLoad) {
5085 if (!isABI_O32())
5086 return true;
5088 warnIfNoMacro(IDLoc);
5090 MipsTargetStreamer &TOut = getTargetStreamer();
5091 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5092 unsigned FirstReg = Inst.getOperand(0).getReg();
5093 unsigned SecondReg = nextReg(FirstReg);
5094 unsigned BaseReg = Inst.getOperand(1).getReg();
5095 if (!SecondReg)
5096 return true;
5098 warnIfRegIndexIsAT(FirstReg, IDLoc);
5100 assert(Inst.getOperand(2).isImm() &&
5101 "Offset for load macro is not immediate!");
5103 MCOperand &FirstOffset = Inst.getOperand(2);
5104 signed NextOffset = FirstOffset.getImm() + 4;
5105 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5107 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5108 return true;
5110 // For loads, clobber the base register with the second load instead of the
5111 // first if the BaseReg == FirstReg.
5112 if (FirstReg != BaseReg || !IsLoad) {
5113 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5114 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5115 } else {
5116 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5117 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5120 return false;
5124 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5125 // swc1 $<reg>, offset+4($reg2)'
5126 // or if little endian to 'swc1 $<reg>, offset($reg2);
5127 // swc1 $<reg+1>, offset+4($reg2)'
5128 // for Mips1.
5129 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5130 MCStreamer &Out,
5131 const MCSubtargetInfo *STI) {
5132 if (!isABI_O32())
5133 return true;
5135 warnIfNoMacro(IDLoc);
5137 MipsTargetStreamer &TOut = getTargetStreamer();
5138 unsigned Opcode = Mips::SWC1;
5139 unsigned FirstReg = Inst.getOperand(0).getReg();
5140 unsigned SecondReg = nextReg(FirstReg);
5141 unsigned BaseReg = Inst.getOperand(1).getReg();
5142 if (!SecondReg)
5143 return true;
5145 warnIfRegIndexIsAT(FirstReg, IDLoc);
5147 assert(Inst.getOperand(2).isImm() &&
5148 "Offset for macro is not immediate!");
5150 MCOperand &FirstOffset = Inst.getOperand(2);
5151 signed NextOffset = FirstOffset.getImm() + 4;
5152 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5154 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5155 return true;
5157 if (!IsLittleEndian)
5158 std::swap(FirstReg, SecondReg);
5160 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5161 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5163 return false;
5166 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5167 const MCSubtargetInfo *STI) {
5168 MipsTargetStreamer &TOut = getTargetStreamer();
5170 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5171 assert(Inst.getOperand(0).isReg() &&
5172 Inst.getOperand(1).isReg() &&
5173 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5175 unsigned DstReg = Inst.getOperand(0).getReg();
5176 unsigned SrcReg = Inst.getOperand(1).getReg();
5177 unsigned OpReg = Inst.getOperand(2).getReg();
5179 warnIfNoMacro(IDLoc);
5181 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5182 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5183 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5184 return false;
5187 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5188 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5189 return false;
5192 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5193 const MCSubtargetInfo *STI) {
5194 MipsTargetStreamer &TOut = getTargetStreamer();
5196 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5197 assert(Inst.getOperand(0).isReg() &&
5198 Inst.getOperand(1).isReg() &&
5199 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5201 unsigned DstReg = Inst.getOperand(0).getReg();
5202 unsigned SrcReg = Inst.getOperand(1).getReg();
5203 int64_t Imm = Inst.getOperand(2).getImm();
5205 warnIfNoMacro(IDLoc);
5207 if (Imm == 0) {
5208 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5209 return false;
5212 if (SrcReg == Mips::ZERO) {
5213 Warning(IDLoc, "comparison is always false");
5214 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5215 DstReg, SrcReg, SrcReg, IDLoc, STI);
5216 return false;
5219 unsigned Opc;
5220 if (Imm > -0x8000 && Imm < 0) {
5221 Imm = -Imm;
5222 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5223 } else {
5224 Opc = Mips::XORi;
5227 if (!isUInt<16>(Imm)) {
5228 unsigned ATReg = getATReg(IDLoc);
5229 if (!ATReg)
5230 return true;
5232 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5233 Out, STI))
5234 return true;
5236 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5237 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5238 return false;
5241 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5242 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5243 return false;
5246 // Map the DSP accumulator and control register to the corresponding gpr
5247 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5248 // do not map the DSP registers contigously to gpr registers.
5249 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5250 switch (Inst.getOpcode()) {
5251 case Mips::MFTLO:
5252 case Mips::MTTLO:
5253 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5254 case Mips::AC0:
5255 return Mips::ZERO;
5256 case Mips::AC1:
5257 return Mips::A0;
5258 case Mips::AC2:
5259 return Mips::T0;
5260 case Mips::AC3:
5261 return Mips::T4;
5262 default:
5263 llvm_unreachable("Unknown register for 'mttr' alias!");
5265 case Mips::MFTHI:
5266 case Mips::MTTHI:
5267 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5268 case Mips::AC0:
5269 return Mips::AT;
5270 case Mips::AC1:
5271 return Mips::A1;
5272 case Mips::AC2:
5273 return Mips::T1;
5274 case Mips::AC3:
5275 return Mips::T5;
5276 default:
5277 llvm_unreachable("Unknown register for 'mttr' alias!");
5279 case Mips::MFTACX:
5280 case Mips::MTTACX:
5281 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5282 case Mips::AC0:
5283 return Mips::V0;
5284 case Mips::AC1:
5285 return Mips::A2;
5286 case Mips::AC2:
5287 return Mips::T2;
5288 case Mips::AC3:
5289 return Mips::T6;
5290 default:
5291 llvm_unreachable("Unknown register for 'mttr' alias!");
5293 case Mips::MFTDSP:
5294 case Mips::MTTDSP:
5295 return Mips::S0;
5296 default:
5297 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5301 // Map the floating point register operand to the corresponding register
5302 // operand.
5303 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5304 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5305 case Mips::F0: return Mips::ZERO;
5306 case Mips::F1: return Mips::AT;
5307 case Mips::F2: return Mips::V0;
5308 case Mips::F3: return Mips::V1;
5309 case Mips::F4: return Mips::A0;
5310 case Mips::F5: return Mips::A1;
5311 case Mips::F6: return Mips::A2;
5312 case Mips::F7: return Mips::A3;
5313 case Mips::F8: return Mips::T0;
5314 case Mips::F9: return Mips::T1;
5315 case Mips::F10: return Mips::T2;
5316 case Mips::F11: return Mips::T3;
5317 case Mips::F12: return Mips::T4;
5318 case Mips::F13: return Mips::T5;
5319 case Mips::F14: return Mips::T6;
5320 case Mips::F15: return Mips::T7;
5321 case Mips::F16: return Mips::S0;
5322 case Mips::F17: return Mips::S1;
5323 case Mips::F18: return Mips::S2;
5324 case Mips::F19: return Mips::S3;
5325 case Mips::F20: return Mips::S4;
5326 case Mips::F21: return Mips::S5;
5327 case Mips::F22: return Mips::S6;
5328 case Mips::F23: return Mips::S7;
5329 case Mips::F24: return Mips::T8;
5330 case Mips::F25: return Mips::T9;
5331 case Mips::F26: return Mips::K0;
5332 case Mips::F27: return Mips::K1;
5333 case Mips::F28: return Mips::GP;
5334 case Mips::F29: return Mips::SP;
5335 case Mips::F30: return Mips::FP;
5336 case Mips::F31: return Mips::RA;
5337 default: llvm_unreachable("Unknown register for mttc1 alias!");
5341 // Map the coprocessor operand the corresponding gpr register operand.
5342 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5343 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5344 case Mips::COP00: return Mips::ZERO;
5345 case Mips::COP01: return Mips::AT;
5346 case Mips::COP02: return Mips::V0;
5347 case Mips::COP03: return Mips::V1;
5348 case Mips::COP04: return Mips::A0;
5349 case Mips::COP05: return Mips::A1;
5350 case Mips::COP06: return Mips::A2;
5351 case Mips::COP07: return Mips::A3;
5352 case Mips::COP08: return Mips::T0;
5353 case Mips::COP09: return Mips::T1;
5354 case Mips::COP010: return Mips::T2;
5355 case Mips::COP011: return Mips::T3;
5356 case Mips::COP012: return Mips::T4;
5357 case Mips::COP013: return Mips::T5;
5358 case Mips::COP014: return Mips::T6;
5359 case Mips::COP015: return Mips::T7;
5360 case Mips::COP016: return Mips::S0;
5361 case Mips::COP017: return Mips::S1;
5362 case Mips::COP018: return Mips::S2;
5363 case Mips::COP019: return Mips::S3;
5364 case Mips::COP020: return Mips::S4;
5365 case Mips::COP021: return Mips::S5;
5366 case Mips::COP022: return Mips::S6;
5367 case Mips::COP023: return Mips::S7;
5368 case Mips::COP024: return Mips::T8;
5369 case Mips::COP025: return Mips::T9;
5370 case Mips::COP026: return Mips::K0;
5371 case Mips::COP027: return Mips::K1;
5372 case Mips::COP028: return Mips::GP;
5373 case Mips::COP029: return Mips::SP;
5374 case Mips::COP030: return Mips::FP;
5375 case Mips::COP031: return Mips::RA;
5376 default: llvm_unreachable("Unknown register for mttc0 alias!");
5380 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5381 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5382 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5383 const MCSubtargetInfo *STI) {
5384 MipsTargetStreamer &TOut = getTargetStreamer();
5385 unsigned rd = 0;
5386 unsigned u = 1;
5387 unsigned sel = 0;
5388 unsigned h = 0;
5389 bool IsMFTR = false;
5390 switch (Inst.getOpcode()) {
5391 case Mips::MFTC0:
5392 IsMFTR = true;
5393 LLVM_FALLTHROUGH;
5394 case Mips::MTTC0:
5395 u = 0;
5396 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5397 sel = Inst.getOperand(2).getImm();
5398 break;
5399 case Mips::MFTGPR:
5400 IsMFTR = true;
5401 LLVM_FALLTHROUGH;
5402 case Mips::MTTGPR:
5403 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5404 break;
5405 case Mips::MFTLO:
5406 case Mips::MFTHI:
5407 case Mips::MFTACX:
5408 case Mips::MFTDSP:
5409 IsMFTR = true;
5410 LLVM_FALLTHROUGH;
5411 case Mips::MTTLO:
5412 case Mips::MTTHI:
5413 case Mips::MTTACX:
5414 case Mips::MTTDSP:
5415 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5416 sel = 1;
5417 break;
5418 case Mips::MFTHC1:
5419 h = 1;
5420 LLVM_FALLTHROUGH;
5421 case Mips::MFTC1:
5422 IsMFTR = true;
5423 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5424 sel = 2;
5425 break;
5426 case Mips::MTTHC1:
5427 h = 1;
5428 LLVM_FALLTHROUGH;
5429 case Mips::MTTC1:
5430 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5431 sel = 2;
5432 break;
5433 case Mips::CFTC1:
5434 IsMFTR = true;
5435 LLVM_FALLTHROUGH;
5436 case Mips::CTTC1:
5437 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5438 sel = 3;
5439 break;
5441 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5442 unsigned Op1 =
5443 IsMFTR ? rd
5444 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5445 : Inst.getOperand(0).getReg());
5447 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5448 STI);
5449 return false;
5452 unsigned
5453 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5454 const OperandVector &Operands) {
5455 switch (Inst.getOpcode()) {
5456 default:
5457 return Match_Success;
5458 case Mips::DATI:
5459 case Mips::DAHI:
5460 if (static_cast<MipsOperand &>(*Operands[1])
5461 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5462 return Match_Success;
5463 return Match_RequiresSameSrcAndDst;
5467 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5468 switch (Inst.getOpcode()) {
5469 // As described by the MIPSR6 spec, daui must not use the zero operand for
5470 // its source operand.
5471 case Mips::DAUI:
5472 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5473 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5474 return Match_RequiresNoZeroRegister;
5475 return Match_Success;
5476 // As described by the Mips32r2 spec, the registers Rd and Rs for
5477 // jalr.hb must be different.
5478 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5479 // and registers Rd and Base for microMIPS lwp instruction
5480 case Mips::JALR_HB:
5481 case Mips::JALR_HB64:
5482 case Mips::JALRC_HB_MMR6:
5483 case Mips::JALRC_MMR6:
5484 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5485 return Match_RequiresDifferentSrcAndDst;
5486 return Match_Success;
5487 case Mips::LWP_MM:
5488 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5489 return Match_RequiresDifferentSrcAndDst;
5490 return Match_Success;
5491 case Mips::SYNC:
5492 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5493 return Match_NonZeroOperandForSync;
5494 return Match_Success;
5495 case Mips::MFC0:
5496 case Mips::MTC0:
5497 case Mips::MTC2:
5498 case Mips::MFC2:
5499 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5500 return Match_NonZeroOperandForMTCX;
5501 return Match_Success;
5502 // As described the MIPSR6 spec, the compact branches that compare registers
5503 // must:
5504 // a) Not use the zero register.
5505 // b) Not use the same register twice.
5506 // c) rs < rt for bnec, beqc.
5507 // NB: For this case, the encoding will swap the operands as their
5508 // ordering doesn't matter. GAS performs this transformation too.
5509 // Hence, that constraint does not have to be enforced.
5511 // The compact branches that branch iff the signed addition of two registers
5512 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5513 // operand swapping. They do not have restriction of using the zero register.
5514 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5515 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5516 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5517 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5518 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5519 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5520 case Mips::BLEZC64:
5521 case Mips::BGEZC64:
5522 case Mips::BGTZC64:
5523 case Mips::BLTZC64:
5524 case Mips::BEQZC64:
5525 case Mips::BNEZC64:
5526 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5527 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5528 return Match_RequiresNoZeroRegister;
5529 return Match_Success;
5530 case Mips::BGEC: case Mips::BGEC_MMR6:
5531 case Mips::BLTC: case Mips::BLTC_MMR6:
5532 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5533 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5534 case Mips::BEQC: case Mips::BEQC_MMR6:
5535 case Mips::BNEC: case Mips::BNEC_MMR6:
5536 case Mips::BGEC64:
5537 case Mips::BLTC64:
5538 case Mips::BGEUC64:
5539 case Mips::BLTUC64:
5540 case Mips::BEQC64:
5541 case Mips::BNEC64:
5542 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5543 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5544 return Match_RequiresNoZeroRegister;
5545 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5546 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5547 return Match_RequiresNoZeroRegister;
5548 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5549 return Match_RequiresDifferentOperands;
5550 return Match_Success;
5551 case Mips::DINS: {
5552 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5553 "Operands must be immediates for dins!");
5554 const signed Pos = Inst.getOperand(2).getImm();
5555 const signed Size = Inst.getOperand(3).getImm();
5556 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5557 return Match_RequiresPosSizeRange0_32;
5558 return Match_Success;
5560 case Mips::DINSM:
5561 case Mips::DINSU: {
5562 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5563 "Operands must be immediates for dinsm/dinsu!");
5564 const signed Pos = Inst.getOperand(2).getImm();
5565 const signed Size = Inst.getOperand(3).getImm();
5566 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5567 return Match_RequiresPosSizeRange33_64;
5568 return Match_Success;
5570 case Mips::DEXT: {
5571 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5572 "Operands must be immediates for DEXTM!");
5573 const signed Pos = Inst.getOperand(2).getImm();
5574 const signed Size = Inst.getOperand(3).getImm();
5575 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5576 return Match_RequiresPosSizeUImm6;
5577 return Match_Success;
5579 case Mips::DEXTM:
5580 case Mips::DEXTU: {
5581 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5582 "Operands must be immediates for dextm/dextu!");
5583 const signed Pos = Inst.getOperand(2).getImm();
5584 const signed Size = Inst.getOperand(3).getImm();
5585 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5586 return Match_RequiresPosSizeRange33_64;
5587 return Match_Success;
5589 case Mips::CRC32B: case Mips::CRC32CB:
5590 case Mips::CRC32H: case Mips::CRC32CH:
5591 case Mips::CRC32W: case Mips::CRC32CW:
5592 case Mips::CRC32D: case Mips::CRC32CD:
5593 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5594 return Match_RequiresSameSrcAndDst;
5595 return Match_Success;
5598 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5599 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5600 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5601 return Match_NoFCCRegisterForCurrentISA;
5603 return Match_Success;
5607 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5608 uint64_t ErrorInfo) {
5609 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5610 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5611 if (ErrorLoc == SMLoc())
5612 return Loc;
5613 return ErrorLoc;
5615 return Loc;
5618 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5619 OperandVector &Operands,
5620 MCStreamer &Out,
5621 uint64_t &ErrorInfo,
5622 bool MatchingInlineAsm) {
5623 MCInst Inst;
5624 unsigned MatchResult =
5625 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5627 switch (MatchResult) {
5628 case Match_Success:
5629 if (processInstruction(Inst, IDLoc, Out, STI))
5630 return true;
5631 return false;
5632 case Match_MissingFeature:
5633 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5634 return true;
5635 case Match_InvalidOperand: {
5636 SMLoc ErrorLoc = IDLoc;
5637 if (ErrorInfo != ~0ULL) {
5638 if (ErrorInfo >= Operands.size())
5639 return Error(IDLoc, "too few operands for instruction");
5641 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5642 if (ErrorLoc == SMLoc())
5643 ErrorLoc = IDLoc;
5646 return Error(ErrorLoc, "invalid operand for instruction");
5648 case Match_NonZeroOperandForSync:
5649 return Error(IDLoc,
5650 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5651 case Match_NonZeroOperandForMTCX:
5652 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5653 case Match_MnemonicFail:
5654 return Error(IDLoc, "invalid instruction");
5655 case Match_RequiresDifferentSrcAndDst:
5656 return Error(IDLoc, "source and destination must be different");
5657 case Match_RequiresDifferentOperands:
5658 return Error(IDLoc, "registers must be different");
5659 case Match_RequiresNoZeroRegister:
5660 return Error(IDLoc, "invalid operand ($zero) for instruction");
5661 case Match_RequiresSameSrcAndDst:
5662 return Error(IDLoc, "source and destination must match");
5663 case Match_NoFCCRegisterForCurrentISA:
5664 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5665 "non-zero fcc register doesn't exist in current ISA level");
5666 case Match_Immz:
5667 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5668 case Match_UImm1_0:
5669 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5670 "expected 1-bit unsigned immediate");
5671 case Match_UImm2_0:
5672 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5673 "expected 2-bit unsigned immediate");
5674 case Match_UImm2_1:
5675 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5676 "expected immediate in range 1 .. 4");
5677 case Match_UImm3_0:
5678 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5679 "expected 3-bit unsigned immediate");
5680 case Match_UImm4_0:
5681 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5682 "expected 4-bit unsigned immediate");
5683 case Match_SImm4_0:
5684 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5685 "expected 4-bit signed immediate");
5686 case Match_UImm5_0:
5687 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5688 "expected 5-bit unsigned immediate");
5689 case Match_SImm5_0:
5690 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5691 "expected 5-bit signed immediate");
5692 case Match_UImm5_1:
5693 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5694 "expected immediate in range 1 .. 32");
5695 case Match_UImm5_32:
5696 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5697 "expected immediate in range 32 .. 63");
5698 case Match_UImm5_33:
5699 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5700 "expected immediate in range 33 .. 64");
5701 case Match_UImm5_0_Report_UImm6:
5702 // This is used on UImm5 operands that have a corresponding UImm5_32
5703 // operand to avoid confusing the user.
5704 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5705 "expected 6-bit unsigned immediate");
5706 case Match_UImm5_Lsl2:
5707 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5708 "expected both 7-bit unsigned immediate and multiple of 4");
5709 case Match_UImmRange2_64:
5710 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5711 "expected immediate in range 2 .. 64");
5712 case Match_UImm6_0:
5713 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5714 "expected 6-bit unsigned immediate");
5715 case Match_UImm6_Lsl2:
5716 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5717 "expected both 8-bit unsigned immediate and multiple of 4");
5718 case Match_SImm6_0:
5719 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5720 "expected 6-bit signed immediate");
5721 case Match_UImm7_0:
5722 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5723 "expected 7-bit unsigned immediate");
5724 case Match_UImm7_N1:
5725 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5726 "expected immediate in range -1 .. 126");
5727 case Match_SImm7_Lsl2:
5728 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5729 "expected both 9-bit signed immediate and multiple of 4");
5730 case Match_UImm8_0:
5731 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5732 "expected 8-bit unsigned immediate");
5733 case Match_UImm10_0:
5734 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5735 "expected 10-bit unsigned immediate");
5736 case Match_SImm10_0:
5737 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5738 "expected 10-bit signed immediate");
5739 case Match_SImm11_0:
5740 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5741 "expected 11-bit signed immediate");
5742 case Match_UImm16:
5743 case Match_UImm16_Relaxed:
5744 case Match_UImm16_AltRelaxed:
5745 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5746 "expected 16-bit unsigned immediate");
5747 case Match_SImm16:
5748 case Match_SImm16_Relaxed:
5749 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5750 "expected 16-bit signed immediate");
5751 case Match_SImm19_Lsl2:
5752 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5753 "expected both 19-bit signed immediate and multiple of 4");
5754 case Match_UImm20_0:
5755 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5756 "expected 20-bit unsigned immediate");
5757 case Match_UImm26_0:
5758 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5759 "expected 26-bit unsigned immediate");
5760 case Match_SImm32:
5761 case Match_SImm32_Relaxed:
5762 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5763 "expected 32-bit signed immediate");
5764 case Match_UImm32_Coerced:
5765 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5766 "expected 32-bit immediate");
5767 case Match_MemSImm9:
5768 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5769 "expected memory with 9-bit signed offset");
5770 case Match_MemSImm10:
5771 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5772 "expected memory with 10-bit signed offset");
5773 case Match_MemSImm10Lsl1:
5774 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5775 "expected memory with 11-bit signed offset and multiple of 2");
5776 case Match_MemSImm10Lsl2:
5777 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5778 "expected memory with 12-bit signed offset and multiple of 4");
5779 case Match_MemSImm10Lsl3:
5780 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5781 "expected memory with 13-bit signed offset and multiple of 8");
5782 case Match_MemSImm11:
5783 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5784 "expected memory with 11-bit signed offset");
5785 case Match_MemSImm12:
5786 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5787 "expected memory with 12-bit signed offset");
5788 case Match_MemSImm16:
5789 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5790 "expected memory with 16-bit signed offset");
5791 case Match_MemSImmPtr:
5792 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5793 "expected memory with 32-bit signed offset");
5794 case Match_RequiresPosSizeRange0_32: {
5795 SMLoc ErrorStart = Operands[3]->getStartLoc();
5796 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5797 return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
5798 SMRange(ErrorStart, ErrorEnd));
5800 case Match_RequiresPosSizeUImm6: {
5801 SMLoc ErrorStart = Operands[3]->getStartLoc();
5802 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5803 return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
5804 SMRange(ErrorStart, ErrorEnd));
5806 case Match_RequiresPosSizeRange33_64: {
5807 SMLoc ErrorStart = Operands[3]->getStartLoc();
5808 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5809 return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
5810 SMRange(ErrorStart, ErrorEnd));
5814 llvm_unreachable("Implement any new match types added!");
5817 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
5818 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
5819 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
5820 ") without \".set noat\"");
5823 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
5824 if (!AssemblerOptions.back()->isMacro())
5825 Warning(Loc, "macro instruction expanded into multiple instructions");
5828 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
5829 const OperandVector &Operands) {
5830 assert(
5831 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
5832 "Unexpected instruction!");
5833 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5834 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5835 Inst.addOperand(MCOperand::createReg(NextReg));
5836 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5839 void
5840 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
5841 SMRange Range, bool ShowColors) {
5842 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
5843 Range, SMFixIt(Range, FixMsg),
5844 ShowColors);
5847 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
5848 int CC;
5850 CC = StringSwitch<unsigned>(Name)
5851 .Case("zero", 0)
5852 .Cases("at", "AT", 1)
5853 .Case("a0", 4)
5854 .Case("a1", 5)
5855 .Case("a2", 6)
5856 .Case("a3", 7)
5857 .Case("v0", 2)
5858 .Case("v1", 3)
5859 .Case("s0", 16)
5860 .Case("s1", 17)
5861 .Case("s2", 18)
5862 .Case("s3", 19)
5863 .Case("s4", 20)
5864 .Case("s5", 21)
5865 .Case("s6", 22)
5866 .Case("s7", 23)
5867 .Case("k0", 26)
5868 .Case("k1", 27)
5869 .Case("gp", 28)
5870 .Case("sp", 29)
5871 .Case("fp", 30)
5872 .Case("s8", 30)
5873 .Case("ra", 31)
5874 .Case("t0", 8)
5875 .Case("t1", 9)
5876 .Case("t2", 10)
5877 .Case("t3", 11)
5878 .Case("t4", 12)
5879 .Case("t5", 13)
5880 .Case("t6", 14)
5881 .Case("t7", 15)
5882 .Case("t8", 24)
5883 .Case("t9", 25)
5884 .Default(-1);
5886 if (!(isABI_N32() || isABI_N64()))
5887 return CC;
5889 if (12 <= CC && CC <= 15) {
5890 // Name is one of t4-t7
5891 AsmToken RegTok = getLexer().peekTok();
5892 SMRange RegRange = RegTok.getLocRange();
5894 StringRef FixedName = StringSwitch<StringRef>(Name)
5895 .Case("t4", "t0")
5896 .Case("t5", "t1")
5897 .Case("t6", "t2")
5898 .Case("t7", "t3")
5899 .Default("");
5900 assert(FixedName != "" && "Register name is not one of t4-t7.");
5902 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
5903 "Did you mean $" + FixedName + "?", RegRange);
5906 // Although SGI documentation just cuts out t0-t3 for n32/n64,
5907 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
5908 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
5909 if (8 <= CC && CC <= 11)
5910 CC += 4;
5912 if (CC == -1)
5913 CC = StringSwitch<unsigned>(Name)
5914 .Case("a4", 8)
5915 .Case("a5", 9)
5916 .Case("a6", 10)
5917 .Case("a7", 11)
5918 .Case("kt0", 26)
5919 .Case("kt1", 27)
5920 .Default(-1);
5922 return CC;
5925 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
5926 int CC;
5928 CC = StringSwitch<unsigned>(Name)
5929 .Case("hwr_cpunum", 0)
5930 .Case("hwr_synci_step", 1)
5931 .Case("hwr_cc", 2)
5932 .Case("hwr_ccres", 3)
5933 .Case("hwr_ulr", 29)
5934 .Default(-1);
5936 return CC;
5939 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
5940 if (Name[0] == 'f') {
5941 StringRef NumString = Name.substr(1);
5942 unsigned IntVal;
5943 if (NumString.getAsInteger(10, IntVal))
5944 return -1; // This is not an integer.
5945 if (IntVal > 31) // Maximum index for fpu register.
5946 return -1;
5947 return IntVal;
5949 return -1;
5952 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
5953 if (Name.startswith("fcc")) {
5954 StringRef NumString = Name.substr(3);
5955 unsigned IntVal;
5956 if (NumString.getAsInteger(10, IntVal))
5957 return -1; // This is not an integer.
5958 if (IntVal > 7) // There are only 8 fcc registers.
5959 return -1;
5960 return IntVal;
5962 return -1;
5965 int MipsAsmParser::matchACRegisterName(StringRef Name) {
5966 if (Name.startswith("ac")) {
5967 StringRef NumString = Name.substr(2);
5968 unsigned IntVal;
5969 if (NumString.getAsInteger(10, IntVal))
5970 return -1; // This is not an integer.
5971 if (IntVal > 3) // There are only 3 acc registers.
5972 return -1;
5973 return IntVal;
5975 return -1;
5978 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
5979 unsigned IntVal;
5981 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
5982 return -1;
5984 if (IntVal > 31)
5985 return -1;
5987 return IntVal;
5990 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
5991 int CC;
5993 CC = StringSwitch<unsigned>(Name)
5994 .Case("msair", 0)
5995 .Case("msacsr", 1)
5996 .Case("msaaccess", 2)
5997 .Case("msasave", 3)
5998 .Case("msamodify", 4)
5999 .Case("msarequest", 5)
6000 .Case("msamap", 6)
6001 .Case("msaunmap", 7)
6002 .Default(-1);
6004 return CC;
6007 bool MipsAsmParser::canUseATReg() {
6008 return AssemblerOptions.back()->getATRegIndex() != 0;
6011 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
6012 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6013 if (ATIndex == 0) {
6014 reportParseError(Loc,
6015 "pseudo-instruction requires $at, which is not available");
6016 return 0;
6018 unsigned AT = getReg(
6019 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6020 return AT;
6023 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
6024 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6027 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6028 MCAsmParser &Parser = getParser();
6029 LLVM_DEBUG(dbgs() << "parseOperand\n");
6031 // Check if the current operand has a custom associated parser, if so, try to
6032 // custom parse the operand, or fallback to the general approach.
6033 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6034 if (ResTy == MatchOperand_Success)
6035 return false;
6036 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6037 // there was a match, but an error occurred, in which case, just return that
6038 // the operand parsing failed.
6039 if (ResTy == MatchOperand_ParseFail)
6040 return true;
6042 LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6044 switch (getLexer().getKind()) {
6045 case AsmToken::Dollar: {
6046 // Parse the register.
6047 SMLoc S = Parser.getTok().getLoc();
6049 // Almost all registers have been parsed by custom parsers. There is only
6050 // one exception to this. $zero (and it's alias $0) will reach this point
6051 // for div, divu, and similar instructions because it is not an operand
6052 // to the instruction definition but an explicit register. Special case
6053 // this situation for now.
6054 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
6055 return false;
6057 // Maybe it is a symbol reference.
6058 StringRef Identifier;
6059 if (Parser.parseIdentifier(Identifier))
6060 return true;
6062 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6063 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
6064 // Otherwise create a symbol reference.
6065 const MCExpr *Res =
6066 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
6068 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
6069 return false;
6071 default: {
6072 LLVM_DEBUG(dbgs() << ".. generic integer expression\n");
6074 const MCExpr *Expr;
6075 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6076 if (getParser().parseExpression(Expr))
6077 return true;
6079 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6081 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6082 return false;
6084 } // switch(getLexer().getKind())
6085 return true;
6088 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
6089 switch (Expr->getKind()) {
6090 case MCExpr::Constant:
6091 return true;
6092 case MCExpr::SymbolRef:
6093 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
6094 case MCExpr::Binary: {
6095 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
6096 if (!isEvaluated(BE->getLHS()))
6097 return false;
6098 return isEvaluated(BE->getRHS());
6100 case MCExpr::Unary:
6101 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
6102 case MCExpr::Target:
6103 return true;
6105 return false;
6108 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
6109 SMLoc &EndLoc) {
6110 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6111 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6112 if (ResTy == MatchOperand_Success) {
6113 assert(Operands.size() == 1);
6114 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6115 StartLoc = Operand.getStartLoc();
6116 EndLoc = Operand.getEndLoc();
6118 // AFAIK, we only support numeric registers and named GPR's in CFI
6119 // directives.
6120 // Don't worry about eating tokens before failing. Using an unrecognised
6121 // register is a parse error.
6122 if (Operand.isGPRAsmReg()) {
6123 // Resolve to GPR32 or GPR64 appropriately.
6124 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6127 return (RegNo == (unsigned)-1);
6130 assert(Operands.size() == 0);
6131 return (RegNo == (unsigned)-1);
6134 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
6135 SMLoc S;
6137 if (isParenExpr)
6138 return getParser().parseParenExprOfDepth(0, Res, S);
6139 return getParser().parseExpression(Res);
6142 OperandMatchResultTy
6143 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6144 MCAsmParser &Parser = getParser();
6145 LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6146 const MCExpr *IdVal = nullptr;
6147 SMLoc S;
6148 bool isParenExpr = false;
6149 OperandMatchResultTy Res = MatchOperand_NoMatch;
6150 // First operand is the offset.
6151 S = Parser.getTok().getLoc();
6153 if (getLexer().getKind() == AsmToken::LParen) {
6154 Parser.Lex();
6155 isParenExpr = true;
6158 if (getLexer().getKind() != AsmToken::Dollar) {
6159 if (parseMemOffset(IdVal, isParenExpr))
6160 return MatchOperand_ParseFail;
6162 const AsmToken &Tok = Parser.getTok(); // Get the next token.
6163 if (Tok.isNot(AsmToken::LParen)) {
6164 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6165 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6166 SMLoc E =
6167 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6168 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6169 return MatchOperand_Success;
6171 if (Tok.is(AsmToken::EndOfStatement)) {
6172 SMLoc E =
6173 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6175 // Zero register assumed, add a memory operand with ZERO as its base.
6176 // "Base" will be managed by k_Memory.
6177 auto Base = MipsOperand::createGPRReg(
6178 0, "0", getContext().getRegisterInfo(), S, E, *this);
6179 Operands.push_back(
6180 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6181 return MatchOperand_Success;
6183 MCBinaryExpr::Opcode Opcode;
6184 // GAS and LLVM treat comparison operators different. GAS will generate -1
6185 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6186 // highly unlikely to be found in a memory offset expression, we don't
6187 // handle them.
6188 switch (Tok.getKind()) {
6189 case AsmToken::Plus:
6190 Opcode = MCBinaryExpr::Add;
6191 Parser.Lex();
6192 break;
6193 case AsmToken::Minus:
6194 Opcode = MCBinaryExpr::Sub;
6195 Parser.Lex();
6196 break;
6197 case AsmToken::Star:
6198 Opcode = MCBinaryExpr::Mul;
6199 Parser.Lex();
6200 break;
6201 case AsmToken::Pipe:
6202 Opcode = MCBinaryExpr::Or;
6203 Parser.Lex();
6204 break;
6205 case AsmToken::Amp:
6206 Opcode = MCBinaryExpr::And;
6207 Parser.Lex();
6208 break;
6209 case AsmToken::LessLess:
6210 Opcode = MCBinaryExpr::Shl;
6211 Parser.Lex();
6212 break;
6213 case AsmToken::GreaterGreater:
6214 Opcode = MCBinaryExpr::LShr;
6215 Parser.Lex();
6216 break;
6217 case AsmToken::Caret:
6218 Opcode = MCBinaryExpr::Xor;
6219 Parser.Lex();
6220 break;
6221 case AsmToken::Slash:
6222 Opcode = MCBinaryExpr::Div;
6223 Parser.Lex();
6224 break;
6225 case AsmToken::Percent:
6226 Opcode = MCBinaryExpr::Mod;
6227 Parser.Lex();
6228 break;
6229 default:
6230 Error(Parser.getTok().getLoc(), "'(' or expression expected");
6231 return MatchOperand_ParseFail;
6233 const MCExpr * NextExpr;
6234 if (getParser().parseExpression(NextExpr))
6235 return MatchOperand_ParseFail;
6236 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6239 Parser.Lex(); // Eat the '(' token.
6242 Res = parseAnyRegister(Operands);
6243 if (Res != MatchOperand_Success)
6244 return Res;
6246 if (Parser.getTok().isNot(AsmToken::RParen)) {
6247 Error(Parser.getTok().getLoc(), "')' expected");
6248 return MatchOperand_ParseFail;
6251 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6253 Parser.Lex(); // Eat the ')' token.
6255 if (!IdVal)
6256 IdVal = MCConstantExpr::create(0, getContext());
6258 // Replace the register operand with the memory operand.
6259 std::unique_ptr<MipsOperand> op(
6260 static_cast<MipsOperand *>(Operands.back().release()));
6261 // Remove the register from the operands.
6262 // "op" will be managed by k_Memory.
6263 Operands.pop_back();
6264 // Add the memory operand.
6265 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6266 int64_t Imm;
6267 if (IdVal->evaluateAsAbsolute(Imm))
6268 IdVal = MCConstantExpr::create(Imm, getContext());
6269 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6270 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6271 getContext());
6274 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6275 return MatchOperand_Success;
6278 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6279 MCAsmParser &Parser = getParser();
6280 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6281 if (!Sym)
6282 return false;
6284 SMLoc S = Parser.getTok().getLoc();
6285 if (Sym->isVariable()) {
6286 const MCExpr *Expr = Sym->getVariableValue();
6287 if (Expr->getKind() == MCExpr::SymbolRef) {
6288 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6289 StringRef DefSymbol = Ref->getSymbol().getName();
6290 if (DefSymbol.startswith("$")) {
6291 OperandMatchResultTy ResTy =
6292 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6293 if (ResTy == MatchOperand_Success) {
6294 Parser.Lex();
6295 return true;
6297 if (ResTy == MatchOperand_ParseFail)
6298 llvm_unreachable("Should never ParseFail");
6301 } else if (Sym->isUnset()) {
6302 // If symbol is unset, it might be created in the `parseSetAssignment`
6303 // routine as an alias for a numeric register name.
6304 // Lookup in the aliases list.
6305 auto Entry = RegisterSets.find(Sym->getName());
6306 if (Entry != RegisterSets.end()) {
6307 OperandMatchResultTy ResTy =
6308 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6309 if (ResTy == MatchOperand_Success) {
6310 Parser.Lex();
6311 return true;
6316 return false;
6319 OperandMatchResultTy
6320 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
6321 StringRef Identifier,
6322 SMLoc S) {
6323 int Index = matchCPURegisterName(Identifier);
6324 if (Index != -1) {
6325 Operands.push_back(MipsOperand::createGPRReg(
6326 Index, Identifier, getContext().getRegisterInfo(), S,
6327 getLexer().getLoc(), *this));
6328 return MatchOperand_Success;
6331 Index = matchHWRegsRegisterName(Identifier);
6332 if (Index != -1) {
6333 Operands.push_back(MipsOperand::createHWRegsReg(
6334 Index, Identifier, getContext().getRegisterInfo(), S,
6335 getLexer().getLoc(), *this));
6336 return MatchOperand_Success;
6339 Index = matchFPURegisterName(Identifier);
6340 if (Index != -1) {
6341 Operands.push_back(MipsOperand::createFGRReg(
6342 Index, Identifier, getContext().getRegisterInfo(), S,
6343 getLexer().getLoc(), *this));
6344 return MatchOperand_Success;
6347 Index = matchFCCRegisterName(Identifier);
6348 if (Index != -1) {
6349 Operands.push_back(MipsOperand::createFCCReg(
6350 Index, Identifier, getContext().getRegisterInfo(), S,
6351 getLexer().getLoc(), *this));
6352 return MatchOperand_Success;
6355 Index = matchACRegisterName(Identifier);
6356 if (Index != -1) {
6357 Operands.push_back(MipsOperand::createACCReg(
6358 Index, Identifier, getContext().getRegisterInfo(), S,
6359 getLexer().getLoc(), *this));
6360 return MatchOperand_Success;
6363 Index = matchMSA128RegisterName(Identifier);
6364 if (Index != -1) {
6365 Operands.push_back(MipsOperand::createMSA128Reg(
6366 Index, Identifier, getContext().getRegisterInfo(), S,
6367 getLexer().getLoc(), *this));
6368 return MatchOperand_Success;
6371 Index = matchMSA128CtrlRegisterName(Identifier);
6372 if (Index != -1) {
6373 Operands.push_back(MipsOperand::createMSACtrlReg(
6374 Index, Identifier, getContext().getRegisterInfo(), S,
6375 getLexer().getLoc(), *this));
6376 return MatchOperand_Success;
6379 return MatchOperand_NoMatch;
6382 OperandMatchResultTy
6383 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6384 const AsmToken &Token, SMLoc S) {
6385 if (Token.is(AsmToken::Identifier)) {
6386 LLVM_DEBUG(dbgs() << ".. identifier\n");
6387 StringRef Identifier = Token.getIdentifier();
6388 OperandMatchResultTy ResTy =
6389 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6390 return ResTy;
6391 } else if (Token.is(AsmToken::Integer)) {
6392 LLVM_DEBUG(dbgs() << ".. integer\n");
6393 int64_t RegNum = Token.getIntVal();
6394 if (RegNum < 0 || RegNum > 31) {
6395 // Show the error, but treat invalid register
6396 // number as a normal one to continue parsing
6397 // and catch other possible errors.
6398 Error(getLexer().getLoc(), "invalid register number");
6400 Operands.push_back(MipsOperand::createNumericReg(
6401 RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6402 Token.getLoc(), *this));
6403 return MatchOperand_Success;
6406 LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6408 return MatchOperand_NoMatch;
6411 OperandMatchResultTy
6412 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6413 auto Token = getLexer().peekTok(false);
6414 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6417 OperandMatchResultTy
6418 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6419 MCAsmParser &Parser = getParser();
6420 LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6422 auto Token = Parser.getTok();
6424 SMLoc S = Token.getLoc();
6426 if (Token.isNot(AsmToken::Dollar)) {
6427 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6428 if (Token.is(AsmToken::Identifier)) {
6429 if (searchSymbolAlias(Operands))
6430 return MatchOperand_Success;
6432 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6433 return MatchOperand_NoMatch;
6435 LLVM_DEBUG(dbgs() << ".. $\n");
6437 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
6438 if (ResTy == MatchOperand_Success) {
6439 Parser.Lex(); // $
6440 Parser.Lex(); // identifier
6442 return ResTy;
6445 OperandMatchResultTy
6446 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6447 MCAsmParser &Parser = getParser();
6448 LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6450 SMLoc S = getLexer().getLoc();
6452 // Registers are a valid target and have priority over symbols.
6453 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
6454 if (ResTy != MatchOperand_NoMatch)
6455 return ResTy;
6457 // Integers and expressions are acceptable
6458 const MCExpr *Expr = nullptr;
6459 if (Parser.parseExpression(Expr)) {
6460 // We have no way of knowing if a symbol was consumed so we must ParseFail
6461 return MatchOperand_ParseFail;
6463 Operands.push_back(
6464 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6465 return MatchOperand_Success;
6468 OperandMatchResultTy
6469 MipsAsmParser::parseInvNum(OperandVector &Operands) {
6470 MCAsmParser &Parser = getParser();
6471 const MCExpr *IdVal;
6472 // If the first token is '$' we may have register operand. We have to reject
6473 // cases where it is not a register. Complicating the matter is that
6474 // register names are not reserved across all ABIs.
6475 // Peek past the dollar to see if it's a register name for this ABI.
6476 SMLoc S = Parser.getTok().getLoc();
6477 if (Parser.getTok().is(AsmToken::Dollar)) {
6478 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6479 ? MatchOperand_ParseFail
6480 : MatchOperand_NoMatch;
6482 if (getParser().parseExpression(IdVal))
6483 return MatchOperand_ParseFail;
6484 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6485 if (!MCE)
6486 return MatchOperand_NoMatch;
6487 int64_t Val = MCE->getValue();
6488 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6489 Operands.push_back(MipsOperand::CreateImm(
6490 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6491 return MatchOperand_Success;
6494 OperandMatchResultTy
6495 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6496 MCAsmParser &Parser = getParser();
6497 SmallVector<unsigned, 10> Regs;
6498 unsigned RegNo;
6499 unsigned PrevReg = Mips::NoRegister;
6500 bool RegRange = false;
6501 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6503 if (Parser.getTok().isNot(AsmToken::Dollar))
6504 return MatchOperand_ParseFail;
6506 SMLoc S = Parser.getTok().getLoc();
6507 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
6508 SMLoc E = getLexer().getLoc();
6509 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6510 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6511 if (RegRange) {
6512 // Remove last register operand because registers from register range
6513 // should be inserted first.
6514 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6515 (!isGP64bit() && RegNo == Mips::RA)) {
6516 Regs.push_back(RegNo);
6517 } else {
6518 unsigned TmpReg = PrevReg + 1;
6519 while (TmpReg <= RegNo) {
6520 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6521 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6522 isGP64bit())) {
6523 Error(E, "invalid register operand");
6524 return MatchOperand_ParseFail;
6527 PrevReg = TmpReg;
6528 Regs.push_back(TmpReg++);
6532 RegRange = false;
6533 } else {
6534 if ((PrevReg == Mips::NoRegister) &&
6535 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6536 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
6537 Error(E, "$16 or $31 expected");
6538 return MatchOperand_ParseFail;
6539 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6540 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6541 !isGP64bit()) ||
6542 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6543 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6544 isGP64bit()))) {
6545 Error(E, "invalid register operand");
6546 return MatchOperand_ParseFail;
6547 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6548 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6549 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6550 isGP64bit()))) {
6551 Error(E, "consecutive register numbers expected");
6552 return MatchOperand_ParseFail;
6555 Regs.push_back(RegNo);
6558 if (Parser.getTok().is(AsmToken::Minus))
6559 RegRange = true;
6561 if (!Parser.getTok().isNot(AsmToken::Minus) &&
6562 !Parser.getTok().isNot(AsmToken::Comma)) {
6563 Error(E, "',' or '-' expected");
6564 return MatchOperand_ParseFail;
6567 Lex(); // Consume comma or minus
6568 if (Parser.getTok().isNot(AsmToken::Dollar))
6569 break;
6571 PrevReg = RegNo;
6574 SMLoc E = Parser.getTok().getLoc();
6575 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6576 parseMemOperand(Operands);
6577 return MatchOperand_Success;
6580 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6581 /// either this.
6582 /// ::= '(', register, ')'
6583 /// handle it before we iterate so we don't get tripped up by the lack of
6584 /// a comma.
6585 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6586 MCAsmParser &Parser = getParser();
6587 if (getLexer().is(AsmToken::LParen)) {
6588 Operands.push_back(
6589 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6590 Parser.Lex();
6591 if (parseOperand(Operands, Name)) {
6592 SMLoc Loc = getLexer().getLoc();
6593 return Error(Loc, "unexpected token in argument list");
6595 if (Parser.getTok().isNot(AsmToken::RParen)) {
6596 SMLoc Loc = getLexer().getLoc();
6597 return Error(Loc, "unexpected token, expected ')'");
6599 Operands.push_back(
6600 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6601 Parser.Lex();
6603 return false;
6606 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6607 /// either one of these.
6608 /// ::= '[', register, ']'
6609 /// ::= '[', integer, ']'
6610 /// handle it before we iterate so we don't get tripped up by the lack of
6611 /// a comma.
6612 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6613 OperandVector &Operands) {
6614 MCAsmParser &Parser = getParser();
6615 if (getLexer().is(AsmToken::LBrac)) {
6616 Operands.push_back(
6617 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6618 Parser.Lex();
6619 if (parseOperand(Operands, Name)) {
6620 SMLoc Loc = getLexer().getLoc();
6621 return Error(Loc, "unexpected token in argument list");
6623 if (Parser.getTok().isNot(AsmToken::RBrac)) {
6624 SMLoc Loc = getLexer().getLoc();
6625 return Error(Loc, "unexpected token, expected ']'");
6627 Operands.push_back(
6628 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6629 Parser.Lex();
6631 return false;
6634 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6635 unsigned VariantID = 0);
6637 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
6638 SMLoc NameLoc, OperandVector &Operands) {
6639 MCAsmParser &Parser = getParser();
6640 LLVM_DEBUG(dbgs() << "ParseInstruction\n");
6642 // We have reached first instruction, module directive are now forbidden.
6643 getTargetStreamer().forbidModuleDirective();
6645 // Check if we have valid mnemonic
6646 if (!mnemonicIsValid(Name, 0)) {
6647 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6648 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
6649 return Error(NameLoc, "unknown instruction" + Suggestion);
6651 // First operand in MCInst is instruction mnemonic.
6652 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
6654 // Read the remaining operands.
6655 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6656 // Read the first operand.
6657 if (parseOperand(Operands, Name)) {
6658 SMLoc Loc = getLexer().getLoc();
6659 return Error(Loc, "unexpected token in argument list");
6661 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6662 return true;
6663 // AFAIK, parenthesis suffixes are never on the first operand
6665 while (getLexer().is(AsmToken::Comma)) {
6666 Parser.Lex(); // Eat the comma.
6667 // Parse and remember the operand.
6668 if (parseOperand(Operands, Name)) {
6669 SMLoc Loc = getLexer().getLoc();
6670 return Error(Loc, "unexpected token in argument list");
6672 // Parse bracket and parenthesis suffixes before we iterate
6673 if (getLexer().is(AsmToken::LBrac)) {
6674 if (parseBracketSuffix(Name, Operands))
6675 return true;
6676 } else if (getLexer().is(AsmToken::LParen) &&
6677 parseParenSuffix(Name, Operands))
6678 return true;
6681 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6682 SMLoc Loc = getLexer().getLoc();
6683 return Error(Loc, "unexpected token in argument list");
6685 Parser.Lex(); // Consume the EndOfStatement.
6686 return false;
6689 // FIXME: Given that these have the same name, these should both be
6690 // consistent on affecting the Parser.
6691 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
6692 SMLoc Loc = getLexer().getLoc();
6693 return Error(Loc, ErrorMsg);
6696 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
6697 return Error(Loc, ErrorMsg);
6700 bool MipsAsmParser::parseSetNoAtDirective() {
6701 MCAsmParser &Parser = getParser();
6702 // Line should look like: ".set noat".
6704 // Set the $at register to $0.
6705 AssemblerOptions.back()->setATRegIndex(0);
6707 Parser.Lex(); // Eat "noat".
6709 // If this is not the end of the statement, report an error.
6710 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6711 reportParseError("unexpected token, expected end of statement");
6712 return false;
6715 getTargetStreamer().emitDirectiveSetNoAt();
6716 Parser.Lex(); // Consume the EndOfStatement.
6717 return false;
6720 bool MipsAsmParser::parseSetAtDirective() {
6721 // Line can be: ".set at", which sets $at to $1
6722 // or ".set at=$reg", which sets $at to $reg.
6723 MCAsmParser &Parser = getParser();
6724 Parser.Lex(); // Eat "at".
6726 if (getLexer().is(AsmToken::EndOfStatement)) {
6727 // No register was specified, so we set $at to $1.
6728 AssemblerOptions.back()->setATRegIndex(1);
6730 getTargetStreamer().emitDirectiveSetAt();
6731 Parser.Lex(); // Consume the EndOfStatement.
6732 return false;
6735 if (getLexer().isNot(AsmToken::Equal)) {
6736 reportParseError("unexpected token, expected equals sign");
6737 return false;
6739 Parser.Lex(); // Eat "=".
6741 if (getLexer().isNot(AsmToken::Dollar)) {
6742 if (getLexer().is(AsmToken::EndOfStatement)) {
6743 reportParseError("no register specified");
6744 return false;
6745 } else {
6746 reportParseError("unexpected token, expected dollar sign '$'");
6747 return false;
6750 Parser.Lex(); // Eat "$".
6752 // Find out what "reg" is.
6753 unsigned AtRegNo;
6754 const AsmToken &Reg = Parser.getTok();
6755 if (Reg.is(AsmToken::Identifier)) {
6756 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
6757 } else if (Reg.is(AsmToken::Integer)) {
6758 AtRegNo = Reg.getIntVal();
6759 } else {
6760 reportParseError("unexpected token, expected identifier or integer");
6761 return false;
6764 // Check if $reg is a valid register. If it is, set $at to $reg.
6765 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
6766 reportParseError("invalid register");
6767 return false;
6769 Parser.Lex(); // Eat "reg".
6771 // If this is not the end of the statement, report an error.
6772 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6773 reportParseError("unexpected token, expected end of statement");
6774 return false;
6777 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6779 Parser.Lex(); // Consume the EndOfStatement.
6780 return false;
6783 bool MipsAsmParser::parseSetReorderDirective() {
6784 MCAsmParser &Parser = getParser();
6785 Parser.Lex();
6786 // If this is not the end of the statement, report an error.
6787 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6788 reportParseError("unexpected token, expected end of statement");
6789 return false;
6791 AssemblerOptions.back()->setReorder();
6792 getTargetStreamer().emitDirectiveSetReorder();
6793 Parser.Lex(); // Consume the EndOfStatement.
6794 return false;
6797 bool MipsAsmParser::parseSetNoReorderDirective() {
6798 MCAsmParser &Parser = getParser();
6799 Parser.Lex();
6800 // If this is not the end of the statement, report an error.
6801 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6802 reportParseError("unexpected token, expected end of statement");
6803 return false;
6805 AssemblerOptions.back()->setNoReorder();
6806 getTargetStreamer().emitDirectiveSetNoReorder();
6807 Parser.Lex(); // Consume the EndOfStatement.
6808 return false;
6811 bool MipsAsmParser::parseSetMacroDirective() {
6812 MCAsmParser &Parser = getParser();
6813 Parser.Lex();
6814 // If this is not the end of the statement, report an error.
6815 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6816 reportParseError("unexpected token, expected end of statement");
6817 return false;
6819 AssemblerOptions.back()->setMacro();
6820 getTargetStreamer().emitDirectiveSetMacro();
6821 Parser.Lex(); // Consume the EndOfStatement.
6822 return false;
6825 bool MipsAsmParser::parseSetNoMacroDirective() {
6826 MCAsmParser &Parser = getParser();
6827 Parser.Lex();
6828 // If this is not the end of the statement, report an error.
6829 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6830 reportParseError("unexpected token, expected end of statement");
6831 return false;
6833 if (AssemblerOptions.back()->isReorder()) {
6834 reportParseError("`noreorder' must be set before `nomacro'");
6835 return false;
6837 AssemblerOptions.back()->setNoMacro();
6838 getTargetStreamer().emitDirectiveSetNoMacro();
6839 Parser.Lex(); // Consume the EndOfStatement.
6840 return false;
6843 bool MipsAsmParser::parseSetMsaDirective() {
6844 MCAsmParser &Parser = getParser();
6845 Parser.Lex();
6847 // If this is not the end of the statement, report an error.
6848 if (getLexer().isNot(AsmToken::EndOfStatement))
6849 return reportParseError("unexpected token, expected end of statement");
6851 setFeatureBits(Mips::FeatureMSA, "msa");
6852 getTargetStreamer().emitDirectiveSetMsa();
6853 return false;
6856 bool MipsAsmParser::parseSetNoMsaDirective() {
6857 MCAsmParser &Parser = getParser();
6858 Parser.Lex();
6860 // If this is not the end of the statement, report an error.
6861 if (getLexer().isNot(AsmToken::EndOfStatement))
6862 return reportParseError("unexpected token, expected end of statement");
6864 clearFeatureBits(Mips::FeatureMSA, "msa");
6865 getTargetStreamer().emitDirectiveSetNoMsa();
6866 return false;
6869 bool MipsAsmParser::parseSetNoDspDirective() {
6870 MCAsmParser &Parser = getParser();
6871 Parser.Lex(); // Eat "nodsp".
6873 // If this is not the end of the statement, report an error.
6874 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6875 reportParseError("unexpected token, expected end of statement");
6876 return false;
6879 clearFeatureBits(Mips::FeatureDSP, "dsp");
6880 getTargetStreamer().emitDirectiveSetNoDsp();
6881 return false;
6884 bool MipsAsmParser::parseSetMips16Directive() {
6885 MCAsmParser &Parser = getParser();
6886 Parser.Lex(); // Eat "mips16".
6888 // If this is not the end of the statement, report an error.
6889 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6890 reportParseError("unexpected token, expected end of statement");
6891 return false;
6894 setFeatureBits(Mips::FeatureMips16, "mips16");
6895 getTargetStreamer().emitDirectiveSetMips16();
6896 Parser.Lex(); // Consume the EndOfStatement.
6897 return false;
6900 bool MipsAsmParser::parseSetNoMips16Directive() {
6901 MCAsmParser &Parser = getParser();
6902 Parser.Lex(); // Eat "nomips16".
6904 // If this is not the end of the statement, report an error.
6905 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6906 reportParseError("unexpected token, expected end of statement");
6907 return false;
6910 clearFeatureBits(Mips::FeatureMips16, "mips16");
6911 getTargetStreamer().emitDirectiveSetNoMips16();
6912 Parser.Lex(); // Consume the EndOfStatement.
6913 return false;
6916 bool MipsAsmParser::parseSetFpDirective() {
6917 MCAsmParser &Parser = getParser();
6918 MipsABIFlagsSection::FpABIKind FpAbiVal;
6919 // Line can be: .set fp=32
6920 // .set fp=xx
6921 // .set fp=64
6922 Parser.Lex(); // Eat fp token
6923 AsmToken Tok = Parser.getTok();
6924 if (Tok.isNot(AsmToken::Equal)) {
6925 reportParseError("unexpected token, expected equals sign '='");
6926 return false;
6928 Parser.Lex(); // Eat '=' token.
6929 Tok = Parser.getTok();
6931 if (!parseFpABIValue(FpAbiVal, ".set"))
6932 return false;
6934 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6935 reportParseError("unexpected token, expected end of statement");
6936 return false;
6938 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6939 Parser.Lex(); // Consume the EndOfStatement.
6940 return false;
6943 bool MipsAsmParser::parseSetOddSPRegDirective() {
6944 MCAsmParser &Parser = getParser();
6946 Parser.Lex(); // Eat "oddspreg".
6947 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6948 reportParseError("unexpected token, expected end of statement");
6949 return false;
6952 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6953 getTargetStreamer().emitDirectiveSetOddSPReg();
6954 return false;
6957 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6958 MCAsmParser &Parser = getParser();
6960 Parser.Lex(); // Eat "nooddspreg".
6961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6962 reportParseError("unexpected token, expected end of statement");
6963 return false;
6966 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6967 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6968 return false;
6971 bool MipsAsmParser::parseSetMtDirective() {
6972 MCAsmParser &Parser = getParser();
6973 Parser.Lex(); // Eat "mt".
6975 // If this is not the end of the statement, report an error.
6976 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6977 reportParseError("unexpected token, expected end of statement");
6978 return false;
6981 setFeatureBits(Mips::FeatureMT, "mt");
6982 getTargetStreamer().emitDirectiveSetMt();
6983 Parser.Lex(); // Consume the EndOfStatement.
6984 return false;
6987 bool MipsAsmParser::parseSetNoMtDirective() {
6988 MCAsmParser &Parser = getParser();
6989 Parser.Lex(); // Eat "nomt".
6991 // If this is not the end of the statement, report an error.
6992 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6993 reportParseError("unexpected token, expected end of statement");
6994 return false;
6997 clearFeatureBits(Mips::FeatureMT, "mt");
6999 getTargetStreamer().emitDirectiveSetNoMt();
7000 Parser.Lex(); // Consume the EndOfStatement.
7001 return false;
7004 bool MipsAsmParser::parseSetNoCRCDirective() {
7005 MCAsmParser &Parser = getParser();
7006 Parser.Lex(); // Eat "nocrc".
7008 // If this is not the end of the statement, report an error.
7009 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7010 reportParseError("unexpected token, expected end of statement");
7011 return false;
7014 clearFeatureBits(Mips::FeatureCRC, "crc");
7016 getTargetStreamer().emitDirectiveSetNoCRC();
7017 Parser.Lex(); // Consume the EndOfStatement.
7018 return false;
7021 bool MipsAsmParser::parseSetNoVirtDirective() {
7022 MCAsmParser &Parser = getParser();
7023 Parser.Lex(); // Eat "novirt".
7025 // If this is not the end of the statement, report an error.
7026 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7027 reportParseError("unexpected token, expected end of statement");
7028 return false;
7031 clearFeatureBits(Mips::FeatureVirt, "virt");
7033 getTargetStreamer().emitDirectiveSetNoVirt();
7034 Parser.Lex(); // Consume the EndOfStatement.
7035 return false;
7038 bool MipsAsmParser::parseSetNoGINVDirective() {
7039 MCAsmParser &Parser = getParser();
7040 Parser.Lex(); // Eat "noginv".
7042 // If this is not the end of the statement, report an error.
7043 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7044 reportParseError("unexpected token, expected end of statement");
7045 return false;
7048 clearFeatureBits(Mips::FeatureGINV, "ginv");
7050 getTargetStreamer().emitDirectiveSetNoGINV();
7051 Parser.Lex(); // Consume the EndOfStatement.
7052 return false;
7055 bool MipsAsmParser::parseSetPopDirective() {
7056 MCAsmParser &Parser = getParser();
7057 SMLoc Loc = getLexer().getLoc();
7059 Parser.Lex();
7060 if (getLexer().isNot(AsmToken::EndOfStatement))
7061 return reportParseError("unexpected token, expected end of statement");
7063 // Always keep an element on the options "stack" to prevent the user
7064 // from changing the initial options. This is how we remember them.
7065 if (AssemblerOptions.size() == 2)
7066 return reportParseError(Loc, ".set pop with no .set push");
7068 MCSubtargetInfo &STI = copySTI();
7069 AssemblerOptions.pop_back();
7070 setAvailableFeatures(
7071 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7072 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7074 getTargetStreamer().emitDirectiveSetPop();
7075 return false;
7078 bool MipsAsmParser::parseSetPushDirective() {
7079 MCAsmParser &Parser = getParser();
7080 Parser.Lex();
7081 if (getLexer().isNot(AsmToken::EndOfStatement))
7082 return reportParseError("unexpected token, expected end of statement");
7084 // Create a copy of the current assembler options environment and push it.
7085 AssemblerOptions.push_back(
7086 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7088 getTargetStreamer().emitDirectiveSetPush();
7089 return false;
7092 bool MipsAsmParser::parseSetSoftFloatDirective() {
7093 MCAsmParser &Parser = getParser();
7094 Parser.Lex();
7095 if (getLexer().isNot(AsmToken::EndOfStatement))
7096 return reportParseError("unexpected token, expected end of statement");
7098 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7099 getTargetStreamer().emitDirectiveSetSoftFloat();
7100 return false;
7103 bool MipsAsmParser::parseSetHardFloatDirective() {
7104 MCAsmParser &Parser = getParser();
7105 Parser.Lex();
7106 if (getLexer().isNot(AsmToken::EndOfStatement))
7107 return reportParseError("unexpected token, expected end of statement");
7109 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7110 getTargetStreamer().emitDirectiveSetHardFloat();
7111 return false;
7114 bool MipsAsmParser::parseSetAssignment() {
7115 StringRef Name;
7116 MCAsmParser &Parser = getParser();
7118 if (Parser.parseIdentifier(Name))
7119 return reportParseError("expected identifier after .set");
7121 if (getLexer().isNot(AsmToken::Comma))
7122 return reportParseError("unexpected token, expected comma");
7123 Lex(); // Eat comma
7125 if (getLexer().is(AsmToken::Dollar) &&
7126 getLexer().peekTok().is(AsmToken::Integer)) {
7127 // Parse assignment of a numeric register:
7128 // .set r1,$1
7129 Parser.Lex(); // Eat $.
7130 RegisterSets[Name] = Parser.getTok();
7131 Parser.Lex(); // Eat identifier.
7132 getContext().getOrCreateSymbol(Name);
7133 return false;
7136 MCSymbol *Sym;
7137 const MCExpr *Value;
7138 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7139 Parser, Sym, Value))
7140 return true;
7141 Sym->setVariableValue(Value);
7143 return false;
7146 bool MipsAsmParser::parseSetMips0Directive() {
7147 MCAsmParser &Parser = getParser();
7148 Parser.Lex();
7149 if (getLexer().isNot(AsmToken::EndOfStatement))
7150 return reportParseError("unexpected token, expected end of statement");
7152 // Reset assembler options to their initial values.
7153 MCSubtargetInfo &STI = copySTI();
7154 setAvailableFeatures(
7155 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7156 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7157 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7159 getTargetStreamer().emitDirectiveSetMips0();
7160 return false;
7163 bool MipsAsmParser::parseSetArchDirective() {
7164 MCAsmParser &Parser = getParser();
7165 Parser.Lex();
7166 if (getLexer().isNot(AsmToken::Equal))
7167 return reportParseError("unexpected token, expected equals sign");
7169 Parser.Lex();
7170 StringRef Arch;
7171 if (Parser.parseIdentifier(Arch))
7172 return reportParseError("expected arch identifier");
7174 StringRef ArchFeatureName =
7175 StringSwitch<StringRef>(Arch)
7176 .Case("mips1", "mips1")
7177 .Case("mips2", "mips2")
7178 .Case("mips3", "mips3")
7179 .Case("mips4", "mips4")
7180 .Case("mips5", "mips5")
7181 .Case("mips32", "mips32")
7182 .Case("mips32r2", "mips32r2")
7183 .Case("mips32r3", "mips32r3")
7184 .Case("mips32r5", "mips32r5")
7185 .Case("mips32r6", "mips32r6")
7186 .Case("mips64", "mips64")
7187 .Case("mips64r2", "mips64r2")
7188 .Case("mips64r3", "mips64r3")
7189 .Case("mips64r5", "mips64r5")
7190 .Case("mips64r6", "mips64r6")
7191 .Case("octeon", "cnmips")
7192 .Case("r4000", "mips3") // This is an implementation of Mips3.
7193 .Default("");
7195 if (ArchFeatureName.empty())
7196 return reportParseError("unsupported architecture");
7198 if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7199 return reportParseError("mips64r6 does not support microMIPS");
7201 selectArch(ArchFeatureName);
7202 getTargetStreamer().emitDirectiveSetArch(Arch);
7203 return false;
7206 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7207 MCAsmParser &Parser = getParser();
7208 Parser.Lex();
7209 if (getLexer().isNot(AsmToken::EndOfStatement))
7210 return reportParseError("unexpected token, expected end of statement");
7212 switch (Feature) {
7213 default:
7214 llvm_unreachable("Unimplemented feature");
7215 case Mips::FeatureDSP:
7216 setFeatureBits(Mips::FeatureDSP, "dsp");
7217 getTargetStreamer().emitDirectiveSetDsp();
7218 break;
7219 case Mips::FeatureDSPR2:
7220 setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7221 getTargetStreamer().emitDirectiveSetDspr2();
7222 break;
7223 case Mips::FeatureMicroMips:
7224 setFeatureBits(Mips::FeatureMicroMips, "micromips");
7225 getTargetStreamer().emitDirectiveSetMicroMips();
7226 break;
7227 case Mips::FeatureMips1:
7228 selectArch("mips1");
7229 getTargetStreamer().emitDirectiveSetMips1();
7230 break;
7231 case Mips::FeatureMips2:
7232 selectArch("mips2");
7233 getTargetStreamer().emitDirectiveSetMips2();
7234 break;
7235 case Mips::FeatureMips3:
7236 selectArch("mips3");
7237 getTargetStreamer().emitDirectiveSetMips3();
7238 break;
7239 case Mips::FeatureMips4:
7240 selectArch("mips4");
7241 getTargetStreamer().emitDirectiveSetMips4();
7242 break;
7243 case Mips::FeatureMips5:
7244 selectArch("mips5");
7245 getTargetStreamer().emitDirectiveSetMips5();
7246 break;
7247 case Mips::FeatureMips32:
7248 selectArch("mips32");
7249 getTargetStreamer().emitDirectiveSetMips32();
7250 break;
7251 case Mips::FeatureMips32r2:
7252 selectArch("mips32r2");
7253 getTargetStreamer().emitDirectiveSetMips32R2();
7254 break;
7255 case Mips::FeatureMips32r3:
7256 selectArch("mips32r3");
7257 getTargetStreamer().emitDirectiveSetMips32R3();
7258 break;
7259 case Mips::FeatureMips32r5:
7260 selectArch("mips32r5");
7261 getTargetStreamer().emitDirectiveSetMips32R5();
7262 break;
7263 case Mips::FeatureMips32r6:
7264 selectArch("mips32r6");
7265 getTargetStreamer().emitDirectiveSetMips32R6();
7266 break;
7267 case Mips::FeatureMips64:
7268 selectArch("mips64");
7269 getTargetStreamer().emitDirectiveSetMips64();
7270 break;
7271 case Mips::FeatureMips64r2:
7272 selectArch("mips64r2");
7273 getTargetStreamer().emitDirectiveSetMips64R2();
7274 break;
7275 case Mips::FeatureMips64r3:
7276 selectArch("mips64r3");
7277 getTargetStreamer().emitDirectiveSetMips64R3();
7278 break;
7279 case Mips::FeatureMips64r5:
7280 selectArch("mips64r5");
7281 getTargetStreamer().emitDirectiveSetMips64R5();
7282 break;
7283 case Mips::FeatureMips64r6:
7284 selectArch("mips64r6");
7285 getTargetStreamer().emitDirectiveSetMips64R6();
7286 break;
7287 case Mips::FeatureCRC:
7288 setFeatureBits(Mips::FeatureCRC, "crc");
7289 getTargetStreamer().emitDirectiveSetCRC();
7290 break;
7291 case Mips::FeatureVirt:
7292 setFeatureBits(Mips::FeatureVirt, "virt");
7293 getTargetStreamer().emitDirectiveSetVirt();
7294 break;
7295 case Mips::FeatureGINV:
7296 setFeatureBits(Mips::FeatureGINV, "ginv");
7297 getTargetStreamer().emitDirectiveSetGINV();
7298 break;
7300 return false;
7303 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7304 MCAsmParser &Parser = getParser();
7305 if (getLexer().isNot(AsmToken::Comma)) {
7306 SMLoc Loc = getLexer().getLoc();
7307 return Error(Loc, ErrorStr);
7310 Parser.Lex(); // Eat the comma.
7311 return true;
7314 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7315 // In this class, it is only used for .cprestore.
7316 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7317 // MipsTargetELFStreamer and MipsAsmParser.
7318 bool MipsAsmParser::isPicAndNotNxxAbi() {
7319 return inPicMode() && !(isABI_N32() || isABI_N64());
7322 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7323 if (AssemblerOptions.back()->isReorder())
7324 Warning(Loc, ".cpload should be inside a noreorder section");
7326 if (inMips16Mode()) {
7327 reportParseError(".cpload is not supported in Mips16 mode");
7328 return false;
7331 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7332 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7333 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7334 reportParseError("expected register containing function address");
7335 return false;
7338 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7339 if (!RegOpnd.isGPRAsmReg()) {
7340 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7341 return false;
7344 // If this is not the end of the statement, report an error.
7345 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7346 reportParseError("unexpected token, expected end of statement");
7347 return false;
7350 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7351 return false;
7354 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7355 if (!isABI_N32() && !isABI_N64()) {
7356 reportParseError(".cplocal is allowed only in N32 or N64 mode");
7357 return false;
7360 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7361 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
7362 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
7363 reportParseError("expected register containing global pointer");
7364 return false;
7367 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7368 if (!RegOpnd.isGPRAsmReg()) {
7369 reportParseError(RegOpnd.getStartLoc(), "invalid register");
7370 return false;
7373 // If this is not the end of the statement, report an error.
7374 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7375 reportParseError("unexpected token, expected end of statement");
7376 return false;
7378 getParser().Lex(); // Consume the EndOfStatement.
7380 unsigned NewReg = RegOpnd.getGPR32Reg();
7381 if (IsPicEnabled)
7382 GPReg = NewReg;
7384 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7385 return false;
7388 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7389 MCAsmParser &Parser = getParser();
7391 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7392 // is used in non-PIC mode.
7394 if (inMips16Mode()) {
7395 reportParseError(".cprestore is not supported in Mips16 mode");
7396 return false;
7399 // Get the stack offset value.
7400 const MCExpr *StackOffset;
7401 int64_t StackOffsetVal;
7402 if (Parser.parseExpression(StackOffset)) {
7403 reportParseError("expected stack offset value");
7404 return false;
7407 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7408 reportParseError("stack offset is not an absolute expression");
7409 return false;
7412 if (StackOffsetVal < 0) {
7413 Warning(Loc, ".cprestore with negative stack offset has no effect");
7414 IsCpRestoreSet = false;
7415 } else {
7416 IsCpRestoreSet = true;
7417 CpRestoreOffset = StackOffsetVal;
7420 // If this is not the end of the statement, report an error.
7421 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7422 reportParseError("unexpected token, expected end of statement");
7423 return false;
7426 if (!getTargetStreamer().emitDirectiveCpRestore(
7427 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7428 return true;
7429 Parser.Lex(); // Consume the EndOfStatement.
7430 return false;
7433 bool MipsAsmParser::parseDirectiveCPSetup() {
7434 MCAsmParser &Parser = getParser();
7435 unsigned FuncReg;
7436 unsigned Save;
7437 bool SaveIsReg = true;
7439 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7440 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
7441 if (ResTy == MatchOperand_NoMatch) {
7442 reportParseError("expected register containing function address");
7443 return false;
7446 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7447 if (!FuncRegOpnd.isGPRAsmReg()) {
7448 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7449 return false;
7452 FuncReg = FuncRegOpnd.getGPR32Reg();
7453 TmpReg.clear();
7455 if (!eatComma("unexpected token, expected comma"))
7456 return true;
7458 ResTy = parseAnyRegister(TmpReg);
7459 if (ResTy == MatchOperand_NoMatch) {
7460 const MCExpr *OffsetExpr;
7461 int64_t OffsetVal;
7462 SMLoc ExprLoc = getLexer().getLoc();
7464 if (Parser.parseExpression(OffsetExpr) ||
7465 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7466 reportParseError(ExprLoc, "expected save register or stack offset");
7467 return false;
7470 Save = OffsetVal;
7471 SaveIsReg = false;
7472 } else {
7473 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7474 if (!SaveOpnd.isGPRAsmReg()) {
7475 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7476 return false;
7478 Save = SaveOpnd.getGPR32Reg();
7481 if (!eatComma("unexpected token, expected comma"))
7482 return true;
7484 const MCExpr *Expr;
7485 if (Parser.parseExpression(Expr)) {
7486 reportParseError("expected expression");
7487 return false;
7490 if (Expr->getKind() != MCExpr::SymbolRef) {
7491 reportParseError("expected symbol");
7492 return false;
7494 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7496 CpSaveLocation = Save;
7497 CpSaveLocationIsRegister = SaveIsReg;
7499 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7500 SaveIsReg);
7501 return false;
7504 bool MipsAsmParser::parseDirectiveCPReturn() {
7505 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7506 CpSaveLocationIsRegister);
7507 return false;
7510 bool MipsAsmParser::parseDirectiveNaN() {
7511 MCAsmParser &Parser = getParser();
7512 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7513 const AsmToken &Tok = Parser.getTok();
7515 if (Tok.getString() == "2008") {
7516 Parser.Lex();
7517 getTargetStreamer().emitDirectiveNaN2008();
7518 return false;
7519 } else if (Tok.getString() == "legacy") {
7520 Parser.Lex();
7521 getTargetStreamer().emitDirectiveNaNLegacy();
7522 return false;
7525 // If we don't recognize the option passed to the .nan
7526 // directive (e.g. no option or unknown option), emit an error.
7527 reportParseError("invalid option in .nan directive");
7528 return false;
7531 bool MipsAsmParser::parseDirectiveSet() {
7532 const AsmToken &Tok = getParser().getTok();
7533 StringRef IdVal = Tok.getString();
7534 SMLoc Loc = Tok.getLoc();
7536 if (IdVal == "noat")
7537 return parseSetNoAtDirective();
7538 if (IdVal == "at")
7539 return parseSetAtDirective();
7540 if (IdVal == "arch")
7541 return parseSetArchDirective();
7542 if (IdVal == "bopt") {
7543 Warning(Loc, "'bopt' feature is unsupported");
7544 getParser().Lex();
7545 return false;
7547 if (IdVal == "nobopt") {
7548 // We're already running in nobopt mode, so nothing to do.
7549 getParser().Lex();
7550 return false;
7552 if (IdVal == "fp")
7553 return parseSetFpDirective();
7554 if (IdVal == "oddspreg")
7555 return parseSetOddSPRegDirective();
7556 if (IdVal == "nooddspreg")
7557 return parseSetNoOddSPRegDirective();
7558 if (IdVal == "pop")
7559 return parseSetPopDirective();
7560 if (IdVal == "push")
7561 return parseSetPushDirective();
7562 if (IdVal == "reorder")
7563 return parseSetReorderDirective();
7564 if (IdVal == "noreorder")
7565 return parseSetNoReorderDirective();
7566 if (IdVal == "macro")
7567 return parseSetMacroDirective();
7568 if (IdVal == "nomacro")
7569 return parseSetNoMacroDirective();
7570 if (IdVal == "mips16")
7571 return parseSetMips16Directive();
7572 if (IdVal == "nomips16")
7573 return parseSetNoMips16Directive();
7574 if (IdVal == "nomicromips") {
7575 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7576 getTargetStreamer().emitDirectiveSetNoMicroMips();
7577 getParser().eatToEndOfStatement();
7578 return false;
7580 if (IdVal == "micromips") {
7581 if (hasMips64r6()) {
7582 Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7583 return false;
7585 return parseSetFeature(Mips::FeatureMicroMips);
7587 if (IdVal == "mips0")
7588 return parseSetMips0Directive();
7589 if (IdVal == "mips1")
7590 return parseSetFeature(Mips::FeatureMips1);
7591 if (IdVal == "mips2")
7592 return parseSetFeature(Mips::FeatureMips2);
7593 if (IdVal == "mips3")
7594 return parseSetFeature(Mips::FeatureMips3);
7595 if (IdVal == "mips4")
7596 return parseSetFeature(Mips::FeatureMips4);
7597 if (IdVal == "mips5")
7598 return parseSetFeature(Mips::FeatureMips5);
7599 if (IdVal == "mips32")
7600 return parseSetFeature(Mips::FeatureMips32);
7601 if (IdVal == "mips32r2")
7602 return parseSetFeature(Mips::FeatureMips32r2);
7603 if (IdVal == "mips32r3")
7604 return parseSetFeature(Mips::FeatureMips32r3);
7605 if (IdVal == "mips32r5")
7606 return parseSetFeature(Mips::FeatureMips32r5);
7607 if (IdVal == "mips32r6")
7608 return parseSetFeature(Mips::FeatureMips32r6);
7609 if (IdVal == "mips64")
7610 return parseSetFeature(Mips::FeatureMips64);
7611 if (IdVal == "mips64r2")
7612 return parseSetFeature(Mips::FeatureMips64r2);
7613 if (IdVal == "mips64r3")
7614 return parseSetFeature(Mips::FeatureMips64r3);
7615 if (IdVal == "mips64r5")
7616 return parseSetFeature(Mips::FeatureMips64r5);
7617 if (IdVal == "mips64r6") {
7618 if (inMicroMipsMode()) {
7619 Error(Loc, "MIPS64R6 is not supported with microMIPS");
7620 return false;
7622 return parseSetFeature(Mips::FeatureMips64r6);
7624 if (IdVal == "dsp")
7625 return parseSetFeature(Mips::FeatureDSP);
7626 if (IdVal == "dspr2")
7627 return parseSetFeature(Mips::FeatureDSPR2);
7628 if (IdVal == "nodsp")
7629 return parseSetNoDspDirective();
7630 if (IdVal == "msa")
7631 return parseSetMsaDirective();
7632 if (IdVal == "nomsa")
7633 return parseSetNoMsaDirective();
7634 if (IdVal == "mt")
7635 return parseSetMtDirective();
7636 if (IdVal == "nomt")
7637 return parseSetNoMtDirective();
7638 if (IdVal == "softfloat")
7639 return parseSetSoftFloatDirective();
7640 if (IdVal == "hardfloat")
7641 return parseSetHardFloatDirective();
7642 if (IdVal == "crc")
7643 return parseSetFeature(Mips::FeatureCRC);
7644 if (IdVal == "nocrc")
7645 return parseSetNoCRCDirective();
7646 if (IdVal == "virt")
7647 return parseSetFeature(Mips::FeatureVirt);
7648 if (IdVal == "novirt")
7649 return parseSetNoVirtDirective();
7650 if (IdVal == "ginv")
7651 return parseSetFeature(Mips::FeatureGINV);
7652 if (IdVal == "noginv")
7653 return parseSetNoGINVDirective();
7655 // It is just an identifier, look for an assignment.
7656 return parseSetAssignment();
7659 /// parseDirectiveGpWord
7660 /// ::= .gpword local_sym
7661 bool MipsAsmParser::parseDirectiveGpWord() {
7662 MCAsmParser &Parser = getParser();
7663 const MCExpr *Value;
7664 // EmitGPRel32Value requires an expression, so we are using base class
7665 // method to evaluate the expression.
7666 if (getParser().parseExpression(Value))
7667 return true;
7668 getParser().getStreamer().EmitGPRel32Value(Value);
7670 if (getLexer().isNot(AsmToken::EndOfStatement))
7671 return Error(getLexer().getLoc(),
7672 "unexpected token, expected end of statement");
7673 Parser.Lex(); // Eat EndOfStatement token.
7674 return false;
7677 /// parseDirectiveGpDWord
7678 /// ::= .gpdword local_sym
7679 bool MipsAsmParser::parseDirectiveGpDWord() {
7680 MCAsmParser &Parser = getParser();
7681 const MCExpr *Value;
7682 // EmitGPRel64Value requires an expression, so we are using base class
7683 // method to evaluate the expression.
7684 if (getParser().parseExpression(Value))
7685 return true;
7686 getParser().getStreamer().EmitGPRel64Value(Value);
7688 if (getLexer().isNot(AsmToken::EndOfStatement))
7689 return Error(getLexer().getLoc(),
7690 "unexpected token, expected end of statement");
7691 Parser.Lex(); // Eat EndOfStatement token.
7692 return false;
7695 /// parseDirectiveDtpRelWord
7696 /// ::= .dtprelword tls_sym
7697 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7698 MCAsmParser &Parser = getParser();
7699 const MCExpr *Value;
7700 // EmitDTPRel32Value requires an expression, so we are using base class
7701 // method to evaluate the expression.
7702 if (getParser().parseExpression(Value))
7703 return true;
7704 getParser().getStreamer().EmitDTPRel32Value(Value);
7706 if (getLexer().isNot(AsmToken::EndOfStatement))
7707 return Error(getLexer().getLoc(),
7708 "unexpected token, expected end of statement");
7709 Parser.Lex(); // Eat EndOfStatement token.
7710 return false;
7713 /// parseDirectiveDtpRelDWord
7714 /// ::= .dtpreldword tls_sym
7715 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7716 MCAsmParser &Parser = getParser();
7717 const MCExpr *Value;
7718 // EmitDTPRel64Value requires an expression, so we are using base class
7719 // method to evaluate the expression.
7720 if (getParser().parseExpression(Value))
7721 return true;
7722 getParser().getStreamer().EmitDTPRel64Value(Value);
7724 if (getLexer().isNot(AsmToken::EndOfStatement))
7725 return Error(getLexer().getLoc(),
7726 "unexpected token, expected end of statement");
7727 Parser.Lex(); // Eat EndOfStatement token.
7728 return false;
7731 /// parseDirectiveTpRelWord
7732 /// ::= .tprelword tls_sym
7733 bool MipsAsmParser::parseDirectiveTpRelWord() {
7734 MCAsmParser &Parser = getParser();
7735 const MCExpr *Value;
7736 // EmitTPRel32Value requires an expression, so we are using base class
7737 // method to evaluate the expression.
7738 if (getParser().parseExpression(Value))
7739 return true;
7740 getParser().getStreamer().EmitTPRel32Value(Value);
7742 if (getLexer().isNot(AsmToken::EndOfStatement))
7743 return Error(getLexer().getLoc(),
7744 "unexpected token, expected end of statement");
7745 Parser.Lex(); // Eat EndOfStatement token.
7746 return false;
7749 /// parseDirectiveTpRelDWord
7750 /// ::= .tpreldword tls_sym
7751 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7752 MCAsmParser &Parser = getParser();
7753 const MCExpr *Value;
7754 // EmitTPRel64Value requires an expression, so we are using base class
7755 // method to evaluate the expression.
7756 if (getParser().parseExpression(Value))
7757 return true;
7758 getParser().getStreamer().EmitTPRel64Value(Value);
7760 if (getLexer().isNot(AsmToken::EndOfStatement))
7761 return Error(getLexer().getLoc(),
7762 "unexpected token, expected end of statement");
7763 Parser.Lex(); // Eat EndOfStatement token.
7764 return false;
7767 bool MipsAsmParser::parseDirectiveOption() {
7768 MCAsmParser &Parser = getParser();
7769 // Get the option token.
7770 AsmToken Tok = Parser.getTok();
7771 // At the moment only identifiers are supported.
7772 if (Tok.isNot(AsmToken::Identifier)) {
7773 return Error(Parser.getTok().getLoc(),
7774 "unexpected token, expected identifier");
7777 StringRef Option = Tok.getIdentifier();
7779 if (Option == "pic0") {
7780 // MipsAsmParser needs to know if the current PIC mode changes.
7781 IsPicEnabled = false;
7783 getTargetStreamer().emitDirectiveOptionPic0();
7784 Parser.Lex();
7785 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7786 return Error(Parser.getTok().getLoc(),
7787 "unexpected token, expected end of statement");
7789 return false;
7792 if (Option == "pic2") {
7793 // MipsAsmParser needs to know if the current PIC mode changes.
7794 IsPicEnabled = true;
7796 getTargetStreamer().emitDirectiveOptionPic2();
7797 Parser.Lex();
7798 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7799 return Error(Parser.getTok().getLoc(),
7800 "unexpected token, expected end of statement");
7802 return false;
7805 // Unknown option.
7806 Warning(Parser.getTok().getLoc(),
7807 "unknown option, expected 'pic0' or 'pic2'");
7808 Parser.eatToEndOfStatement();
7809 return false;
7812 /// parseInsnDirective
7813 /// ::= .insn
7814 bool MipsAsmParser::parseInsnDirective() {
7815 // If this is not the end of the statement, report an error.
7816 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7817 reportParseError("unexpected token, expected end of statement");
7818 return false;
7821 // The actual label marking happens in
7822 // MipsELFStreamer::createPendingLabelRelocs().
7823 getTargetStreamer().emitDirectiveInsn();
7825 getParser().Lex(); // Eat EndOfStatement token.
7826 return false;
7829 /// parseRSectionDirective
7830 /// ::= .rdata
7831 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
7832 // If this is not the end of the statement, report an error.
7833 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7834 reportParseError("unexpected token, expected end of statement");
7835 return false;
7838 MCSection *ELFSection = getContext().getELFSection(
7839 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
7840 getParser().getStreamer().SwitchSection(ELFSection);
7842 getParser().Lex(); // Eat EndOfStatement token.
7843 return false;
7846 /// parseSSectionDirective
7847 /// ::= .sbss
7848 /// ::= .sdata
7849 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
7850 // If this is not the end of the statement, report an error.
7851 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7852 reportParseError("unexpected token, expected end of statement");
7853 return false;
7856 MCSection *ELFSection = getContext().getELFSection(
7857 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
7858 getParser().getStreamer().SwitchSection(ELFSection);
7860 getParser().Lex(); // Eat EndOfStatement token.
7861 return false;
7864 /// parseDirectiveModule
7865 /// ::= .module oddspreg
7866 /// ::= .module nooddspreg
7867 /// ::= .module fp=value
7868 /// ::= .module softfloat
7869 /// ::= .module hardfloat
7870 /// ::= .module mt
7871 /// ::= .module crc
7872 /// ::= .module nocrc
7873 /// ::= .module virt
7874 /// ::= .module novirt
7875 /// ::= .module ginv
7876 /// ::= .module noginv
7877 bool MipsAsmParser::parseDirectiveModule() {
7878 MCAsmParser &Parser = getParser();
7879 MCAsmLexer &Lexer = getLexer();
7880 SMLoc L = Lexer.getLoc();
7882 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7883 // TODO : get a better message.
7884 reportParseError(".module directive must appear before any code");
7885 return false;
7888 StringRef Option;
7889 if (Parser.parseIdentifier(Option)) {
7890 reportParseError("expected .module option identifier");
7891 return false;
7894 if (Option == "oddspreg") {
7895 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7897 // Synchronize the abiflags information with the FeatureBits information we
7898 // changed above.
7899 getTargetStreamer().updateABIInfo(*this);
7901 // If printing assembly, use the recently updated abiflags information.
7902 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7903 // emitted at the end).
7904 getTargetStreamer().emitDirectiveModuleOddSPReg();
7906 // If this is not the end of the statement, report an error.
7907 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7908 reportParseError("unexpected token, expected end of statement");
7909 return false;
7912 return false; // parseDirectiveModule has finished successfully.
7913 } else if (Option == "nooddspreg") {
7914 if (!isABI_O32()) {
7915 return Error(L, "'.module nooddspreg' requires the O32 ABI");
7918 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7920 // Synchronize the abiflags information with the FeatureBits information we
7921 // changed above.
7922 getTargetStreamer().updateABIInfo(*this);
7924 // If printing assembly, use the recently updated abiflags information.
7925 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7926 // emitted at the end).
7927 getTargetStreamer().emitDirectiveModuleOddSPReg();
7929 // If this is not the end of the statement, report an error.
7930 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7931 reportParseError("unexpected token, expected end of statement");
7932 return false;
7935 return false; // parseDirectiveModule has finished successfully.
7936 } else if (Option == "fp") {
7937 return parseDirectiveModuleFP();
7938 } else if (Option == "softfloat") {
7939 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7941 // Synchronize the ABI Flags information with the FeatureBits information we
7942 // updated above.
7943 getTargetStreamer().updateABIInfo(*this);
7945 // If printing assembly, use the recently updated ABI Flags information.
7946 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7947 // emitted later).
7948 getTargetStreamer().emitDirectiveModuleSoftFloat();
7950 // If this is not the end of the statement, report an error.
7951 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7952 reportParseError("unexpected token, expected end of statement");
7953 return false;
7956 return false; // parseDirectiveModule has finished successfully.
7957 } else if (Option == "hardfloat") {
7958 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7960 // Synchronize the ABI Flags information with the FeatureBits information we
7961 // updated above.
7962 getTargetStreamer().updateABIInfo(*this);
7964 // If printing assembly, use the recently updated ABI Flags information.
7965 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7966 // emitted later).
7967 getTargetStreamer().emitDirectiveModuleHardFloat();
7969 // If this is not the end of the statement, report an error.
7970 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7971 reportParseError("unexpected token, expected end of statement");
7972 return false;
7975 return false; // parseDirectiveModule has finished successfully.
7976 } else if (Option == "mt") {
7977 setModuleFeatureBits(Mips::FeatureMT, "mt");
7979 // Synchronize the ABI Flags information with the FeatureBits information we
7980 // updated above.
7981 getTargetStreamer().updateABIInfo(*this);
7983 // If printing assembly, use the recently updated ABI Flags information.
7984 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
7985 // emitted later).
7986 getTargetStreamer().emitDirectiveModuleMT();
7988 // If this is not the end of the statement, report an error.
7989 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7990 reportParseError("unexpected token, expected end of statement");
7991 return false;
7994 return false; // parseDirectiveModule has finished successfully.
7995 } else if (Option == "crc") {
7996 setModuleFeatureBits(Mips::FeatureCRC, "crc");
7998 // Synchronize the ABI Flags information with the FeatureBits information we
7999 // updated above.
8000 getTargetStreamer().updateABIInfo(*this);
8002 // If printing assembly, use the recently updated ABI Flags information.
8003 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8004 // emitted later).
8005 getTargetStreamer().emitDirectiveModuleCRC();
8007 // If this is not the end of the statement, report an error.
8008 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8009 reportParseError("unexpected token, expected end of statement");
8010 return false;
8013 return false; // parseDirectiveModule has finished successfully.
8014 } else if (Option == "nocrc") {
8015 clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8017 // Synchronize the ABI Flags information with the FeatureBits information we
8018 // updated above.
8019 getTargetStreamer().updateABIInfo(*this);
8021 // If printing assembly, use the recently updated ABI Flags information.
8022 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8023 // emitted later).
8024 getTargetStreamer().emitDirectiveModuleNoCRC();
8026 // If this is not the end of the statement, report an error.
8027 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8028 reportParseError("unexpected token, expected end of statement");
8029 return false;
8032 return false; // parseDirectiveModule has finished successfully.
8033 } else if (Option == "virt") {
8034 setModuleFeatureBits(Mips::FeatureVirt, "virt");
8036 // Synchronize the ABI Flags information with the FeatureBits information we
8037 // updated above.
8038 getTargetStreamer().updateABIInfo(*this);
8040 // If printing assembly, use the recently updated ABI Flags information.
8041 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8042 // emitted later).
8043 getTargetStreamer().emitDirectiveModuleVirt();
8045 // If this is not the end of the statement, report an error.
8046 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8047 reportParseError("unexpected token, expected end of statement");
8048 return false;
8051 return false; // parseDirectiveModule has finished successfully.
8052 } else if (Option == "novirt") {
8053 clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8055 // Synchronize the ABI Flags information with the FeatureBits information we
8056 // updated above.
8057 getTargetStreamer().updateABIInfo(*this);
8059 // If printing assembly, use the recently updated ABI Flags information.
8060 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8061 // emitted later).
8062 getTargetStreamer().emitDirectiveModuleNoVirt();
8064 // If this is not the end of the statement, report an error.
8065 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8066 reportParseError("unexpected token, expected end of statement");
8067 return false;
8070 return false; // parseDirectiveModule has finished successfully.
8071 } else if (Option == "ginv") {
8072 setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8074 // Synchronize the ABI Flags information with the FeatureBits information we
8075 // updated above.
8076 getTargetStreamer().updateABIInfo(*this);
8078 // If printing assembly, use the recently updated ABI Flags information.
8079 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8080 // emitted later).
8081 getTargetStreamer().emitDirectiveModuleGINV();
8083 // If this is not the end of the statement, report an error.
8084 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8085 reportParseError("unexpected token, expected end of statement");
8086 return false;
8089 return false; // parseDirectiveModule has finished successfully.
8090 } else if (Option == "noginv") {
8091 clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8093 // Synchronize the ABI Flags information with the FeatureBits information we
8094 // updated above.
8095 getTargetStreamer().updateABIInfo(*this);
8097 // If printing assembly, use the recently updated ABI Flags information.
8098 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8099 // emitted later).
8100 getTargetStreamer().emitDirectiveModuleNoGINV();
8102 // If this is not the end of the statement, report an error.
8103 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8104 reportParseError("unexpected token, expected end of statement");
8105 return false;
8108 return false; // parseDirectiveModule has finished successfully.
8109 } else {
8110 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8114 /// parseDirectiveModuleFP
8115 /// ::= =32
8116 /// ::= =xx
8117 /// ::= =64
8118 bool MipsAsmParser::parseDirectiveModuleFP() {
8119 MCAsmParser &Parser = getParser();
8120 MCAsmLexer &Lexer = getLexer();
8122 if (Lexer.isNot(AsmToken::Equal)) {
8123 reportParseError("unexpected token, expected equals sign '='");
8124 return false;
8126 Parser.Lex(); // Eat '=' token.
8128 MipsABIFlagsSection::FpABIKind FpABI;
8129 if (!parseFpABIValue(FpABI, ".module"))
8130 return false;
8132 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8133 reportParseError("unexpected token, expected end of statement");
8134 return false;
8137 // Synchronize the abiflags information with the FeatureBits information we
8138 // changed above.
8139 getTargetStreamer().updateABIInfo(*this);
8141 // If printing assembly, use the recently updated abiflags information.
8142 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8143 // emitted at the end).
8144 getTargetStreamer().emitDirectiveModuleFP();
8146 Parser.Lex(); // Consume the EndOfStatement.
8147 return false;
8150 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8151 StringRef Directive) {
8152 MCAsmParser &Parser = getParser();
8153 MCAsmLexer &Lexer = getLexer();
8154 bool ModuleLevelOptions = Directive == ".module";
8156 if (Lexer.is(AsmToken::Identifier)) {
8157 StringRef Value = Parser.getTok().getString();
8158 Parser.Lex();
8160 if (Value != "xx") {
8161 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8162 return false;
8165 if (!isABI_O32()) {
8166 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8167 return false;
8170 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8171 if (ModuleLevelOptions) {
8172 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8173 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8174 } else {
8175 setFeatureBits(Mips::FeatureFPXX, "fpxx");
8176 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8178 return true;
8181 if (Lexer.is(AsmToken::Integer)) {
8182 unsigned Value = Parser.getTok().getIntVal();
8183 Parser.Lex();
8185 if (Value != 32 && Value != 64) {
8186 reportParseError("unsupported value, expected 'xx', '32' or '64'");
8187 return false;
8190 if (Value == 32) {
8191 if (!isABI_O32()) {
8192 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8193 return false;
8196 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8197 if (ModuleLevelOptions) {
8198 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8199 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8200 } else {
8201 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8202 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8204 } else {
8205 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8206 if (ModuleLevelOptions) {
8207 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8208 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8209 } else {
8210 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8211 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8215 return true;
8218 return false;
8221 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8222 // This returns false if this function recognizes the directive
8223 // regardless of whether it is successfully handles or reports an
8224 // error. Otherwise it returns true to give the generic parser a
8225 // chance at recognizing it.
8227 MCAsmParser &Parser = getParser();
8228 StringRef IDVal = DirectiveID.getString();
8230 if (IDVal == ".cpload") {
8231 parseDirectiveCpLoad(DirectiveID.getLoc());
8232 return false;
8234 if (IDVal == ".cprestore") {
8235 parseDirectiveCpRestore(DirectiveID.getLoc());
8236 return false;
8238 if (IDVal == ".cplocal") {
8239 parseDirectiveCpLocal(DirectiveID.getLoc());
8240 return false;
8242 if (IDVal == ".ent") {
8243 StringRef SymbolName;
8245 if (Parser.parseIdentifier(SymbolName)) {
8246 reportParseError("expected identifier after .ent");
8247 return false;
8250 // There's an undocumented extension that allows an integer to
8251 // follow the name of the procedure which AFAICS is ignored by GAS.
8252 // Example: .ent foo,2
8253 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8254 if (getLexer().isNot(AsmToken::Comma)) {
8255 // Even though we accept this undocumented extension for compatibility
8256 // reasons, the additional integer argument does not actually change
8257 // the behaviour of the '.ent' directive, so we would like to discourage
8258 // its use. We do this by not referring to the extended version in
8259 // error messages which are not directly related to its use.
8260 reportParseError("unexpected token, expected end of statement");
8261 return false;
8263 Parser.Lex(); // Eat the comma.
8264 const MCExpr *DummyNumber;
8265 int64_t DummyNumberVal;
8266 // If the user was explicitly trying to use the extended version,
8267 // we still give helpful extension-related error messages.
8268 if (Parser.parseExpression(DummyNumber)) {
8269 reportParseError("expected number after comma");
8270 return false;
8272 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8273 reportParseError("expected an absolute expression after comma");
8274 return false;
8278 // If this is not the end of the statement, report an error.
8279 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8280 reportParseError("unexpected token, expected end of statement");
8281 return false;
8284 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8286 getTargetStreamer().emitDirectiveEnt(*Sym);
8287 CurrentFn = Sym;
8288 IsCpRestoreSet = false;
8289 return false;
8292 if (IDVal == ".end") {
8293 StringRef SymbolName;
8295 if (Parser.parseIdentifier(SymbolName)) {
8296 reportParseError("expected identifier after .end");
8297 return false;
8300 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8301 reportParseError("unexpected token, expected end of statement");
8302 return false;
8305 if (CurrentFn == nullptr) {
8306 reportParseError(".end used without .ent");
8307 return false;
8310 if ((SymbolName != CurrentFn->getName())) {
8311 reportParseError(".end symbol does not match .ent symbol");
8312 return false;
8315 getTargetStreamer().emitDirectiveEnd(SymbolName);
8316 CurrentFn = nullptr;
8317 IsCpRestoreSet = false;
8318 return false;
8321 if (IDVal == ".frame") {
8322 // .frame $stack_reg, frame_size_in_bytes, $return_reg
8323 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8324 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
8325 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8326 reportParseError("expected stack register");
8327 return false;
8330 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8331 if (!StackRegOpnd.isGPRAsmReg()) {
8332 reportParseError(StackRegOpnd.getStartLoc(),
8333 "expected general purpose register");
8334 return false;
8336 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8338 if (Parser.getTok().is(AsmToken::Comma))
8339 Parser.Lex();
8340 else {
8341 reportParseError("unexpected token, expected comma");
8342 return false;
8345 // Parse the frame size.
8346 const MCExpr *FrameSize;
8347 int64_t FrameSizeVal;
8349 if (Parser.parseExpression(FrameSize)) {
8350 reportParseError("expected frame size value");
8351 return false;
8354 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8355 reportParseError("frame size not an absolute expression");
8356 return false;
8359 if (Parser.getTok().is(AsmToken::Comma))
8360 Parser.Lex();
8361 else {
8362 reportParseError("unexpected token, expected comma");
8363 return false;
8366 // Parse the return register.
8367 TmpReg.clear();
8368 ResTy = parseAnyRegister(TmpReg);
8369 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
8370 reportParseError("expected return register");
8371 return false;
8374 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8375 if (!ReturnRegOpnd.isGPRAsmReg()) {
8376 reportParseError(ReturnRegOpnd.getStartLoc(),
8377 "expected general purpose register");
8378 return false;
8381 // If this is not the end of the statement, report an error.
8382 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8383 reportParseError("unexpected token, expected end of statement");
8384 return false;
8387 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8388 ReturnRegOpnd.getGPR32Reg());
8389 IsCpRestoreSet = false;
8390 return false;
8393 if (IDVal == ".set") {
8394 parseDirectiveSet();
8395 return false;
8398 if (IDVal == ".mask" || IDVal == ".fmask") {
8399 // .mask bitmask, frame_offset
8400 // bitmask: One bit for each register used.
8401 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8402 // first register is expected to be saved.
8403 // Examples:
8404 // .mask 0x80000000, -4
8405 // .fmask 0x80000000, -4
8408 // Parse the bitmask
8409 const MCExpr *BitMask;
8410 int64_t BitMaskVal;
8412 if (Parser.parseExpression(BitMask)) {
8413 reportParseError("expected bitmask value");
8414 return false;
8417 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8418 reportParseError("bitmask not an absolute expression");
8419 return false;
8422 if (Parser.getTok().is(AsmToken::Comma))
8423 Parser.Lex();
8424 else {
8425 reportParseError("unexpected token, expected comma");
8426 return false;
8429 // Parse the frame_offset
8430 const MCExpr *FrameOffset;
8431 int64_t FrameOffsetVal;
8433 if (Parser.parseExpression(FrameOffset)) {
8434 reportParseError("expected frame offset value");
8435 return false;
8438 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8439 reportParseError("frame offset not an absolute expression");
8440 return false;
8443 // If this is not the end of the statement, report an error.
8444 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8445 reportParseError("unexpected token, expected end of statement");
8446 return false;
8449 if (IDVal == ".mask")
8450 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8451 else
8452 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8453 return false;
8456 if (IDVal == ".nan")
8457 return parseDirectiveNaN();
8459 if (IDVal == ".gpword") {
8460 parseDirectiveGpWord();
8461 return false;
8464 if (IDVal == ".gpdword") {
8465 parseDirectiveGpDWord();
8466 return false;
8469 if (IDVal == ".dtprelword") {
8470 parseDirectiveDtpRelWord();
8471 return false;
8474 if (IDVal == ".dtpreldword") {
8475 parseDirectiveDtpRelDWord();
8476 return false;
8479 if (IDVal == ".tprelword") {
8480 parseDirectiveTpRelWord();
8481 return false;
8484 if (IDVal == ".tpreldword") {
8485 parseDirectiveTpRelDWord();
8486 return false;
8489 if (IDVal == ".option") {
8490 parseDirectiveOption();
8491 return false;
8494 if (IDVal == ".abicalls") {
8495 getTargetStreamer().emitDirectiveAbiCalls();
8496 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8497 Error(Parser.getTok().getLoc(),
8498 "unexpected token, expected end of statement");
8500 return false;
8503 if (IDVal == ".cpsetup") {
8504 parseDirectiveCPSetup();
8505 return false;
8507 if (IDVal == ".cpreturn") {
8508 parseDirectiveCPReturn();
8509 return false;
8511 if (IDVal == ".module") {
8512 parseDirectiveModule();
8513 return false;
8515 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8516 parseInternalDirectiveReallowModule();
8517 return false;
8519 if (IDVal == ".insn") {
8520 parseInsnDirective();
8521 return false;
8523 if (IDVal == ".rdata") {
8524 parseRSectionDirective(".rodata");
8525 return false;
8527 if (IDVal == ".sbss") {
8528 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8529 return false;
8531 if (IDVal == ".sdata") {
8532 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8533 return false;
8536 return true;
8539 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8540 // If this is not the end of the statement, report an error.
8541 if (getLexer().isNot(AsmToken::EndOfStatement)) {
8542 reportParseError("unexpected token, expected end of statement");
8543 return false;
8546 getTargetStreamer().reallowModuleDirective();
8548 getParser().Lex(); // Eat EndOfStatement token.
8549 return false;
8552 extern "C" void LLVMInitializeMipsAsmParser() {
8553 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8554 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8555 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8556 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8559 #define GET_REGISTER_MATCHER
8560 #define GET_MATCHER_IMPLEMENTATION
8561 #define GET_MNEMONIC_SPELL_CHECKER
8562 #include "MipsGenAsmMatcher.inc"
8564 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8565 // Find the appropriate table for this asm variant.
8566 const MatchEntry *Start, *End;
8567 switch (VariantID) {
8568 default: llvm_unreachable("invalid variant!");
8569 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8571 // Search the table.
8572 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8573 return MnemonicRange.first != MnemonicRange.second;