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