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