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