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