LLVM  3.7.0
MipsAsmParser.cpp
Go to the documentation of this file.
1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/SourceMgr.h"
33 #include <memory>
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "mips-asm-parser"
38 
39 namespace llvm {
40 class MCInstrInfo;
41 }
42 
43 namespace {
44 class MipsAssemblerOptions {
45 public:
46  MipsAssemblerOptions(const FeatureBitset &Features_) :
47  ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
48 
49  MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50  ATReg = Opts->getATRegIndex();
51  Reorder = Opts->isReorder();
52  Macro = Opts->isMacro();
53  Features = Opts->getFeatures();
54  }
55 
56  unsigned getATRegIndex() const { return ATReg; }
57  bool setATRegIndex(unsigned Reg) {
58  if (Reg > 31)
59  return false;
60 
61  ATReg = Reg;
62  return true;
63  }
64 
65  bool isReorder() const { return Reorder; }
66  void setReorder() { Reorder = true; }
67  void setNoReorder() { Reorder = false; }
68 
69  bool isMacro() const { return Macro; }
70  void setMacro() { Macro = true; }
71  void setNoMacro() { Macro = false; }
72 
73  const FeatureBitset &getFeatures() const { return Features; }
74  void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
75 
76  // Set of features that are either architecture features or referenced
77  // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78  // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79  // The reason we need this mask is explained in the selectArch function.
80  // FIXME: Ideally we would like TableGen to generate this information.
81  static const FeatureBitset AllArchRelatedMask;
82 
83 private:
84  unsigned ATReg;
85  bool Reorder;
86  bool Macro;
88 };
89 }
90 
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92  Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93  Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94  Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95  Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96  Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97  Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98  Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99  Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
100 };
101 
102 namespace {
103 class MipsAsmParser : public MCTargetAsmParser {
104  MipsTargetStreamer &getTargetStreamer() {
105  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106  return static_cast<MipsTargetStreamer &>(TS);
107  }
108 
109  MCSubtargetInfo &STI;
110  MipsABIInfo ABI;
112  MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113  // nullptr, which indicates that no function is currently
114  // selected. This usually happens after an '.end func'
115  // directive.
116  bool IsLittleEndian;
117 
118  // Print a warning along with its fix-it message at the given range.
119  void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
120  SMRange Range, bool ShowColors = true);
121 
122 #define GET_ASSEMBLER_HEADER
123 #include "MipsGenAsmMatcher.inc"
124 
125  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
126 
127  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
129  uint64_t &ErrorInfo,
130  bool MatchingInlineAsm) override;
131 
132  /// Parse a register as used in CFI directives
133  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
134 
135  bool parseParenSuffix(StringRef Name, OperandVector &Operands);
136 
137  bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
138 
139  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
140  SMLoc NameLoc, OperandVector &Operands) override;
141 
142  bool ParseDirective(AsmToken DirectiveID) override;
143 
144  MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
145 
146  MipsAsmParser::OperandMatchResultTy
147  matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
148  StringRef Identifier, SMLoc S);
149 
150  MipsAsmParser::OperandMatchResultTy
151  matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
152 
153  MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
154 
155  MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
156 
157  MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
158 
159  MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 
161  MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 
163  MipsAsmParser::OperandMatchResultTy
164  parseRegisterPair (OperandVector &Operands);
165 
166  MipsAsmParser::OperandMatchResultTy
167  parseMovePRegPair(OperandVector &Operands);
168 
169  MipsAsmParser::OperandMatchResultTy
170  parseRegisterList (OperandVector &Operands);
171 
172  bool searchSymbolAlias(OperandVector &Operands);
173 
174  bool parseOperand(OperandVector &, StringRef Mnemonic);
175 
176  bool needsExpansion(MCInst &Inst);
177 
178  // Expands assembly pseudo instructions.
179  // Returns false on success, true otherwise.
180  bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
181  SmallVectorImpl<MCInst> &Instructions);
182 
183  bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
184  SmallVectorImpl<MCInst> &Instructions);
185 
186  bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
187  bool Is32BitImm, SMLoc IDLoc,
188  SmallVectorImpl<MCInst> &Instructions);
189 
190  bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
191  unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
192  SmallVectorImpl<MCInst> &Instructions);
193 
194  bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
195  SmallVectorImpl<MCInst> &Instructions);
196 
197  bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
198  SmallVectorImpl<MCInst> &Instructions);
199 
200  bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
201  SmallVectorImpl<MCInst> &Instructions);
202  bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
203  SmallVectorImpl<MCInst> &Instructions);
204 
205  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
206  SmallVectorImpl<MCInst> &Instructions, bool isLoad,
207  bool isImmOpnd);
208 
209  bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
210  SmallVectorImpl<MCInst> &Instructions);
211 
212  bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
213  SmallVectorImpl<MCInst> &Instructions);
214 
215  bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
216  SmallVectorImpl<MCInst> &Instructions);
217 
218  bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
219  SmallVectorImpl<MCInst> &Instructions);
220 
221  bool expandUlw(MCInst &Inst, SMLoc IDLoc,
222  SmallVectorImpl<MCInst> &Instructions);
223 
224  void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
225  SmallVectorImpl<MCInst> &Instructions);
226 
227  void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
228  bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
229 
230  bool reportParseError(Twine ErrorMsg);
231  bool reportParseError(SMLoc Loc, Twine ErrorMsg);
232 
233  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
234  bool parseRelocOperand(const MCExpr *&Res);
235 
236  const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
237 
238  bool isEvaluated(const MCExpr *Expr);
239  bool parseSetMips0Directive();
240  bool parseSetArchDirective();
241  bool parseSetFeature(uint64_t Feature);
242  bool parseDirectiveCpLoad(SMLoc Loc);
243  bool parseDirectiveCPSetup();
244  bool parseDirectiveNaN();
245  bool parseDirectiveSet();
246  bool parseDirectiveOption();
247  bool parseInsnDirective();
248 
249  bool parseSetAtDirective();
250  bool parseSetNoAtDirective();
251  bool parseSetMacroDirective();
252  bool parseSetNoMacroDirective();
253  bool parseSetMsaDirective();
254  bool parseSetNoMsaDirective();
255  bool parseSetNoDspDirective();
256  bool parseSetReorderDirective();
257  bool parseSetNoReorderDirective();
258  bool parseSetMips16Directive();
259  bool parseSetNoMips16Directive();
260  bool parseSetFpDirective();
261  bool parseSetOddSPRegDirective();
262  bool parseSetNoOddSPRegDirective();
263  bool parseSetPopDirective();
264  bool parseSetPushDirective();
265  bool parseSetSoftFloatDirective();
266  bool parseSetHardFloatDirective();
267 
268  bool parseSetAssignment();
269 
270  bool parseDataDirective(unsigned Size, SMLoc L);
271  bool parseDirectiveGpWord();
272  bool parseDirectiveGpDWord();
273  bool parseDirectiveModule();
274  bool parseDirectiveModuleFP();
275  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
276  StringRef Directive);
277 
278  bool parseInternalDirectiveReallowModule();
279 
281 
282  bool eatComma(StringRef ErrorStr);
283 
284  int matchCPURegisterName(StringRef Symbol);
285 
286  int matchHWRegsRegisterName(StringRef Symbol);
287 
288  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
289 
290  int matchFPURegisterName(StringRef Name);
291 
292  int matchFCCRegisterName(StringRef Name);
293 
294  int matchACRegisterName(StringRef Name);
295 
296  int matchMSA128RegisterName(StringRef Name);
297 
298  int matchMSA128CtrlRegisterName(StringRef Name);
299 
300  unsigned getReg(int RC, int RegNo);
301 
302  unsigned getGPR(int RegNo);
303 
304  /// Returns the internal register number for the current AT. Also checks if
305  /// the current AT is unavailable (set to $0) and gives an error if it is.
306  /// This should be used in pseudo-instruction expansions which need AT.
307  unsigned getATReg(SMLoc Loc);
308 
309  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
310  SmallVectorImpl<MCInst> &Instructions);
311 
312  // Helper function that checks if the value of a vector index is within the
313  // boundaries of accepted values for each RegisterKind
314  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
315  bool validateMSAIndex(int Val, int RegKind);
316 
317  // Selects a new architecture by updating the FeatureBits with the necessary
318  // info including implied dependencies.
319  // Internally, it clears all the feature bits related to *any* architecture
320  // and selects the new one using the ToggleFeature functionality of the
321  // MCSubtargetInfo object that handles implied dependencies. The reason we
322  // clear all the arch related bits manually is because ToggleFeature only
323  // clears the features that imply the feature being cleared and not the
324  // features implied by the feature being cleared. This is easier to see
325  // with an example:
326  // --------------------------------------------------
327  // | Feature | Implies |
328  // | -------------------------------------------------|
329  // | FeatureMips1 | None |
330  // | FeatureMips2 | FeatureMips1 |
331  // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
332  // | FeatureMips4 | FeatureMips3 |
333  // | ... | |
334  // --------------------------------------------------
335  //
336  // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
337  // FeatureMipsGP64 | FeatureMips1)
338  // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
339  void selectArch(StringRef ArchFeature) {
340  FeatureBitset FeatureBits = STI.getFeatureBits();
341  FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
342  STI.setFeatureBits(FeatureBits);
343  setAvailableFeatures(
344  ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
345  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
346  }
347 
348  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
349  if (!(STI.getFeatureBits()[Feature])) {
350  setAvailableFeatures(
351  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
352  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
353  }
354  }
355 
356  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
357  if (STI.getFeatureBits()[Feature]) {
358  setAvailableFeatures(
359  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
360  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
361  }
362  }
363 
364  void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
365  setFeatureBits(Feature, FeatureString);
366  AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
367  }
368 
369  void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
370  clearFeatureBits(Feature, FeatureString);
371  AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
372  }
373 
374 public:
375  enum MipsMatchResultTy {
376  Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
377 #define GET_OPERAND_DIAGNOSTIC_TYPES
378 #include "MipsGenAsmMatcher.inc"
379 #undef GET_OPERAND_DIAGNOSTIC_TYPES
380 
381  };
382 
383  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
384  const MCInstrInfo &MII, const MCTargetOptions &Options)
385  : MCTargetAsmParser(), STI(sti),
386  ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
387  sti.getCPU(), Options)) {
389 
390  parser.addAliasForDirective(".asciiz", ".asciz");
391 
392  // Initialize the set of available features.
393  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
394 
395  // Remember the initial assembler options. The user can not modify these.
396  AssemblerOptions.push_back(
397  llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
398 
399  // Create an assembler options environment for the user to modify.
400  AssemblerOptions.push_back(
401  llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
402 
403  getTargetStreamer().updateABIInfo(*this);
404 
405  if (!isABI_O32() && !useOddSPReg() != 0)
406  report_fatal_error("-mno-odd-spreg requires the O32 ABI");
407 
408  CurrentFn = nullptr;
409 
410  Triple TheTriple(sti.getTargetTriple());
411  if ((TheTriple.getArch() == Triple::mips) ||
412  (TheTriple.getArch() == Triple::mips64))
413  IsLittleEndian = false;
414  else
415  IsLittleEndian = true;
416  }
417 
418  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
419  bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
420 
421  bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
422  bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
423  const MipsABIInfo &getABI() const { return ABI; }
424  bool isABI_N32() const { return ABI.IsN32(); }
425  bool isABI_N64() const { return ABI.IsN64(); }
426  bool isABI_O32() const { return ABI.IsO32(); }
427  bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
428 
429  bool useOddSPReg() const {
430  return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
431  }
432 
433  bool inMicroMipsMode() const {
434  return STI.getFeatureBits()[Mips::FeatureMicroMips];
435  }
436  bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
437  bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
438  bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
439  bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
440  bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
441  bool hasMips32() const {
442  return STI.getFeatureBits()[Mips::FeatureMips32];
443  }
444  bool hasMips64() const {
445  return STI.getFeatureBits()[Mips::FeatureMips64];
446  }
447  bool hasMips32r2() const {
448  return STI.getFeatureBits()[Mips::FeatureMips32r2];
449  }
450  bool hasMips64r2() const {
451  return STI.getFeatureBits()[Mips::FeatureMips64r2];
452  }
453  bool hasMips32r3() const {
454  return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
455  }
456  bool hasMips64r3() const {
457  return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
458  }
459  bool hasMips32r5() const {
460  return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
461  }
462  bool hasMips64r5() const {
463  return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
464  }
465  bool hasMips32r6() const {
466  return STI.getFeatureBits()[Mips::FeatureMips32r6];
467  }
468  bool hasMips64r6() const {
469  return STI.getFeatureBits()[Mips::FeatureMips64r6];
470  }
471 
472  bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
473  bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
474  bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
475  bool hasCnMips() const {
476  return (STI.getFeatureBits()[Mips::FeatureCnMips]);
477  }
478 
479  bool inMips16Mode() const {
480  return STI.getFeatureBits()[Mips::FeatureMips16];
481  }
482 
483  bool useSoftFloat() const {
484  return STI.getFeatureBits()[Mips::FeatureSoftFloat];
485  }
486 
487  /// Warn if RegIndex is the same as the current AT.
488  void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
489 
490  void warnIfNoMacro(SMLoc Loc);
491 
492  bool isLittle() const { return IsLittleEndian; }
493 };
494 }
495 
496 namespace {
497 
498 /// MipsOperand - Instances of this class represent a parsed Mips machine
499 /// instruction.
500 class MipsOperand : public MCParsedAsmOperand {
501 public:
502  /// Broad categories of register classes
503  /// The exact class is finalized by the render method.
504  enum RegKind {
505  RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
506  RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
507  /// isFP64bit())
508  RegKind_FCC = 4, /// FCC
509  RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
510  RegKind_MSACtrl = 16, /// MSA control registers
511  RegKind_COP2 = 32, /// COP2
512  RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
513  /// context).
514  RegKind_CCR = 128, /// CCR
515  RegKind_HWRegs = 256, /// HWRegs
516  RegKind_COP3 = 512, /// COP3
517  RegKind_COP0 = 1024, /// COP0
518  /// Potentially any (e.g. $1)
519  RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
520  RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
521  RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
522  };
523 
524 private:
525  enum KindTy {
526  k_Immediate, /// An immediate (possibly involving symbol references)
527  k_Memory, /// Base + Offset Memory Address
528  k_PhysRegister, /// A physical register from the Mips namespace
529  k_RegisterIndex, /// A register index in one or more RegKind.
530  k_Token, /// A simple token
531  k_RegList, /// A physical register list
532  k_RegPair /// A pair of physical register
533  } Kind;
534 
535 public:
536  MipsOperand(KindTy K, MipsAsmParser &Parser)
537  : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
538 
539 private:
540  /// For diagnostics, and checking the assembler temporary
541  MipsAsmParser &AsmParser;
542 
543  struct Token {
544  const char *Data;
545  unsigned Length;
546  };
547 
548  struct PhysRegOp {
549  unsigned Num; /// Register Number
550  };
551 
552  struct RegIdxOp {
553  unsigned Index; /// Index into the register class
554  RegKind Kind; /// Bitfield of the kinds it could possibly be
555  const MCRegisterInfo *RegInfo;
556  };
557 
558  struct ImmOp {
559  const MCExpr *Val;
560  };
561 
562  struct MemOp {
563  MipsOperand *Base;
564  const MCExpr *Off;
565  };
566 
567  struct RegListOp {
569  };
570 
571  union {
572  struct Token Tok;
573  struct PhysRegOp PhysReg;
574  struct RegIdxOp RegIdx;
575  struct ImmOp Imm;
576  struct MemOp Mem;
577  struct RegListOp RegList;
578  };
579 
580  SMLoc StartLoc, EndLoc;
581 
582  /// Internal constructor for register kinds
583  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
584  const MCRegisterInfo *RegInfo,
585  SMLoc S, SMLoc E,
586  MipsAsmParser &Parser) {
587  auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
588  Op->RegIdx.Index = Index;
589  Op->RegIdx.RegInfo = RegInfo;
590  Op->RegIdx.Kind = RegKind;
591  Op->StartLoc = S;
592  Op->EndLoc = E;
593  return Op;
594  }
595 
596 public:
597  /// Coerce the register to GPR32 and return the real register for the current
598  /// target.
599  unsigned getGPR32Reg() const {
600  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
601  AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
602  unsigned ClassID = Mips::GPR32RegClassID;
603  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
604  }
605 
606  /// Coerce the register to GPR32 and return the real register for the current
607  /// target.
608  unsigned getGPRMM16Reg() const {
609  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
610  unsigned ClassID = Mips::GPR32RegClassID;
611  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
612  }
613 
614  /// Coerce the register to GPR64 and return the real register for the current
615  /// target.
616  unsigned getGPR64Reg() const {
617  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
618  unsigned ClassID = Mips::GPR64RegClassID;
619  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
620  }
621 
622 private:
623  /// Coerce the register to AFGR64 and return the real register for the current
624  /// target.
625  unsigned getAFGR64Reg() const {
626  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
627  if (RegIdx.Index % 2 != 0)
628  AsmParser.Warning(StartLoc, "Float register should be even.");
629  return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
630  .getRegister(RegIdx.Index / 2);
631  }
632 
633  /// Coerce the register to FGR64 and return the real register for the current
634  /// target.
635  unsigned getFGR64Reg() const {
636  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
637  return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
638  .getRegister(RegIdx.Index);
639  }
640 
641  /// Coerce the register to FGR32 and return the real register for the current
642  /// target.
643  unsigned getFGR32Reg() const {
644  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
645  return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
646  .getRegister(RegIdx.Index);
647  }
648 
649  /// Coerce the register to FGRH32 and return the real register for the current
650  /// target.
651  unsigned getFGRH32Reg() const {
652  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
653  return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
654  .getRegister(RegIdx.Index);
655  }
656 
657  /// Coerce the register to FCC and return the real register for the current
658  /// target.
659  unsigned getFCCReg() const {
660  assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
661  return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
662  .getRegister(RegIdx.Index);
663  }
664 
665  /// Coerce the register to MSA128 and return the real register for the current
666  /// target.
667  unsigned getMSA128Reg() const {
668  assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
669  // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
670  // identical
671  unsigned ClassID = Mips::MSA128BRegClassID;
672  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673  }
674 
675  /// Coerce the register to MSACtrl and return the real register for the
676  /// current target.
677  unsigned getMSACtrlReg() const {
678  assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
679  unsigned ClassID = Mips::MSACtrlRegClassID;
680  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
681  }
682 
683  /// Coerce the register to COP0 and return the real register for the
684  /// current target.
685  unsigned getCOP0Reg() const {
686  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
687  unsigned ClassID = Mips::COP0RegClassID;
688  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
689  }
690 
691  /// Coerce the register to COP2 and return the real register for the
692  /// current target.
693  unsigned getCOP2Reg() const {
694  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
695  unsigned ClassID = Mips::COP2RegClassID;
696  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
697  }
698 
699  /// Coerce the register to COP3 and return the real register for the
700  /// current target.
701  unsigned getCOP3Reg() const {
702  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
703  unsigned ClassID = Mips::COP3RegClassID;
704  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
705  }
706 
707  /// Coerce the register to ACC64DSP and return the real register for the
708  /// current target.
709  unsigned getACC64DSPReg() const {
710  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
711  unsigned ClassID = Mips::ACC64DSPRegClassID;
712  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
713  }
714 
715  /// Coerce the register to HI32DSP and return the real register for the
716  /// current target.
717  unsigned getHI32DSPReg() const {
718  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
719  unsigned ClassID = Mips::HI32DSPRegClassID;
720  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
721  }
722 
723  /// Coerce the register to LO32DSP and return the real register for the
724  /// current target.
725  unsigned getLO32DSPReg() const {
726  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
727  unsigned ClassID = Mips::LO32DSPRegClassID;
728  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
729  }
730 
731  /// Coerce the register to CCR and return the real register for the
732  /// current target.
733  unsigned getCCRReg() const {
734  assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
735  unsigned ClassID = Mips::CCRRegClassID;
736  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
737  }
738 
739  /// Coerce the register to HWRegs and return the real register for the
740  /// current target.
741  unsigned getHWRegsReg() const {
742  assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
743  unsigned ClassID = Mips::HWRegsRegClassID;
744  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
745  }
746 
747 public:
748  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
749  // Add as immediate when possible. Null MCExpr = 0.
750  if (!Expr)
752  else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
753  Inst.addOperand(MCOperand::createImm(CE->getValue()));
754  else
755  Inst.addOperand(MCOperand::createExpr(Expr));
756  }
757 
758  void addRegOperands(MCInst &Inst, unsigned N) const {
759  llvm_unreachable("Use a custom parser instead");
760  }
761 
762  /// Render the operand to an MCInst as a GPR32
763  /// Asserts if the wrong number of operands are requested, or the operand
764  /// is not a k_RegisterIndex compatible with RegKind_GPR
765  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
766  assert(N == 1 && "Invalid number of operands!");
767  Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
768  }
769 
770  void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
771  assert(N == 1 && "Invalid number of operands!");
772  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
773  }
774 
775  void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
776  assert(N == 1 && "Invalid number of operands!");
777  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
778  }
779 
780  void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
781  assert(N == 1 && "Invalid number of operands!");
782  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
783  }
784 
785  /// Render the operand to an MCInst as a GPR64
786  /// Asserts if the wrong number of operands are requested, or the operand
787  /// is not a k_RegisterIndex compatible with RegKind_GPR
788  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
789  assert(N == 1 && "Invalid number of operands!");
790  Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
791  }
792 
793  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
794  assert(N == 1 && "Invalid number of operands!");
795  Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
796  }
797 
798  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
799  assert(N == 1 && "Invalid number of operands!");
800  Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
801  }
802 
803  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
804  assert(N == 1 && "Invalid number of operands!");
805  Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
806  // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
807  if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
808  AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
809  "registers");
810  }
811 
812  void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
813  assert(N == 1 && "Invalid number of operands!");
814  Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
815  }
816 
817  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
818  assert(N == 1 && "Invalid number of operands!");
819  Inst.addOperand(MCOperand::createReg(getFCCReg()));
820  }
821 
822  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
823  assert(N == 1 && "Invalid number of operands!");
824  Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
825  }
826 
827  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
828  assert(N == 1 && "Invalid number of operands!");
829  Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
830  }
831 
832  void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
833  assert(N == 1 && "Invalid number of operands!");
834  Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
835  }
836 
837  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
838  assert(N == 1 && "Invalid number of operands!");
839  Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
840  }
841 
842  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
843  assert(N == 1 && "Invalid number of operands!");
844  Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
845  }
846 
847  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
848  assert(N == 1 && "Invalid number of operands!");
849  Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
850  }
851 
852  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
853  assert(N == 1 && "Invalid number of operands!");
854  Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
855  }
856 
857  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
858  assert(N == 1 && "Invalid number of operands!");
859  Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
860  }
861 
862  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
863  assert(N == 1 && "Invalid number of operands!");
864  Inst.addOperand(MCOperand::createReg(getCCRReg()));
865  }
866 
867  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
868  assert(N == 1 && "Invalid number of operands!");
869  Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
870  }
871 
872  void addImmOperands(MCInst &Inst, unsigned N) const {
873  assert(N == 1 && "Invalid number of operands!");
874  const MCExpr *Expr = getImm();
875  addExpr(Inst, Expr);
876  }
877 
878  void addMemOperands(MCInst &Inst, unsigned N) const {
879  assert(N == 2 && "Invalid number of operands!");
880 
881  Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
882 
883  const MCExpr *Expr = getMemOff();
884  addExpr(Inst, Expr);
885  }
886 
887  void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
888  assert(N == 2 && "Invalid number of operands!");
889 
890  Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
891 
892  const MCExpr *Expr = getMemOff();
893  addExpr(Inst, Expr);
894  }
895 
896  void addRegListOperands(MCInst &Inst, unsigned N) const {
897  assert(N == 1 && "Invalid number of operands!");
898 
899  for (auto RegNo : getRegList())
900  Inst.addOperand(MCOperand::createReg(RegNo));
901  }
902 
903  void addRegPairOperands(MCInst &Inst, unsigned N) const {
904  assert(N == 2 && "Invalid number of operands!");
905  unsigned RegNo = getRegPair();
906  Inst.addOperand(MCOperand::createReg(RegNo++));
907  Inst.addOperand(MCOperand::createReg(RegNo));
908  }
909 
910  void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
911  assert(N == 2 && "Invalid number of operands!");
912  for (auto RegNo : getRegList())
913  Inst.addOperand(MCOperand::createReg(RegNo));
914  }
915 
916  bool isReg() const override {
917  // As a special case until we sort out the definition of div/divu, pretend
918  // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
919  if (isGPRAsmReg() && RegIdx.Index == 0)
920  return true;
921 
922  return Kind == k_PhysRegister;
923  }
924  bool isRegIdx() const { return Kind == k_RegisterIndex; }
925  bool isImm() const override { return Kind == k_Immediate; }
926  bool isConstantImm() const {
927  return isImm() && dyn_cast<MCConstantExpr>(getImm());
928  }
929  template <unsigned Bits> bool isUImm() const {
930  return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
931  }
932  bool isToken() const override {
933  // Note: It's not possible to pretend that other operand kinds are tokens.
934  // The matcher emitter checks tokens first.
935  return Kind == k_Token;
936  }
937  bool isMem() const override { return Kind == k_Memory; }
938  bool isConstantMemOff() const {
939  return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
940  }
941  template <unsigned Bits> bool isMemWithSimmOffset() const {
942  return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
943  }
944  bool isMemWithGRPMM16Base() const {
945  return isMem() && getMemBase()->isMM16AsmReg();
946  }
947  template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
948  return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
949  && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
950  }
951  template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
952  return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
953  && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
954  && (getMemBase()->getGPR32Reg() == Mips::SP);
955  }
956  bool isRegList16() const {
957  if (!isRegList())
958  return false;
959 
960  int Size = RegList.List->size();
961  if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
962  RegList.List->back() != Mips::RA)
963  return false;
964 
965  int PrevReg = *RegList.List->begin();
966  for (int i = 1; i < Size - 1; i++) {
967  int Reg = (*(RegList.List))[i];
968  if ( Reg != PrevReg + 1)
969  return false;
970  PrevReg = Reg;
971  }
972 
973  return true;
974  }
975  bool isInvNum() const { return Kind == k_Immediate; }
976  bool isLSAImm() const {
977  if (!isConstantImm())
978  return false;
979  int64_t Val = getConstantImm();
980  return 1 <= Val && Val <= 4;
981  }
982  bool isRegList() const { return Kind == k_RegList; }
983  bool isMovePRegPair() const {
984  if (Kind != k_RegList || RegList.List->size() != 2)
985  return false;
986 
987  unsigned R0 = RegList.List->front();
988  unsigned R1 = RegList.List->back();
989 
990  if ((R0 == Mips::A1 && R1 == Mips::A2) ||
991  (R0 == Mips::A1 && R1 == Mips::A3) ||
992  (R0 == Mips::A2 && R1 == Mips::A3) ||
993  (R0 == Mips::A0 && R1 == Mips::S5) ||
994  (R0 == Mips::A0 && R1 == Mips::S6) ||
995  (R0 == Mips::A0 && R1 == Mips::A1) ||
996  (R0 == Mips::A0 && R1 == Mips::A2) ||
997  (R0 == Mips::A0 && R1 == Mips::A3))
998  return true;
999 
1000  return false;
1001  }
1002 
1003  StringRef getToken() const {
1004  assert(Kind == k_Token && "Invalid access!");
1005  return StringRef(Tok.Data, Tok.Length);
1006  }
1007  bool isRegPair() const { return Kind == k_RegPair; }
1008 
1009  unsigned getReg() const override {
1010  // As a special case until we sort out the definition of div/divu, pretend
1011  // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1012  if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1013  RegIdx.Kind & RegKind_GPR)
1014  return getGPR32Reg(); // FIXME: GPR64 too
1015 
1016  assert(Kind == k_PhysRegister && "Invalid access!");
1017  return PhysReg.Num;
1018  }
1019 
1020  const MCExpr *getImm() const {
1021  assert((Kind == k_Immediate) && "Invalid access!");
1022  return Imm.Val;
1023  }
1024 
1025  int64_t getConstantImm() const {
1026  const MCExpr *Val = getImm();
1027  return static_cast<const MCConstantExpr *>(Val)->getValue();
1028  }
1029 
1030  MipsOperand *getMemBase() const {
1031  assert((Kind == k_Memory) && "Invalid access!");
1032  return Mem.Base;
1033  }
1034 
1035  const MCExpr *getMemOff() const {
1036  assert((Kind == k_Memory) && "Invalid access!");
1037  return Mem.Off;
1038  }
1039 
1040  int64_t getConstantMemOff() const {
1041  return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1042  }
1043 
1044  const SmallVectorImpl<unsigned> &getRegList() const {
1045  assert((Kind == k_RegList) && "Invalid access!");
1046  return *(RegList.List);
1047  }
1048 
1049  unsigned getRegPair() const {
1050  assert((Kind == k_RegPair) && "Invalid access!");
1051  return RegIdx.Index;
1052  }
1053 
1054  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1055  MipsAsmParser &Parser) {
1056  auto Op = make_unique<MipsOperand>(k_Token, Parser);
1057  Op->Tok.Data = Str.data();
1058  Op->Tok.Length = Str.size();
1059  Op->StartLoc = S;
1060  Op->EndLoc = S;
1061  return Op;
1062  }
1063 
1064  /// Create a numeric register (e.g. $1). The exact register remains
1065  /// unresolved until an instruction successfully matches
1066  static std::unique_ptr<MipsOperand>
1067  createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1068  SMLoc E, MipsAsmParser &Parser) {
1069  DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1070  return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1071  }
1072 
1073  /// Create a register that is definitely a GPR.
1074  /// This is typically only used for named registers such as $gp.
1075  static std::unique_ptr<MipsOperand>
1076  createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1077  MipsAsmParser &Parser) {
1078  return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1079  }
1080 
1081  /// Create a register that is definitely a FGR.
1082  /// This is typically only used for named registers such as $f0.
1083  static std::unique_ptr<MipsOperand>
1084  createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1085  MipsAsmParser &Parser) {
1086  return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1087  }
1088 
1089  /// Create a register that is definitely a HWReg.
1090  /// This is typically only used for named registers such as $hwr_cpunum.
1091  static std::unique_ptr<MipsOperand>
1092  createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1093  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1094  return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1095  }
1096 
1097  /// Create a register that is definitely an FCC.
1098  /// This is typically only used for named registers such as $fcc0.
1099  static std::unique_ptr<MipsOperand>
1100  createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1101  MipsAsmParser &Parser) {
1102  return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1103  }
1104 
1105  /// Create a register that is definitely an ACC.
1106  /// This is typically only used for named registers such as $ac0.
1107  static std::unique_ptr<MipsOperand>
1108  createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1109  MipsAsmParser &Parser) {
1110  return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1111  }
1112 
1113  /// Create a register that is definitely an MSA128.
1114  /// This is typically only used for named registers such as $w0.
1115  static std::unique_ptr<MipsOperand>
1116  createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1117  SMLoc E, MipsAsmParser &Parser) {
1118  return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1119  }
1120 
1121  /// Create a register that is definitely an MSACtrl.
1122  /// This is typically only used for named registers such as $msaaccess.
1123  static std::unique_ptr<MipsOperand>
1124  createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1125  SMLoc E, MipsAsmParser &Parser) {
1126  return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1127  }
1128 
1129  static std::unique_ptr<MipsOperand>
1130  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1131  auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1132  Op->Imm.Val = Val;
1133  Op->StartLoc = S;
1134  Op->EndLoc = E;
1135  return Op;
1136  }
1137 
1138  static std::unique_ptr<MipsOperand>
1139  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1140  SMLoc E, MipsAsmParser &Parser) {
1141  auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1142  Op->Mem.Base = Base.release();
1143  Op->Mem.Off = Off;
1144  Op->StartLoc = S;
1145  Op->EndLoc = E;
1146  return Op;
1147  }
1148 
1149  static std::unique_ptr<MipsOperand>
1150  CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1151  MipsAsmParser &Parser) {
1152  assert (Regs.size() > 0 && "Empty list not allowed");
1153 
1154  auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1155  Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1156  Op->StartLoc = StartLoc;
1157  Op->EndLoc = EndLoc;
1158  return Op;
1159  }
1160 
1161  static std::unique_ptr<MipsOperand>
1162  CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1163  auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1164  Op->RegIdx.Index = RegNo;
1165  Op->StartLoc = S;
1166  Op->EndLoc = E;
1167  return Op;
1168  }
1169 
1170  bool isGPRAsmReg() const {
1171  return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1172  }
1173  bool isMM16AsmReg() const {
1174  if (!(isRegIdx() && RegIdx.Kind))
1175  return false;
1176  return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1177  || RegIdx.Index == 16 || RegIdx.Index == 17);
1178  }
1179  bool isMM16AsmRegZero() const {
1180  if (!(isRegIdx() && RegIdx.Kind))
1181  return false;
1182  return (RegIdx.Index == 0 ||
1183  (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1184  RegIdx.Index == 17);
1185  }
1186  bool isMM16AsmRegMoveP() const {
1187  if (!(isRegIdx() && RegIdx.Kind))
1188  return false;
1189  return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1190  (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1191  }
1192  bool isFGRAsmReg() const {
1193  // AFGR64 is $0-$15 but we handle this in getAFGR64()
1194  return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1195  }
1196  bool isHWRegsAsmReg() const {
1197  return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1198  }
1199  bool isCCRAsmReg() const {
1200  return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1201  }
1202  bool isFCCAsmReg() const {
1203  if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1204  return false;
1205  if (!AsmParser.hasEightFccRegisters())
1206  return RegIdx.Index == 0;
1207  return RegIdx.Index <= 7;
1208  }
1209  bool isACCAsmReg() const {
1210  return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1211  }
1212  bool isCOP0AsmReg() const {
1213  return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1214  }
1215  bool isCOP2AsmReg() const {
1216  return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1217  }
1218  bool isCOP3AsmReg() const {
1219  return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1220  }
1221  bool isMSA128AsmReg() const {
1222  return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1223  }
1224  bool isMSACtrlAsmReg() const {
1225  return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1226  }
1227 
1228  /// getStartLoc - Get the location of the first token of this operand.
1229  SMLoc getStartLoc() const override { return StartLoc; }
1230  /// getEndLoc - Get the location of the last token of this operand.
1231  SMLoc getEndLoc() const override { return EndLoc; }
1232 
1233  virtual ~MipsOperand() {
1234  switch (Kind) {
1235  case k_Immediate:
1236  break;
1237  case k_Memory:
1238  delete Mem.Base;
1239  break;
1240  case k_RegList:
1241  delete RegList.List;
1242  case k_PhysRegister:
1243  case k_RegisterIndex:
1244  case k_Token:
1245  case k_RegPair:
1246  break;
1247  }
1248  }
1249 
1250  void print(raw_ostream &OS) const override {
1251  switch (Kind) {
1252  case k_Immediate:
1253  OS << "Imm<";
1254  OS << *Imm.Val;
1255  OS << ">";
1256  break;
1257  case k_Memory:
1258  OS << "Mem<";
1259  Mem.Base->print(OS);
1260  OS << ", ";
1261  OS << *Mem.Off;
1262  OS << ">";
1263  break;
1264  case k_PhysRegister:
1265  OS << "PhysReg<" << PhysReg.Num << ">";
1266  break;
1267  case k_RegisterIndex:
1268  OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1269  break;
1270  case k_Token:
1271  OS << Tok.Data;
1272  break;
1273  case k_RegList:
1274  OS << "RegList< ";
1275  for (auto Reg : (*RegList.List))
1276  OS << Reg << " ";
1277  OS << ">";
1278  break;
1279  case k_RegPair:
1280  OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1281  break;
1282  }
1283  }
1284 }; // class MipsOperand
1285 } // namespace
1286 
1287 namespace llvm {
1288 extern const MCInstrDesc MipsInsts[];
1289 }
1290 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1291  return MipsInsts[Opcode];
1292 }
1293 
1294 static bool hasShortDelaySlot(unsigned Opcode) {
1295  switch (Opcode) {
1296  case Mips::JALS_MM:
1297  case Mips::JALRS_MM:
1298  case Mips::JALRS16_MM:
1299  case Mips::BGEZALS_MM:
1300  case Mips::BLTZALS_MM:
1301  return true;
1302  default:
1303  return false;
1304  }
1305 }
1306 
1308  SmallVectorImpl<MCInst> &Instructions) {
1309  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1310 
1311  Inst.setLoc(IDLoc);
1312 
1313  if (MCID.isBranch() || MCID.isCall()) {
1314  const unsigned Opcode = Inst.getOpcode();
1315  MCOperand Offset;
1316 
1317  switch (Opcode) {
1318  default:
1319  break;
1320  case Mips::BBIT0:
1321  case Mips::BBIT032:
1322  case Mips::BBIT1:
1323  case Mips::BBIT132:
1324  assert(hasCnMips() && "instruction only valid for octeon cpus");
1325  // Fall through
1326 
1327  case Mips::BEQ:
1328  case Mips::BNE:
1329  case Mips::BEQ_MM:
1330  case Mips::BNE_MM:
1331  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1332  Offset = Inst.getOperand(2);
1333  if (!Offset.isImm())
1334  break; // We'll deal with this situation later on when applying fixups.
1335  if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1336  return Error(IDLoc, "branch target out of range");
1337  if (OffsetToAlignment(Offset.getImm(),
1338  1LL << (inMicroMipsMode() ? 1 : 2)))
1339  return Error(IDLoc, "branch to misaligned address");
1340  break;
1341  case Mips::BGEZ:
1342  case Mips::BGTZ:
1343  case Mips::BLEZ:
1344  case Mips::BLTZ:
1345  case Mips::BGEZAL:
1346  case Mips::BLTZAL:
1347  case Mips::BC1F:
1348  case Mips::BC1T:
1349  case Mips::BGEZ_MM:
1350  case Mips::BGTZ_MM:
1351  case Mips::BLEZ_MM:
1352  case Mips::BLTZ_MM:
1353  case Mips::BGEZAL_MM:
1354  case Mips::BLTZAL_MM:
1355  case Mips::BC1F_MM:
1356  case Mips::BC1T_MM:
1357  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1358  Offset = Inst.getOperand(1);
1359  if (!Offset.isImm())
1360  break; // We'll deal with this situation later on when applying fixups.
1361  if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1362  return Error(IDLoc, "branch target out of range");
1363  if (OffsetToAlignment(Offset.getImm(),
1364  1LL << (inMicroMipsMode() ? 1 : 2)))
1365  return Error(IDLoc, "branch to misaligned address");
1366  break;
1367  case Mips::BEQZ16_MM:
1368  case Mips::BNEZ16_MM:
1369  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1370  Offset = Inst.getOperand(1);
1371  if (!Offset.isImm())
1372  break; // We'll deal with this situation later on when applying fixups.
1373  if (!isIntN(8, Offset.getImm()))
1374  return Error(IDLoc, "branch target out of range");
1375  if (OffsetToAlignment(Offset.getImm(), 2LL))
1376  return Error(IDLoc, "branch to misaligned address");
1377  break;
1378  }
1379  }
1380 
1381  // SSNOP is deprecated on MIPS32r6/MIPS64r6
1382  // We still accept it but it is a normal nop.
1383  if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1384  std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1385  Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1386  "nop instruction");
1387  }
1388 
1389  if (hasCnMips()) {
1390  const unsigned Opcode = Inst.getOpcode();
1391  MCOperand Opnd;
1392  int Imm;
1393 
1394  switch (Opcode) {
1395  default:
1396  break;
1397 
1398  case Mips::BBIT0:
1399  case Mips::BBIT032:
1400  case Mips::BBIT1:
1401  case Mips::BBIT132:
1402  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1403  // The offset is handled above
1404  Opnd = Inst.getOperand(1);
1405  if (!Opnd.isImm())
1406  return Error(IDLoc, "expected immediate operand kind");
1407  Imm = Opnd.getImm();
1408  if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1409  Opcode == Mips::BBIT1 ? 63 : 31))
1410  return Error(IDLoc, "immediate operand value out of range");
1411  if (Imm > 31) {
1412  Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1413  : Mips::BBIT132);
1414  Inst.getOperand(1).setImm(Imm - 32);
1415  }
1416  break;
1417 
1418  case Mips::CINS:
1419  case Mips::CINS32:
1420  case Mips::EXTS:
1421  case Mips::EXTS32:
1422  assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1423  // Check length
1424  Opnd = Inst.getOperand(3);
1425  if (!Opnd.isImm())
1426  return Error(IDLoc, "expected immediate operand kind");
1427  Imm = Opnd.getImm();
1428  if (Imm < 0 || Imm > 31)
1429  return Error(IDLoc, "immediate operand value out of range");
1430  // Check position
1431  Opnd = Inst.getOperand(2);
1432  if (!Opnd.isImm())
1433  return Error(IDLoc, "expected immediate operand kind");
1434  Imm = Opnd.getImm();
1435  if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1436  Opcode == Mips::EXTS ? 63 : 31))
1437  return Error(IDLoc, "immediate operand value out of range");
1438  if (Imm > 31) {
1439  Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1440  Inst.getOperand(2).setImm(Imm - 32);
1441  }
1442  break;
1443 
1444  case Mips::SEQi:
1445  case Mips::SNEi:
1446  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1447  Opnd = Inst.getOperand(2);
1448  if (!Opnd.isImm())
1449  return Error(IDLoc, "expected immediate operand kind");
1450  Imm = Opnd.getImm();
1451  if (!isInt<10>(Imm))
1452  return Error(IDLoc, "immediate operand value out of range");
1453  break;
1454  }
1455  }
1456 
1457  if (MCID.mayLoad() || MCID.mayStore()) {
1458  // Check the offset of memory operand, if it is a symbol
1459  // reference or immediate we may have to expand instructions.
1460  for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1461  const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1462  if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1463  (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1464  MCOperand &Op = Inst.getOperand(i);
1465  if (Op.isImm()) {
1466  int MemOffset = Op.getImm();
1467  if (MemOffset < -32768 || MemOffset > 32767) {
1468  // Offset can't exceed 16bit value.
1469  expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1470  return false;
1471  }
1472  } else if (Op.isExpr()) {
1473  const MCExpr *Expr = Op.getExpr();
1474  if (Expr->getKind() == MCExpr::SymbolRef) {
1475  const MCSymbolRefExpr *SR =
1476  static_cast<const MCSymbolRefExpr *>(Expr);
1477  if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1478  // Expand symbol.
1479  expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1480  return false;
1481  }
1482  } else if (!isEvaluated(Expr)) {
1483  expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1484  return false;
1485  }
1486  }
1487  }
1488  } // for
1489  } // if load/store
1490 
1491  if (inMicroMipsMode()) {
1492  if (MCID.mayLoad()) {
1493  // Try to create 16-bit GP relative load instruction.
1494  for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1495  const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1496  if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1497  (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1498  MCOperand &Op = Inst.getOperand(i);
1499  if (Op.isImm()) {
1500  int MemOffset = Op.getImm();
1501  MCOperand &DstReg = Inst.getOperand(0);
1502  MCOperand &BaseReg = Inst.getOperand(1);
1503  if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1504  getContext().getRegisterInfo()->getRegClass(
1505  Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1506  BaseReg.getReg() == Mips::GP) {
1507  MCInst TmpInst;
1508  TmpInst.setLoc(IDLoc);
1509  TmpInst.setOpcode(Mips::LWGP_MM);
1510  TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1511  TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1512  TmpInst.addOperand(MCOperand::createImm(MemOffset));
1513  Instructions.push_back(TmpInst);
1514  return false;
1515  }
1516  }
1517  }
1518  } // for
1519  } // if load
1520 
1521  // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1522 
1523  MCOperand Opnd;
1524  int Imm;
1525 
1526  switch (Inst.getOpcode()) {
1527  default:
1528  break;
1529  case Mips::ADDIUS5_MM:
1530  Opnd = Inst.getOperand(2);
1531  if (!Opnd.isImm())
1532  return Error(IDLoc, "expected immediate operand kind");
1533  Imm = Opnd.getImm();
1534  if (Imm < -8 || Imm > 7)
1535  return Error(IDLoc, "immediate operand value out of range");
1536  break;
1537  case Mips::ADDIUSP_MM:
1538  Opnd = Inst.getOperand(0);
1539  if (!Opnd.isImm())
1540  return Error(IDLoc, "expected immediate operand kind");
1541  Imm = Opnd.getImm();
1542  if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1543  Imm % 4 != 0)
1544  return Error(IDLoc, "immediate operand value out of range");
1545  break;
1546  case Mips::SLL16_MM:
1547  case Mips::SRL16_MM:
1548  Opnd = Inst.getOperand(2);
1549  if (!Opnd.isImm())
1550  return Error(IDLoc, "expected immediate operand kind");
1551  Imm = Opnd.getImm();
1552  if (Imm < 1 || Imm > 8)
1553  return Error(IDLoc, "immediate operand value out of range");
1554  break;
1555  case Mips::LI16_MM:
1556  Opnd = Inst.getOperand(1);
1557  if (!Opnd.isImm())
1558  return Error(IDLoc, "expected immediate operand kind");
1559  Imm = Opnd.getImm();
1560  if (Imm < -1 || Imm > 126)
1561  return Error(IDLoc, "immediate operand value out of range");
1562  break;
1563  case Mips::ADDIUR2_MM:
1564  Opnd = Inst.getOperand(2);
1565  if (!Opnd.isImm())
1566  return Error(IDLoc, "expected immediate operand kind");
1567  Imm = Opnd.getImm();
1568  if (!(Imm == 1 || Imm == -1 ||
1569  ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1570  return Error(IDLoc, "immediate operand value out of range");
1571  break;
1572  case Mips::ADDIUR1SP_MM:
1573  Opnd = Inst.getOperand(1);
1574  if (!Opnd.isImm())
1575  return Error(IDLoc, "expected immediate operand kind");
1576  Imm = Opnd.getImm();
1577  if (OffsetToAlignment(Imm, 4LL))
1578  return Error(IDLoc, "misaligned immediate operand value");
1579  if (Imm < 0 || Imm > 255)
1580  return Error(IDLoc, "immediate operand value out of range");
1581  break;
1582  case Mips::ANDI16_MM:
1583  Opnd = Inst.getOperand(2);
1584  if (!Opnd.isImm())
1585  return Error(IDLoc, "expected immediate operand kind");
1586  Imm = Opnd.getImm();
1587  if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1588  Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1589  Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1590  return Error(IDLoc, "immediate operand value out of range");
1591  break;
1592  case Mips::LBU16_MM:
1593  Opnd = Inst.getOperand(2);
1594  if (!Opnd.isImm())
1595  return Error(IDLoc, "expected immediate operand kind");
1596  Imm = Opnd.getImm();
1597  if (Imm < -1 || Imm > 14)
1598  return Error(IDLoc, "immediate operand value out of range");
1599  break;
1600  case Mips::SB16_MM:
1601  Opnd = Inst.getOperand(2);
1602  if (!Opnd.isImm())
1603  return Error(IDLoc, "expected immediate operand kind");
1604  Imm = Opnd.getImm();
1605  if (Imm < 0 || Imm > 15)
1606  return Error(IDLoc, "immediate operand value out of range");
1607  break;
1608  case Mips::LHU16_MM:
1609  case Mips::SH16_MM:
1610  Opnd = Inst.getOperand(2);
1611  if (!Opnd.isImm())
1612  return Error(IDLoc, "expected immediate operand kind");
1613  Imm = Opnd.getImm();
1614  if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1615  return Error(IDLoc, "immediate operand value out of range");
1616  break;
1617  case Mips::LW16_MM:
1618  case Mips::SW16_MM:
1619  Opnd = Inst.getOperand(2);
1620  if (!Opnd.isImm())
1621  return Error(IDLoc, "expected immediate operand kind");
1622  Imm = Opnd.getImm();
1623  if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1624  return Error(IDLoc, "immediate operand value out of range");
1625  break;
1626  case Mips::CACHE:
1627  case Mips::PREF:
1628  Opnd = Inst.getOperand(2);
1629  if (!Opnd.isImm())
1630  return Error(IDLoc, "expected immediate operand kind");
1631  Imm = Opnd.getImm();
1632  if (!isUInt<5>(Imm))
1633  return Error(IDLoc, "immediate operand value out of range");
1634  break;
1635  case Mips::ADDIUPC_MM:
1636  MCOperand Opnd = Inst.getOperand(1);
1637  if (!Opnd.isImm())
1638  return Error(IDLoc, "expected immediate operand kind");
1639  int Imm = Opnd.getImm();
1640  if ((Imm % 4 != 0) || !isIntN(25, Imm))
1641  return Error(IDLoc, "immediate operand value out of range");
1642  break;
1643  }
1644  }
1645 
1646  if (needsExpansion(Inst)) {
1647  if (expandInstruction(Inst, IDLoc, Instructions))
1648  return true;
1649  } else
1650  Instructions.push_back(Inst);
1651 
1652  // If this instruction has a delay slot and .set reorder is active,
1653  // emit a NOP after it.
1654  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1655  createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1656 
1657  return false;
1658 }
1659 
1660 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1661 
1662  switch (Inst.getOpcode()) {
1663  case Mips::LoadImm32:
1664  case Mips::LoadImm64:
1665  case Mips::LoadAddrImm32:
1666  case Mips::LoadAddrReg32:
1667  case Mips::B_MM_Pseudo:
1668  case Mips::LWM_MM:
1669  case Mips::SWM_MM:
1670  case Mips::JalOneReg:
1671  case Mips::JalTwoReg:
1672  case Mips::BneImm:
1673  case Mips::BeqImm:
1674  case Mips::BLT:
1675  case Mips::BLE:
1676  case Mips::BGE:
1677  case Mips::BGT:
1678  case Mips::BLTU:
1679  case Mips::BLEU:
1680  case Mips::BGEU:
1681  case Mips::BGTU:
1682  case Mips::Ulhu:
1683  case Mips::Ulw:
1684  return true;
1685  default:
1686  return false;
1687  }
1688 }
1689 
1690 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1691  SmallVectorImpl<MCInst> &Instructions) {
1692  switch (Inst.getOpcode()) {
1693  default: llvm_unreachable("unimplemented expansion");
1694  case Mips::LoadImm32:
1695  return expandLoadImm(Inst, true, IDLoc, Instructions);
1696  case Mips::LoadImm64:
1697  return expandLoadImm(Inst, false, IDLoc, Instructions);
1698  case Mips::LoadAddrImm32:
1699  return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1700  case Mips::LoadAddrReg32:
1701  return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1702  case Mips::B_MM_Pseudo:
1703  return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1704  case Mips::SWM_MM:
1705  case Mips::LWM_MM:
1706  return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1707  case Mips::JalOneReg:
1708  case Mips::JalTwoReg:
1709  return expandJalWithRegs(Inst, IDLoc, Instructions);
1710  case Mips::BneImm:
1711  case Mips::BeqImm:
1712  return expandBranchImm(Inst, IDLoc, Instructions);
1713  case Mips::BLT:
1714  case Mips::BLE:
1715  case Mips::BGE:
1716  case Mips::BGT:
1717  case Mips::BLTU:
1718  case Mips::BLEU:
1719  case Mips::BGEU:
1720  case Mips::BGTU:
1721  return expandCondBranches(Inst, IDLoc, Instructions);
1722  case Mips::Ulhu:
1723  return expandUlhu(Inst, IDLoc, Instructions);
1724  case Mips::Ulw:
1725  return expandUlw(Inst, IDLoc, Instructions);
1726  }
1727 }
1728 
1729 namespace {
1730 void emitRX(unsigned Opcode, unsigned DstReg, MCOperand Imm, SMLoc IDLoc,
1731  SmallVectorImpl<MCInst> &Instructions) {
1732  MCInst tmpInst;
1733  tmpInst.setOpcode(Opcode);
1734  tmpInst.addOperand(MCOperand::createReg(DstReg));
1735  tmpInst.addOperand(Imm);
1736  tmpInst.setLoc(IDLoc);
1737  Instructions.push_back(tmpInst);
1738 }
1739 
1740 void emitRI(unsigned Opcode, unsigned DstReg, int16_t Imm, SMLoc IDLoc,
1741  SmallVectorImpl<MCInst> &Instructions) {
1742  emitRX(Opcode, DstReg, MCOperand::createImm(Imm), IDLoc, Instructions);
1743 }
1744 
1745 
1746 void emitRRX(unsigned Opcode, unsigned DstReg, unsigned SrcReg, MCOperand Imm,
1747  SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1748  MCInst tmpInst;
1749  tmpInst.setOpcode(Opcode);
1750  tmpInst.addOperand(MCOperand::createReg(DstReg));
1751  tmpInst.addOperand(MCOperand::createReg(SrcReg));
1752  tmpInst.addOperand(Imm);
1753  tmpInst.setLoc(IDLoc);
1754  Instructions.push_back(tmpInst);
1755 }
1756 
1757 void emitRRR(unsigned Opcode, unsigned DstReg, unsigned SrcReg,
1758  unsigned SrcReg2, SMLoc IDLoc,
1759  SmallVectorImpl<MCInst> &Instructions) {
1760  emitRRX(Opcode, DstReg, SrcReg, MCOperand::createReg(SrcReg2), IDLoc,
1761  Instructions);
1762 }
1763 
1764 void emitRRI(unsigned Opcode, unsigned DstReg, unsigned SrcReg, int16_t Imm,
1765  SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1766  emitRRX(Opcode, DstReg, SrcReg, MCOperand::createImm(Imm), IDLoc,
1767  Instructions);
1768 }
1769 
1770 template <int16_t ShiftAmount>
1771 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1772  SmallVectorImpl<MCInst> &Instructions) {
1773  if (ShiftAmount >= 32)
1774  emitRRI(Mips::DSLL32, RegNo, RegNo, ShiftAmount - 32, IDLoc, Instructions);
1775  else if (ShiftAmount > 0)
1776  emitRRI(Mips::DSLL, RegNo, RegNo, ShiftAmount, IDLoc, Instructions);
1777 
1778  // There's no need for an ORi if the immediate is 0.
1779  if (Operand.isImm() && Operand.getImm() == 0)
1780  return;
1781 
1782  emitRRX(Mips::ORi, RegNo, RegNo, Operand, IDLoc, Instructions);
1783 }
1784 
1785 template <unsigned ShiftAmount>
1786 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1787  SmallVectorImpl<MCInst> &Instructions) {
1788  createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1789  Instructions);
1790 }
1791 }
1792 
1793 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1794  SmallVectorImpl<MCInst> &Instructions) {
1795  // Create a JALR instruction which is going to replace the pseudo-JAL.
1796  MCInst JalrInst;
1797  JalrInst.setLoc(IDLoc);
1798  const MCOperand FirstRegOp = Inst.getOperand(0);
1799  const unsigned Opcode = Inst.getOpcode();
1800 
1801  if (Opcode == Mips::JalOneReg) {
1802  // jal $rs => jalr $rs
1803  if (inMicroMipsMode()) {
1804  JalrInst.setOpcode(Mips::JALR16_MM);
1805  JalrInst.addOperand(FirstRegOp);
1806  } else {
1807  JalrInst.setOpcode(Mips::JALR);
1808  JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1809  JalrInst.addOperand(FirstRegOp);
1810  }
1811  } else if (Opcode == Mips::JalTwoReg) {
1812  // jal $rd, $rs => jalr $rd, $rs
1813  JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1814  JalrInst.addOperand(FirstRegOp);
1815  const MCOperand SecondRegOp = Inst.getOperand(1);
1816  JalrInst.addOperand(SecondRegOp);
1817  }
1818  Instructions.push_back(JalrInst);
1819 
1820  // If .set reorder is active, emit a NOP after it.
1821  if (AssemblerOptions.back()->isReorder()) {
1822  // This is a 32-bit NOP because these 2 pseudo-instructions
1823  // do not have a short delay slot.
1824  MCInst NopInst;
1825  NopInst.setOpcode(Mips::SLL);
1826  NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1827  NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1828  NopInst.addOperand(MCOperand::createImm(0));
1829  Instructions.push_back(NopInst);
1830  }
1831 
1832  return false;
1833 }
1834 
1835 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1836  unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1837  SmallVectorImpl<MCInst> &Instructions) {
1838  if (!Is32BitImm && !isGP64bit()) {
1839  Error(IDLoc, "instruction requires a 64-bit architecture");
1840  return true;
1841  }
1842 
1843  if (Is32BitImm) {
1844  if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1845  // Sign extend up to 64-bit so that the predicates match the hardware
1846  // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
1847  // true.
1848  ImmValue = SignExtend64<32>(ImmValue);
1849  } else {
1850  Error(IDLoc, "instruction requires a 32-bit immediate");
1851  return true;
1852  }
1853  }
1854 
1855  bool UseSrcReg = false;
1856  if (SrcReg != Mips::NoRegister)
1857  UseSrcReg = true;
1858 
1859  unsigned TmpReg = DstReg;
1860  if (UseSrcReg && (DstReg == SrcReg)) {
1861  // At this point we need AT to perform the expansions and we exit if it is
1862  // not available.
1863  unsigned ATReg = getATReg(IDLoc);
1864  if (!ATReg)
1865  return true;
1866  TmpReg = ATReg;
1867  }
1868 
1869  // FIXME: gas has a special case for values that are 000...1111, which
1870  // becomes a li -1 and then a dsrl
1871  if (isInt<16>(ImmValue)) {
1872  // li d,j => addiu d,$zero,j
1873  if (!UseSrcReg)
1874  SrcReg = Mips::ZERO;
1875  emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1876  } else if (isUInt<16>(ImmValue)) {
1877  // li d,j => ori d,$zero,j
1878  unsigned TmpReg = DstReg;
1879  if (SrcReg == DstReg) {
1880  unsigned ATReg = getATReg(IDLoc);
1881  if (!ATReg)
1882  return true;
1883  TmpReg = ATReg;
1884  }
1885 
1886  emitRRI(Mips::ORi, TmpReg, Mips::ZERO, ImmValue, IDLoc, Instructions);
1887  if (UseSrcReg)
1888  emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1889  } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1890  warnIfNoMacro(IDLoc);
1891 
1892  // For all other values which are representable as a 32-bit integer:
1893  // li d,j => lui d,hi16(j)
1894  // ori d,d,lo16(j)
1895  uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1896  uint16_t Bits15To0 = ImmValue & 0xffff;
1897 
1898  if (!Is32BitImm && !isInt<32>(ImmValue)) {
1899  // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1900  // upper 32 bits.
1901  emitRRI(Mips::ORi, TmpReg, Mips::ZERO, Bits31To16, IDLoc, Instructions);
1902  emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
1903  } else
1904  emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
1905  createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1906 
1907  if (UseSrcReg)
1908  createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1909 
1910  } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1911  warnIfNoMacro(IDLoc);
1912 
1913  // <------- lo32 ------>
1914  // <------- hi32 ------>
1915  // <- hi16 -> <- lo16 ->
1916  // _________________________________
1917  // | | | |
1918  // | 16-bits | 16-bits | 16-bits |
1919  // |__________|__________|__________|
1920  //
1921  // For any 64-bit value that is representable as a 48-bit integer:
1922  // li d,j => lui d,hi16(j)
1923  // ori d,d,hi16(lo32(j))
1924  // dsll d,d,16
1925  // ori d,d,lo16(lo32(j))
1926  uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1927  uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1928  uint16_t Bits15To0 = ImmValue & 0xffff;
1929 
1930  emitRI(Mips::LUi, TmpReg, Bits47To32, IDLoc, Instructions);
1931  createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1932  createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1933 
1934  if (UseSrcReg)
1935  createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1936 
1937  } else {
1938  warnIfNoMacro(IDLoc);
1939 
1940  // <------- hi32 ------> <------- lo32 ------>
1941  // <- hi16 -> <- lo16 ->
1942  // ___________________________________________
1943  // | | | | |
1944  // | 16-bits | 16-bits | 16-bits | 16-bits |
1945  // |__________|__________|__________|__________|
1946  //
1947  // For all other values which are representable as a 64-bit integer:
1948  // li d,j => lui d,hi16(j)
1949  // ori d,d,lo16(hi32(j))
1950  // dsll d,d,16
1951  // ori d,d,hi16(lo32(j))
1952  // dsll d,d,16
1953  // ori d,d,lo16(lo32(j))
1954  uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1955  uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1956  uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1957  uint16_t Bits15To0 = ImmValue & 0xffff;
1958 
1959  emitRI(Mips::LUi, TmpReg, Bits63To48, IDLoc, Instructions);
1960  createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1961 
1962  // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1963  // two left shifts of 16 bits.
1964  if (Bits31To16 == 0) {
1965  createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1966  } else {
1967  createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1968  createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1969  }
1970 
1971  if (UseSrcReg)
1972  createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1973  }
1974  return false;
1975 }
1976 
1977 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1978  SmallVectorImpl<MCInst> &Instructions) {
1979  const MCOperand &ImmOp = Inst.getOperand(1);
1980  assert(ImmOp.isImm() && "expected immediate operand kind");
1981  const MCOperand &DstRegOp = Inst.getOperand(0);
1982  assert(DstRegOp.isReg() && "expected register operand kind");
1983 
1984  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1985  Is32BitImm, IDLoc, Instructions))
1986  return true;
1987 
1988  return false;
1989 }
1990 
1991 bool
1992 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1993  SmallVectorImpl<MCInst> &Instructions) {
1994  const MCOperand &DstRegOp = Inst.getOperand(0);
1995  assert(DstRegOp.isReg() && "expected register operand kind");
1996 
1997  const MCOperand &SrcRegOp = Inst.getOperand(1);
1998  assert(SrcRegOp.isReg() && "expected register operand kind");
1999 
2000  const MCOperand &ImmOp = Inst.getOperand(2);
2001  assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2002  "expected immediate operand kind");
2003  if (!ImmOp.isImm()) {
2004  if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2005  SrcRegOp.getReg(), Is32BitImm, IDLoc,
2006  Instructions))
2007  return true;
2008 
2009  return false;
2010  }
2011 
2012  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
2013  Is32BitImm, IDLoc, Instructions))
2014  return true;
2015 
2016  return false;
2017 }
2018 
2019 bool
2020 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2021  SmallVectorImpl<MCInst> &Instructions) {
2022  const MCOperand &DstRegOp = Inst.getOperand(0);
2023  assert(DstRegOp.isReg() && "expected register operand kind");
2024 
2025  const MCOperand &ImmOp = Inst.getOperand(1);
2026  assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2027  "expected immediate operand kind");
2028  if (!ImmOp.isImm()) {
2029  if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2030  Mips::NoRegister, Is32BitImm, IDLoc,
2031  Instructions))
2032  return true;
2033 
2034  return false;
2035  }
2036 
2037  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2038  Is32BitImm, IDLoc, Instructions))
2039  return true;
2040 
2041  return false;
2042 }
2043 
2044 bool MipsAsmParser::loadAndAddSymbolAddress(
2045  const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2046  SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2047  warnIfNoMacro(IDLoc);
2048 
2049  if (Is32BitSym && isABI_N64())
2050  Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
2051 
2052  MCInst tmpInst;
2053  const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2054  const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2055  &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2056  const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2057  &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2058 
2059  bool UseSrcReg = SrcReg != Mips::NoRegister;
2060 
2061  unsigned TmpReg = DstReg;
2062  if (UseSrcReg && (DstReg == SrcReg)) {
2063  // At this point we need AT to perform the expansions and we exit if it is
2064  // not available.
2065  unsigned ATReg = getATReg(IDLoc);
2066  if (!ATReg)
2067  return true;
2068  TmpReg = ATReg;
2069  }
2070 
2071  if (!Is32BitSym) {
2072  // If it's a 64-bit architecture, expand to:
2073  // la d,sym => lui d,highest(sym)
2074  // ori d,d,higher(sym)
2075  // dsll d,d,16
2076  // ori d,d,hi16(sym)
2077  // dsll d,d,16
2078  // ori d,d,lo16(sym)
2079  const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2080  &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2081  const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2082  &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2083 
2084  tmpInst.setOpcode(Mips::LUi);
2085  tmpInst.addOperand(MCOperand::createReg(TmpReg));
2086  tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2087  Instructions.push_back(tmpInst);
2088 
2089  createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2090  Instructions);
2091  createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2092  Instructions);
2093  createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2094  Instructions);
2095  } else {
2096  // Otherwise, expand to:
2097  // la d,sym => lui d,hi16(sym)
2098  // ori d,d,lo16(sym)
2099  tmpInst.setOpcode(Mips::LUi);
2100  tmpInst.addOperand(MCOperand::createReg(TmpReg));
2101  tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2102  Instructions.push_back(tmpInst);
2103 
2104  emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), SMLoc(),
2105  Instructions);
2106  }
2107 
2108  if (UseSrcReg)
2109  createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2110 
2111  return false;
2112 }
2113 
2114 bool MipsAsmParser::expandUncondBranchMMPseudo(
2115  MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2116  assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2117  "unexpected number of operands");
2118 
2119  MCOperand Offset = Inst.getOperand(0);
2120  if (Offset.isExpr()) {
2121  Inst.clear();
2122  Inst.setOpcode(Mips::BEQ_MM);
2123  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2124  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2125  Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2126  } else {
2127  assert(Offset.isImm() && "expected immediate operand kind");
2128  if (isIntN(11, Offset.getImm())) {
2129  // If offset fits into 11 bits then this instruction becomes microMIPS
2130  // 16-bit unconditional branch instruction.
2131  Inst.setOpcode(Mips::B16_MM);
2132  } else {
2133  if (!isIntN(17, Offset.getImm()))
2134  Error(IDLoc, "branch target out of range");
2135  if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2136  Error(IDLoc, "branch to misaligned address");
2137  Inst.clear();
2138  Inst.setOpcode(Mips::BEQ_MM);
2139  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2140  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2141  Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2142  }
2143  }
2144  Instructions.push_back(Inst);
2145 
2146  // If .set reorder is active, emit a NOP after the branch instruction.
2147  if (AssemblerOptions.back()->isReorder())
2148  createNop(true, IDLoc, Instructions);
2149 
2150  return false;
2151 }
2152 
2153 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2154  SmallVectorImpl<MCInst> &Instructions) {
2155  const MCOperand &DstRegOp = Inst.getOperand(0);
2156  assert(DstRegOp.isReg() && "expected register operand kind");
2157 
2158  const MCOperand &ImmOp = Inst.getOperand(1);
2159  assert(ImmOp.isImm() && "expected immediate operand kind");
2160 
2161  const MCOperand &MemOffsetOp = Inst.getOperand(2);
2162  assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2163 
2164  unsigned OpCode = 0;
2165  switch(Inst.getOpcode()) {
2166  case Mips::BneImm:
2167  OpCode = Mips::BNE;
2168  break;
2169  case Mips::BeqImm:
2170  OpCode = Mips::BEQ;
2171  break;
2172  default:
2173  llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2174  break;
2175  }
2176 
2177  int64_t ImmValue = ImmOp.getImm();
2178  if (ImmValue == 0) {
2180  BranchInst.setOpcode(OpCode);
2181  BranchInst.addOperand(DstRegOp);
2182  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2183  BranchInst.addOperand(MemOffsetOp);
2184  Instructions.push_back(BranchInst);
2185  } else {
2186  warnIfNoMacro(IDLoc);
2187 
2188  unsigned ATReg = getATReg(IDLoc);
2189  if (!ATReg)
2190  return true;
2191 
2192  if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2193  Instructions))
2194  return true;
2195 
2196  MCInst BranchInst;
2197  BranchInst.setOpcode(OpCode);
2198  BranchInst.addOperand(DstRegOp);
2199  BranchInst.addOperand(MCOperand::createReg(ATReg));
2200  BranchInst.addOperand(MemOffsetOp);
2201  Instructions.push_back(BranchInst);
2202  }
2203  return false;
2204 }
2205 
2206 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2207  SmallVectorImpl<MCInst> &Instructions,
2208  bool isLoad, bool isImmOpnd) {
2209  MCInst TempInst;
2210  unsigned ImmOffset, HiOffset, LoOffset;
2211  const MCExpr *ExprOffset;
2212  unsigned TmpRegNum;
2213  // 1st operand is either the source or destination register.
2214  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2215  unsigned RegOpNum = Inst.getOperand(0).getReg();
2216  // 2nd operand is the base register.
2217  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2218  unsigned BaseRegNum = Inst.getOperand(1).getReg();
2219  // 3rd operand is either an immediate or expression.
2220  if (isImmOpnd) {
2221  assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2222  ImmOffset = Inst.getOperand(2).getImm();
2223  LoOffset = ImmOffset & 0x0000ffff;
2224  HiOffset = (ImmOffset & 0xffff0000) >> 16;
2225  // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2226  if (LoOffset & 0x8000)
2227  HiOffset++;
2228  } else
2229  ExprOffset = Inst.getOperand(2).getExpr();
2230  // All instructions will have the same location.
2231  TempInst.setLoc(IDLoc);
2232  // These are some of the types of expansions we perform here:
2233  // 1) lw $8, sym => lui $8, %hi(sym)
2234  // lw $8, %lo(sym)($8)
2235  // 2) lw $8, offset($9) => lui $8, %hi(offset)
2236  // add $8, $8, $9
2237  // lw $8, %lo(offset)($9)
2238  // 3) lw $8, offset($8) => lui $at, %hi(offset)
2239  // add $at, $at, $8
2240  // lw $8, %lo(offset)($at)
2241  // 4) sw $8, sym => lui $at, %hi(sym)
2242  // sw $8, %lo(sym)($at)
2243  // 5) sw $8, offset($8) => lui $at, %hi(offset)
2244  // add $at, $at, $8
2245  // sw $8, %lo(offset)($at)
2246  // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2247  // ldc1 $f0, %lo(sym)($at)
2248  //
2249  // For load instructions we can use the destination register as a temporary
2250  // if base and dst are different (examples 1 and 2) and if the base register
2251  // is general purpose otherwise we must use $at (example 6) and error if it's
2252  // not available. For stores we must use $at (examples 4 and 5) because we
2253  // must not clobber the source register setting up the offset.
2254  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2255  int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2256  unsigned RegClassIDOp0 =
2257  getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2258  bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2259  (RegClassIDOp0 == Mips::GPR64RegClassID);
2260  if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2261  TmpRegNum = RegOpNum;
2262  else {
2263  // At this point we need AT to perform the expansions and we exit if it is
2264  // not available.
2265  TmpRegNum = getATReg(IDLoc);
2266  if (!TmpRegNum)
2267  return;
2268  }
2269 
2270  TempInst.setOpcode(Mips::LUi);
2271  TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2272  if (isImmOpnd)
2273  TempInst.addOperand(MCOperand::createImm(HiOffset));
2274  else {
2275  const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2276  TempInst.addOperand(MCOperand::createExpr(HiExpr));
2277  }
2278  // Add the instruction to the list.
2279  Instructions.push_back(TempInst);
2280  // Prepare TempInst for next instruction.
2281  TempInst.clear();
2282  // Add temp register to base.
2283  if (BaseRegNum != Mips::ZERO) {
2284  TempInst.setOpcode(Mips::ADDu);
2285  TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2286  TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2287  TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2288  Instructions.push_back(TempInst);
2289  TempInst.clear();
2290  }
2291  // And finally, create original instruction with low part
2292  // of offset and new base.
2293  TempInst.setOpcode(Inst.getOpcode());
2294  TempInst.addOperand(MCOperand::createReg(RegOpNum));
2295  TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2296  if (isImmOpnd)
2297  TempInst.addOperand(MCOperand::createImm(LoOffset));
2298  else {
2299  const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2300  TempInst.addOperand(MCOperand::createExpr(LoExpr));
2301  }
2302  Instructions.push_back(TempInst);
2303  TempInst.clear();
2304 }
2305 
2306 bool
2307 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2308  SmallVectorImpl<MCInst> &Instructions) {
2309  unsigned OpNum = Inst.getNumOperands();
2310  unsigned Opcode = Inst.getOpcode();
2311  unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2312 
2313  assert (Inst.getOperand(OpNum - 1).isImm() &&
2314  Inst.getOperand(OpNum - 2).isReg() &&
2315  Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2316 
2317  if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2318  Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2319  Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2320  Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2321  // It can be implemented as SWM16 or LWM16 instruction.
2322  NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2323 
2324  Inst.setOpcode(NewOpcode);
2325  Instructions.push_back(Inst);
2326  return false;
2327 }
2328 
2329 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2330  SmallVectorImpl<MCInst> &Instructions) {
2331  unsigned PseudoOpcode = Inst.getOpcode();
2332  unsigned SrcReg = Inst.getOperand(0).getReg();
2333  unsigned TrgReg = Inst.getOperand(1).getReg();
2334  const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2335 
2336  unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2337  bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2338 
2339  switch (PseudoOpcode) {
2340  case Mips::BLT:
2341  case Mips::BLTU:
2342  AcceptsEquality = false;
2343  ReverseOrderSLT = false;
2344  IsUnsigned = (PseudoOpcode == Mips::BLTU);
2345  ZeroSrcOpcode = Mips::BGTZ;
2346  ZeroTrgOpcode = Mips::BLTZ;
2347  break;
2348  case Mips::BLE:
2349  case Mips::BLEU:
2350  AcceptsEquality = true;
2351  ReverseOrderSLT = true;
2352  IsUnsigned = (PseudoOpcode == Mips::BLEU);
2353  ZeroSrcOpcode = Mips::BGEZ;
2354  ZeroTrgOpcode = Mips::BLEZ;
2355  break;
2356  case Mips::BGE:
2357  case Mips::BGEU:
2358  AcceptsEquality = true;
2359  ReverseOrderSLT = false;
2360  IsUnsigned = (PseudoOpcode == Mips::BGEU);
2361  ZeroSrcOpcode = Mips::BLEZ;
2362  ZeroTrgOpcode = Mips::BGEZ;
2363  break;
2364  case Mips::BGT:
2365  case Mips::BGTU:
2366  AcceptsEquality = false;
2367  ReverseOrderSLT = true;
2368  IsUnsigned = (PseudoOpcode == Mips::BGTU);
2369  ZeroSrcOpcode = Mips::BLTZ;
2370  ZeroTrgOpcode = Mips::BGTZ;
2371  break;
2372  default:
2373  llvm_unreachable("unknown opcode for branch pseudo-instruction");
2374  }
2375 
2376  MCInst BranchInst;
2377  bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2378  bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2379  if (IsSrcRegZero && IsTrgRegZero) {
2380  // FIXME: All of these Opcode-specific if's are needed for compatibility
2381  // with GAS' behaviour. However, they may not generate the most efficient
2382  // code in some circumstances.
2383  if (PseudoOpcode == Mips::BLT) {
2384  BranchInst.setOpcode(Mips::BLTZ);
2385  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2386  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2387  Instructions.push_back(BranchInst);
2388  return false;
2389  }
2390  if (PseudoOpcode == Mips::BLE) {
2391  BranchInst.setOpcode(Mips::BLEZ);
2392  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2393  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2394  Instructions.push_back(BranchInst);
2395  Warning(IDLoc, "branch is always taken");
2396  return false;
2397  }
2398  if (PseudoOpcode == Mips::BGE) {
2399  BranchInst.setOpcode(Mips::BGEZ);
2400  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2401  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2402  Instructions.push_back(BranchInst);
2403  Warning(IDLoc, "branch is always taken");
2404  return false;
2405  }
2406  if (PseudoOpcode == Mips::BGT) {
2407  BranchInst.setOpcode(Mips::BGTZ);
2408  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2409  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2410  Instructions.push_back(BranchInst);
2411  return false;
2412  }
2413  if (PseudoOpcode == Mips::BGTU) {
2414  BranchInst.setOpcode(Mips::BNE);
2415  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2416  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2417  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2418  Instructions.push_back(BranchInst);
2419  return false;
2420  }
2421  if (AcceptsEquality) {
2422  // If both registers are $0 and the pseudo-branch accepts equality, it
2423  // will always be taken, so we emit an unconditional branch.
2424  BranchInst.setOpcode(Mips::BEQ);
2425  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2426  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2427  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2428  Instructions.push_back(BranchInst);
2429  Warning(IDLoc, "branch is always taken");
2430  return false;
2431  }
2432  // If both registers are $0 and the pseudo-branch does not accept
2433  // equality, it will never be taken, so we don't have to emit anything.
2434  return false;
2435  }
2436  if (IsSrcRegZero || IsTrgRegZero) {
2437  if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2438  (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2439  // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2440  // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2441  // the pseudo-branch will never be taken, so we don't emit anything.
2442  // This only applies to unsigned pseudo-branches.
2443  return false;
2444  }
2445  if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2446  (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2447  // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2448  // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2449  // the pseudo-branch will always be taken, so we emit an unconditional
2450  // branch.
2451  // This only applies to unsigned pseudo-branches.
2452  BranchInst.setOpcode(Mips::BEQ);
2453  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2454  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2455  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2456  Instructions.push_back(BranchInst);
2457  Warning(IDLoc, "branch is always taken");
2458  return false;
2459  }
2460  if (IsUnsigned) {
2461  // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2462  // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2463  // the pseudo-branch will be taken only when the non-zero register is
2464  // different from 0, so we emit a BNEZ.
2465  //
2466  // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2467  // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2468  // the pseudo-branch will be taken only when the non-zero register is
2469  // equal to 0, so we emit a BEQZ.
2470  //
2471  // Because only BLEU and BGEU branch on equality, we can use the
2472  // AcceptsEquality variable to decide when to emit the BEQZ.
2473  BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2474  BranchInst.addOperand(
2475  MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2476  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2477  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2478  Instructions.push_back(BranchInst);
2479  return false;
2480  }
2481  // If we have a signed pseudo-branch and one of the registers is $0,
2482  // we can use an appropriate compare-to-zero branch. We select which one
2483  // to use in the switch statement above.
2484  BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2485  BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2486  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2487  Instructions.push_back(BranchInst);
2488  return false;
2489  }
2490 
2491  // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2492  // expansions. If it is not available, we return.
2493  unsigned ATRegNum = getATReg(IDLoc);
2494  if (!ATRegNum)
2495  return true;
2496 
2497  warnIfNoMacro(IDLoc);
2498 
2499  // SLT fits well with 2 of our 4 pseudo-branches:
2500  // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2501  // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2502  // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2503  // This is accomplished by using a BNEZ with the result of the SLT.
2504  //
2505  // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2506  // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2507  // Because only BGE and BLE branch on equality, we can use the
2508  // AcceptsEquality variable to decide when to emit the BEQZ.
2509  // Note that the order of the SLT arguments doesn't change between
2510  // opposites.
2511  //
2512  // The same applies to the unsigned variants, except that SLTu is used
2513  // instead of SLT.
2514  MCInst SetInst;
2515  SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2516  SetInst.addOperand(MCOperand::createReg(ATRegNum));
2517  SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2518  SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2519  Instructions.push_back(SetInst);
2520 
2521  BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2522  BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2523  BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2524  BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2525  Instructions.push_back(BranchInst);
2526  return false;
2527 }
2528 
2529 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2530  SmallVectorImpl<MCInst> &Instructions) {
2531  if (hasMips32r6() || hasMips64r6()) {
2532  Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2533  return false;
2534  }
2535 
2536  warnIfNoMacro(IDLoc);
2537 
2538  const MCOperand &DstRegOp = Inst.getOperand(0);
2539  assert(DstRegOp.isReg() && "expected register operand kind");
2540 
2541  const MCOperand &SrcRegOp = Inst.getOperand(1);
2542  assert(SrcRegOp.isReg() && "expected register operand kind");
2543 
2544  const MCOperand &OffsetImmOp = Inst.getOperand(2);
2545  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2546 
2547  unsigned DstReg = DstRegOp.getReg();
2548  unsigned SrcReg = SrcRegOp.getReg();
2549  int64_t OffsetValue = OffsetImmOp.getImm();
2550 
2551  // NOTE: We always need AT for ULHU, as it is always used as the source
2552  // register for one of the LBu's.
2553  unsigned ATReg = getATReg(IDLoc);
2554  if (!ATReg)
2555  return true;
2556 
2557  // When the value of offset+1 does not fit in 16 bits, we have to load the
2558  // offset in AT, (D)ADDu the original source register (if there was one), and
2559  // then use AT as the source register for the 2 generated LBu's.
2560  bool LoadedOffsetInAT = false;
2561  if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2562  LoadedOffsetInAT = true;
2563 
2564  if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2565  IDLoc, Instructions))
2566  return true;
2567 
2568  // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2569  // because it will make our output more similar to GAS'. For example,
2570  // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2571  // instead of just an "ori $1, $9, 32768".
2572  // NOTE: If there is no source register specified in the ULHU, the parser
2573  // will interpret it as $0.
2574  if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2575  createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2576  }
2577 
2578  unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2579  unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2580  unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2581 
2582  int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2583  if (isLittle()) {
2584  FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2585  SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2586  } else {
2587  FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2588  SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2589  }
2590 
2591  unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2592 
2593  MCInst TmpInst;
2594  TmpInst.setOpcode(Mips::LBu);
2595  TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2596  TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2597  TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2598  Instructions.push_back(TmpInst);
2599 
2600  TmpInst.clear();
2601  TmpInst.setOpcode(Mips::LBu);
2602  TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2603  TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2604  TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2605  Instructions.push_back(TmpInst);
2606 
2607  TmpInst.clear();
2608  TmpInst.setOpcode(Mips::SLL);
2609  TmpInst.addOperand(MCOperand::createReg(SllReg));
2610  TmpInst.addOperand(MCOperand::createReg(SllReg));
2611  TmpInst.addOperand(MCOperand::createImm(8));
2612  Instructions.push_back(TmpInst);
2613 
2614  TmpInst.clear();
2615  TmpInst.setOpcode(Mips::OR);
2616  TmpInst.addOperand(MCOperand::createReg(DstReg));
2617  TmpInst.addOperand(MCOperand::createReg(DstReg));
2618  TmpInst.addOperand(MCOperand::createReg(ATReg));
2619  Instructions.push_back(TmpInst);
2620 
2621  return false;
2622 }
2623 
2624 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2625  SmallVectorImpl<MCInst> &Instructions) {
2626  if (hasMips32r6() || hasMips64r6()) {
2627  Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2628  return false;
2629  }
2630 
2631  const MCOperand &DstRegOp = Inst.getOperand(0);
2632  assert(DstRegOp.isReg() && "expected register operand kind");
2633 
2634  const MCOperand &SrcRegOp = Inst.getOperand(1);
2635  assert(SrcRegOp.isReg() && "expected register operand kind");
2636 
2637  const MCOperand &OffsetImmOp = Inst.getOperand(2);
2638  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2639 
2640  unsigned SrcReg = SrcRegOp.getReg();
2641  int64_t OffsetValue = OffsetImmOp.getImm();
2642  unsigned ATReg = 0;
2643 
2644  // When the value of offset+3 does not fit in 16 bits, we have to load the
2645  // offset in AT, (D)ADDu the original source register (if there was one), and
2646  // then use AT as the source register for the generated LWL and LWR.
2647  bool LoadedOffsetInAT = false;
2648  if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2649  ATReg = getATReg(IDLoc);
2650  if (!ATReg)
2651  return true;
2652  LoadedOffsetInAT = true;
2653 
2654  warnIfNoMacro(IDLoc);
2655 
2656  if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2657  IDLoc, Instructions))
2658  return true;
2659 
2660  // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2661  // because it will make our output more similar to GAS'. For example,
2662  // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2663  // instead of just an "ori $1, $9, 32768".
2664  // NOTE: If there is no source register specified in the ULW, the parser
2665  // will interpret it as $0.
2666  if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2667  createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2668  }
2669 
2670  unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2671  int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2672  if (isLittle()) {
2673  LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2674  RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2675  } else {
2676  LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2677  RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2678  }
2679 
2680  MCInst LeftLoadInst;
2681  LeftLoadInst.setOpcode(Mips::LWL);
2682  LeftLoadInst.addOperand(DstRegOp);
2683  LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2684  LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2685  Instructions.push_back(LeftLoadInst);
2686 
2687  MCInst RightLoadInst;
2688  RightLoadInst.setOpcode(Mips::LWR);
2689  RightLoadInst.addOperand(DstRegOp);
2690  RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2691  RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2692  Instructions.push_back(RightLoadInst);
2693 
2694  return false;
2695 }
2696 
2697 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2698  SmallVectorImpl<MCInst> &Instructions) {
2699  MCInst NopInst;
2700  if (hasShortDelaySlot) {
2701  NopInst.setOpcode(Mips::MOVE16_MM);
2702  NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2703  NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2704  } else {
2705  NopInst.setOpcode(Mips::SLL);
2706  NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2707  NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2708  NopInst.addOperand(MCOperand::createImm(0));
2709  }
2710  Instructions.push_back(NopInst);
2711 }
2712 
2713 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2714  unsigned TrgReg, bool Is64Bit,
2715  SmallVectorImpl<MCInst> &Instructions) {
2716  emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
2717  Instructions);
2718 }
2719 
2720 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2721  // As described by the Mips32r2 spec, the registers Rd and Rs for
2722  // jalr.hb must be different.
2723  unsigned Opcode = Inst.getOpcode();
2724 
2725  if (Opcode == Mips::JALR_HB &&
2726  (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2727  return Match_RequiresDifferentSrcAndDst;
2728 
2729  return Match_Success;
2730 }
2731 
2732 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2734  MCStreamer &Out,
2735  uint64_t &ErrorInfo,
2736  bool MatchingInlineAsm) {
2737 
2738  MCInst Inst;
2739  SmallVector<MCInst, 8> Instructions;
2740  unsigned MatchResult =
2741  MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2742 
2743  switch (MatchResult) {
2744  case Match_Success: {
2745  if (processInstruction(Inst, IDLoc, Instructions))
2746  return true;
2747  for (unsigned i = 0; i < Instructions.size(); i++)
2748  Out.EmitInstruction(Instructions[i], STI);
2749  return false;
2750  }
2751  case Match_MissingFeature:
2752  Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2753  return true;
2754  case Match_InvalidOperand: {
2755  SMLoc ErrorLoc = IDLoc;
2756  if (ErrorInfo != ~0ULL) {
2757  if (ErrorInfo >= Operands.size())
2758  return Error(IDLoc, "too few operands for instruction");
2759 
2760  ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2761  if (ErrorLoc == SMLoc())
2762  ErrorLoc = IDLoc;
2763  }
2764 
2765  return Error(ErrorLoc, "invalid operand for instruction");
2766  }
2767  case Match_MnemonicFail:
2768  return Error(IDLoc, "invalid instruction");
2769  case Match_RequiresDifferentSrcAndDst:
2770  return Error(IDLoc, "source and destination must be different");
2771  }
2772 
2773  llvm_unreachable("Implement any new match types added!");
2774 }
2775 
2776 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2777  if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2778  Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2779  ") without \".set noat\"");
2780 }
2781 
2782 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2783  if (!AssemblerOptions.back()->isMacro())
2784  Warning(Loc, "macro instruction expanded into multiple instructions");
2785 }
2786 
2787 void
2788 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2789  SMRange Range, bool ShowColors) {
2790  getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2791  Range, SMFixIt(Range, FixMsg),
2792  ShowColors);
2793 }
2794 
2795 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2796  int CC;
2797 
2799  .Case("zero", 0)
2800  .Case("at", 1)
2801  .Case("a0", 4)
2802  .Case("a1", 5)
2803  .Case("a2", 6)
2804  .Case("a3", 7)
2805  .Case("v0", 2)
2806  .Case("v1", 3)
2807  .Case("s0", 16)
2808  .Case("s1", 17)
2809  .Case("s2", 18)
2810  .Case("s3", 19)
2811  .Case("s4", 20)
2812  .Case("s5", 21)
2813  .Case("s6", 22)
2814  .Case("s7", 23)
2815  .Case("k0", 26)
2816  .Case("k1", 27)
2817  .Case("gp", 28)
2818  .Case("sp", 29)
2819  .Case("fp", 30)
2820  .Case("s8", 30)
2821  .Case("ra", 31)
2822  .Case("t0", 8)
2823  .Case("t1", 9)
2824  .Case("t2", 10)
2825  .Case("t3", 11)
2826  .Case("t4", 12)
2827  .Case("t5", 13)
2828  .Case("t6", 14)
2829  .Case("t7", 15)
2830  .Case("t8", 24)
2831  .Case("t9", 25)
2832  .Default(-1);
2833 
2834  if (!(isABI_N32() || isABI_N64()))
2835  return CC;
2836 
2837  if (12 <= CC && CC <= 15) {
2838  // Name is one of t4-t7
2839  AsmToken RegTok = getLexer().peekTok();
2840  SMRange RegRange = RegTok.getLocRange();
2841 
2843  .Case("t4", "t0")
2844  .Case("t5", "t1")
2845  .Case("t6", "t2")
2846  .Case("t7", "t3")
2847  .Default("");
2848  assert(FixedName != "" && "Register name is not one of t4-t7.");
2849 
2850  printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2851  "Did you mean $" + FixedName + "?", RegRange);
2852  }
2853 
2854  // Although SGI documentation just cuts out t0-t3 for n32/n64,
2855  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2856  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2857  if (8 <= CC && CC <= 11)
2858  CC += 4;
2859 
2860  if (CC == -1)
2862  .Case("a4", 8)
2863  .Case("a5", 9)
2864  .Case("a6", 10)
2865  .Case("a7", 11)
2866  .Case("kt0", 26)
2867  .Case("kt1", 27)
2868  .Default(-1);
2869 
2870  return CC;
2871 }
2872 
2873 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2874  int CC;
2875 
2877  .Case("hwr_cpunum", 0)
2878  .Case("hwr_synci_step", 1)
2879  .Case("hwr_cc", 2)
2880  .Case("hwr_ccres", 3)
2881  .Case("hwr_ulr", 29)
2882  .Default(-1);
2883 
2884  return CC;
2885 }
2886 
2887 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2888 
2889  if (Name[0] == 'f') {
2890  StringRef NumString = Name.substr(1);
2891  unsigned IntVal;
2892  if (NumString.getAsInteger(10, IntVal))
2893  return -1; // This is not an integer.
2894  if (IntVal > 31) // Maximum index for fpu register.
2895  return -1;
2896  return IntVal;
2897  }
2898  return -1;
2899 }
2900 
2901 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2902 
2903  if (Name.startswith("fcc")) {
2904  StringRef NumString = Name.substr(3);
2905  unsigned IntVal;
2906  if (NumString.getAsInteger(10, IntVal))
2907  return -1; // This is not an integer.
2908  if (IntVal > 7) // There are only 8 fcc registers.
2909  return -1;
2910  return IntVal;
2911  }
2912  return -1;
2913 }
2914 
2915 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2916 
2917  if (Name.startswith("ac")) {
2918  StringRef NumString = Name.substr(2);
2919  unsigned IntVal;
2920  if (NumString.getAsInteger(10, IntVal))
2921  return -1; // This is not an integer.
2922  if (IntVal > 3) // There are only 3 acc registers.
2923  return -1;
2924  return IntVal;
2925  }
2926  return -1;
2927 }
2928 
2929 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2930  unsigned IntVal;
2931 
2932  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2933  return -1;
2934 
2935  if (IntVal > 31)
2936  return -1;
2937 
2938  return IntVal;
2939 }
2940 
2941 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2942  int CC;
2943 
2945  .Case("msair", 0)
2946  .Case("msacsr", 1)
2947  .Case("msaaccess", 2)
2948  .Case("msasave", 3)
2949  .Case("msamodify", 4)
2950  .Case("msarequest", 5)
2951  .Case("msamap", 6)
2952  .Case("msaunmap", 7)
2953  .Default(-1);
2954 
2955  return CC;
2956 }
2957 
2958 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2959  unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2960  if (ATIndex == 0) {
2961  reportParseError(Loc,
2962  "pseudo-instruction requires $at, which is not available");
2963  return 0;
2964  }
2965  unsigned AT = getReg(
2966  (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2967  return AT;
2968 }
2969 
2970 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2971  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2972 }
2973 
2974 unsigned MipsAsmParser::getGPR(int RegNo) {
2975  return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2976  RegNo);
2977 }
2978 
2979 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2980  if (RegNum >
2981  getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2982  return -1;
2983 
2984  return getReg(RegClass, RegNum);
2985 }
2986 
2987 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2988  MCAsmParser &Parser = getParser();
2989  DEBUG(dbgs() << "parseOperand\n");
2990 
2991  // Check if the current operand has a custom associated parser, if so, try to
2992  // custom parse the operand, or fallback to the general approach.
2993  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2994  if (ResTy == MatchOperand_Success)
2995  return false;
2996  // If there wasn't a custom match, try the generic matcher below. Otherwise,
2997  // there was a match, but an error occurred, in which case, just return that
2998  // the operand parsing failed.
2999  if (ResTy == MatchOperand_ParseFail)
3000  return true;
3001 
3002  DEBUG(dbgs() << ".. Generic Parser\n");
3003 
3004  switch (getLexer().getKind()) {
3005  default:
3006  Error(Parser.getTok().getLoc(), "unexpected token in operand");
3007  return true;
3008  case AsmToken::Dollar: {
3009  // Parse the register.
3010  SMLoc S = Parser.getTok().getLoc();
3011 
3012  // Almost all registers have been parsed by custom parsers. There is only
3013  // one exception to this. $zero (and it's alias $0) will reach this point
3014  // for div, divu, and similar instructions because it is not an operand
3015  // to the instruction definition but an explicit register. Special case
3016  // this situation for now.
3017  if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3018  return false;
3019 
3020  // Maybe it is a symbol reference.
3021  StringRef Identifier;
3022  if (Parser.parseIdentifier(Identifier))
3023  return true;
3024 
3025  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3026  MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3027  // Otherwise create a symbol reference.
3028  const MCExpr *Res =
3030 
3031  Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3032  return false;
3033  }
3034  // Else drop to expression parsing.
3035  case AsmToken::LParen:
3036  case AsmToken::Minus:
3037  case AsmToken::Plus:
3038  case AsmToken::Integer:
3039  case AsmToken::Tilde:
3040  case AsmToken::String: {
3041  DEBUG(dbgs() << ".. generic integer\n");
3042  OperandMatchResultTy ResTy = parseImm(Operands);
3043  return ResTy != MatchOperand_Success;
3044  }
3045  case AsmToken::Percent: {
3046  // It is a symbol reference or constant expression.
3047  const MCExpr *IdVal;
3048  SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3049  if (parseRelocOperand(IdVal))
3050  return true;
3051 
3052  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3053 
3054  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3055  return false;
3056  } // case AsmToken::Percent
3057  } // switch(getLexer().getKind())
3058  return true;
3059 }
3060 
3061 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3062  StringRef RelocStr) {
3063  const MCExpr *Res;
3064  // Check the type of the expression.
3065  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3066  // It's a constant, evaluate reloc value.
3067  int16_t Val;
3068  switch (getVariantKind(RelocStr)) {
3070  // Get the 1st 16-bits.
3071  Val = MCE->getValue() & 0xffff;
3072  break;
3074  // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3075  // 16 bits being negative.
3076  Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3077  break;
3079  // Get the 3rd 16-bits.
3080  Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3081  break;
3083  // Get the 4th 16-bits.
3084  Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3085  break;
3086  default:
3087  report_fatal_error("unsupported reloc value");
3088  }
3089  return MCConstantExpr::create(Val, getContext());
3090  }
3091 
3092  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3093  // It's a symbol, create a symbolic expression from the symbol.
3094  const MCSymbol *Symbol = &MSRE->getSymbol();
3096  Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3097  return Res;
3098  }
3099 
3100  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3102 
3103  // Try to create target expression.
3105  return MipsMCExpr::create(VK, Expr, getContext());
3106 
3107  const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3108  const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3109  Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3110  return Res;
3111  }
3112 
3113  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3114  const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3115  Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3116  return Res;
3117  }
3118  // Just return the original expression.
3119  return Expr;
3120 }
3121 
3122 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3123 
3124  switch (Expr->getKind()) {
3125  case MCExpr::Constant:
3126  return true;
3127  case MCExpr::SymbolRef:
3128  return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3129  case MCExpr::Binary:
3130  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3131  if (!isEvaluated(BE->getLHS()))
3132  return false;
3133  return isEvaluated(BE->getRHS());
3134  }
3135  case MCExpr::Unary:
3136  return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3137  case MCExpr::Target:
3138  return true;
3139  }
3140  return false;
3141 }
3142 
3143 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3144  MCAsmParser &Parser = getParser();
3145  Parser.Lex(); // Eat the % token.
3146  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3147  if (Tok.isNot(AsmToken::Identifier))
3148  return true;
3149 
3150  std::string Str = Tok.getIdentifier();
3151 
3152  Parser.Lex(); // Eat the identifier.
3153  // Now make an expression from the rest of the operand.
3154  const MCExpr *IdVal;
3155  SMLoc EndLoc;
3156 
3157  if (getLexer().getKind() == AsmToken::LParen) {
3158  while (1) {
3159  Parser.Lex(); // Eat the '(' token.
3160  if (getLexer().getKind() == AsmToken::Percent) {
3161  Parser.Lex(); // Eat the % token.
3162  const AsmToken &nextTok = Parser.getTok();
3163  if (nextTok.isNot(AsmToken::Identifier))
3164  return true;
3165  Str += "(%";
3166  Str += nextTok.getIdentifier();
3167  Parser.Lex(); // Eat the identifier.
3168  if (getLexer().getKind() != AsmToken::LParen)
3169  return true;
3170  } else
3171  break;
3172  }
3173  if (getParser().parseParenExpression(IdVal, EndLoc))
3174  return true;
3175 
3176  while (getLexer().getKind() == AsmToken::RParen)
3177  Parser.Lex(); // Eat the ')' token.
3178 
3179  } else
3180  return true; // Parenthesis must follow the relocation operand.
3181 
3182  Res = evaluateRelocExpr(IdVal, Str);
3183  return false;
3184 }
3185 
3186 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3187  SMLoc &EndLoc) {
3189  OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3190  if (ResTy == MatchOperand_Success) {
3191  assert(Operands.size() == 1);
3192  MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3193  StartLoc = Operand.getStartLoc();
3194  EndLoc = Operand.getEndLoc();
3195 
3196  // AFAIK, we only support numeric registers and named GPR's in CFI
3197  // directives.
3198  // Don't worry about eating tokens before failing. Using an unrecognised
3199  // register is a parse error.
3200  if (Operand.isGPRAsmReg()) {
3201  // Resolve to GPR32 or GPR64 appropriately.
3202  RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3203  }
3204 
3205  return (RegNo == (unsigned)-1);
3206  }
3207 
3208  assert(Operands.size() == 0);
3209  return (RegNo == (unsigned)-1);
3210 }
3211 
3212 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3213  MCAsmParser &Parser = getParser();
3214  SMLoc S;
3215  bool Result = true;
3216  unsigned NumOfLParen = 0;
3217 
3218  while (getLexer().getKind() == AsmToken::LParen) {
3219  Parser.Lex();
3220  ++NumOfLParen;
3221  }
3222 
3223  switch (getLexer().getKind()) {
3224  default:
3225  return true;
3226  case AsmToken::Identifier:
3227  case AsmToken::LParen:
3228  case AsmToken::Integer:
3229  case AsmToken::Minus:
3230  case AsmToken::Plus:
3231  if (isParenExpr)
3232  Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3233  else
3234  Result = (getParser().parseExpression(Res));
3235  while (getLexer().getKind() == AsmToken::RParen)
3236  Parser.Lex();
3237  break;
3238  case AsmToken::Percent:
3239  Result = parseRelocOperand(Res);
3240  }
3241  return Result;
3242 }
3243 
3244 MipsAsmParser::OperandMatchResultTy
3245 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3246  MCAsmParser &Parser = getParser();
3247  DEBUG(dbgs() << "parseMemOperand\n");
3248  const MCExpr *IdVal = nullptr;
3249  SMLoc S;
3250  bool isParenExpr = false;
3251  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3252  // First operand is the offset.
3253  S = Parser.getTok().getLoc();
3254 
3255  if (getLexer().getKind() == AsmToken::LParen) {
3256  Parser.Lex();
3257  isParenExpr = true;
3258  }
3259 
3260  if (getLexer().getKind() != AsmToken::Dollar) {
3261  if (parseMemOffset(IdVal, isParenExpr))
3262  return MatchOperand_ParseFail;
3263 
3264  const AsmToken &Tok = Parser.getTok(); // Get the next token.
3265  if (Tok.isNot(AsmToken::LParen)) {
3266  MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3267  if (Mnemonic.getToken() == "la") {
3268  SMLoc E =
3269  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3270  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3271  return MatchOperand_Success;
3272  }
3273  if (Tok.is(AsmToken::EndOfStatement)) {
3274  SMLoc E =
3275  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3276 
3277  // Zero register assumed, add a memory operand with ZERO as its base.
3278  // "Base" will be managed by k_Memory.
3279  auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3280  S, E, *this);
3281  Operands.push_back(
3282  MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3283  return MatchOperand_Success;
3284  }
3285  Error(Parser.getTok().getLoc(), "'(' expected");
3286  return MatchOperand_ParseFail;
3287  }
3288 
3289  Parser.Lex(); // Eat the '(' token.
3290  }
3291 
3292  Res = parseAnyRegister(Operands);
3293  if (Res != MatchOperand_Success)
3294  return Res;
3295 
3296  if (Parser.getTok().isNot(AsmToken::RParen)) {
3297  Error(Parser.getTok().getLoc(), "')' expected");
3298  return MatchOperand_ParseFail;
3299  }
3300 
3301  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3302 
3303  Parser.Lex(); // Eat the ')' token.
3304 
3305  if (!IdVal)
3306  IdVal = MCConstantExpr::create(0, getContext());
3307 
3308  // Replace the register operand with the memory operand.
3309  std::unique_ptr<MipsOperand> op(
3310  static_cast<MipsOperand *>(Operands.back().release()));
3311  // Remove the register from the operands.
3312  // "op" will be managed by k_Memory.
3313  Operands.pop_back();
3314  // Add the memory operand.
3315  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3316  int64_t Imm;
3317  if (IdVal->evaluateAsAbsolute(Imm))
3318  IdVal = MCConstantExpr::create(Imm, getContext());
3319  else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3320  IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3321  getContext());
3322  }
3323 
3324  Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3325  return MatchOperand_Success;
3326 }
3327 
3328 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3329  MCAsmParser &Parser = getParser();
3330  MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3331  if (Sym) {
3332  SMLoc S = Parser.getTok().getLoc();
3333  const MCExpr *Expr;
3334  if (Sym->isVariable())
3335  Expr = Sym->getVariableValue();
3336  else
3337  return false;
3338  if (Expr->getKind() == MCExpr::SymbolRef) {
3339  const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3340  StringRef DefSymbol = Ref->getSymbol().getName();
3341  if (DefSymbol.startswith("$")) {
3342  OperandMatchResultTy ResTy =
3343  matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3344  if (ResTy == MatchOperand_Success) {
3345  Parser.Lex();
3346  return true;
3347  } else if (ResTy == MatchOperand_ParseFail)
3348  llvm_unreachable("Should never ParseFail");
3349  return false;
3350  }
3351  } else if (Expr->getKind() == MCExpr::Constant) {
3352  Parser.Lex();
3353  const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3354  Operands.push_back(
3355  MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3356  return true;
3357  }
3358  }
3359  return false;
3360 }
3361 
3362 MipsAsmParser::OperandMatchResultTy
3363 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3364  StringRef Identifier,
3365  SMLoc S) {
3366  int Index = matchCPURegisterName(Identifier);
3367  if (Index != -1) {
3368  Operands.push_back(MipsOperand::createGPRReg(
3369  Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3370  return MatchOperand_Success;
3371  }
3372 
3373  Index = matchHWRegsRegisterName(Identifier);
3374  if (Index != -1) {
3375  Operands.push_back(MipsOperand::createHWRegsReg(
3376  Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3377  return MatchOperand_Success;
3378  }
3379 
3380  Index = matchFPURegisterName(Identifier);
3381  if (Index != -1) {
3382  Operands.push_back(MipsOperand::createFGRReg(
3383  Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3384  return MatchOperand_Success;
3385  }
3386 
3387  Index = matchFCCRegisterName(Identifier);
3388  if (Index != -1) {
3389  Operands.push_back(MipsOperand::createFCCReg(
3390  Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3391  return MatchOperand_Success;
3392  }
3393 
3394  Index = matchACRegisterName(Identifier);
3395  if (Index != -1) {
3396  Operands.push_back(MipsOperand::createACCReg(
3397  Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3398  return MatchOperand_Success;
3399  }
3400 
3401  Index = matchMSA128RegisterName(Identifier);
3402  if (Index != -1) {
3403  Operands.push_back(MipsOperand::createMSA128Reg(
3404  Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3405  return MatchOperand_Success;
3406  }
3407 
3408  Index = matchMSA128CtrlRegisterName(Identifier);
3409  if (Index != -1) {
3410  Operands.push_back(MipsOperand::createMSACtrlReg(
3411  Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3412  return MatchOperand_Success;
3413  }
3414 
3415  return MatchOperand_NoMatch;
3416 }
3417 
3418 MipsAsmParser::OperandMatchResultTy
3419 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3420  MCAsmParser &Parser = getParser();
3421  auto Token = Parser.getLexer().peekTok(false);
3422 
3423  if (Token.is(AsmToken::Identifier)) {
3424  DEBUG(dbgs() << ".. identifier\n");
3425  StringRef Identifier = Token.getIdentifier();
3426  OperandMatchResultTy ResTy =
3427  matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3428  return ResTy;
3429  } else if (Token.is(AsmToken::Integer)) {
3430  DEBUG(dbgs() << ".. integer\n");
3431  Operands.push_back(MipsOperand::createNumericReg(
3432  Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3433  *this));
3434  return MatchOperand_Success;
3435  }
3436 
3437  DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3438 
3439  return MatchOperand_NoMatch;
3440 }
3441 
3442 MipsAsmParser::OperandMatchResultTy
3443 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3444  MCAsmParser &Parser = getParser();
3445  DEBUG(dbgs() << "parseAnyRegister\n");
3446 
3447  auto Token = Parser.getTok();
3448 
3449  SMLoc S = Token.getLoc();
3450 
3451  if (Token.isNot(AsmToken::Dollar)) {
3452  DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3453  if (Token.is(AsmToken::Identifier)) {
3454  if (searchSymbolAlias(Operands))
3455  return MatchOperand_Success;
3456  }
3457  DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3458  return MatchOperand_NoMatch;
3459  }
3460  DEBUG(dbgs() << ".. $\n");
3461 
3462  OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3463  if (ResTy == MatchOperand_Success) {
3464  Parser.Lex(); // $
3465  Parser.Lex(); // identifier
3466  }
3467  return ResTy;
3468 }
3469 
3470 MipsAsmParser::OperandMatchResultTy
3471 MipsAsmParser::parseImm(OperandVector &Operands) {
3472  MCAsmParser &Parser = getParser();
3473  switch (getLexer().getKind()) {
3474  default:
3475  return MatchOperand_NoMatch;
3476  case AsmToken::LParen:
3477  case AsmToken::Minus:
3478  case AsmToken::Plus:
3479  case AsmToken::Integer:
3480  case AsmToken::Tilde:
3481  case AsmToken::String:
3482  break;
3483  }
3484 
3485  const MCExpr *IdVal;
3486  SMLoc S = Parser.getTok().getLoc();
3487  if (getParser().parseExpression(IdVal))
3488  return MatchOperand_ParseFail;
3489 
3490  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3491  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3492  return MatchOperand_Success;
3493 }
3494 
3495 MipsAsmParser::OperandMatchResultTy
3496 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3497  MCAsmParser &Parser = getParser();
3498  DEBUG(dbgs() << "parseJumpTarget\n");
3499 
3500  SMLoc S = getLexer().getLoc();
3501 
3502  // Integers and expressions are acceptable
3503  OperandMatchResultTy ResTy = parseImm(Operands);
3504  if (ResTy != MatchOperand_NoMatch)
3505  return ResTy;
3506 
3507  // Registers are a valid target and have priority over symbols.
3508  ResTy = parseAnyRegister(Operands);
3509  if (ResTy != MatchOperand_NoMatch)
3510  return ResTy;
3511 
3512  const MCExpr *Expr = nullptr;
3513  if (Parser.parseExpression(Expr)) {
3514  // We have no way of knowing if a symbol was consumed so we must ParseFail
3515  return MatchOperand_ParseFail;
3516  }
3517  Operands.push_back(
3518  MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3519  return MatchOperand_Success;
3520 }
3521 
3522 MipsAsmParser::OperandMatchResultTy
3523 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3524  MCAsmParser &Parser = getParser();
3525  const MCExpr *IdVal;
3526  // If the first token is '$' we may have register operand.
3527  if (Parser.getTok().is(AsmToken::Dollar))
3528  return MatchOperand_NoMatch;
3529  SMLoc S = Parser.getTok().getLoc();
3530  if (getParser().parseExpression(IdVal))
3531  return MatchOperand_ParseFail;
3532  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3533  assert(MCE && "Unexpected MCExpr type.");
3534  int64_t Val = MCE->getValue();
3535  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3536  Operands.push_back(MipsOperand::CreateImm(
3537  MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3538  return MatchOperand_Success;
3539 }
3540 
3541 MipsAsmParser::OperandMatchResultTy
3542 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3543  MCAsmParser &Parser = getParser();
3544  switch (getLexer().getKind()) {
3545  default:
3546  return MatchOperand_NoMatch;
3547  case AsmToken::LParen:
3548  case AsmToken::Plus:
3549  case AsmToken::Minus:
3550  case AsmToken::Integer:
3551  break;
3552  }
3553 
3554  const MCExpr *Expr;
3555  SMLoc S = Parser.getTok().getLoc();
3556 
3557  if (getParser().parseExpression(Expr))
3558  return MatchOperand_ParseFail;
3559 
3560  int64_t Val;
3561  if (!Expr->evaluateAsAbsolute(Val)) {
3562  Error(S, "expected immediate value");
3563  return MatchOperand_ParseFail;
3564  }
3565 
3566  // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3567  // and because the CPU always adds one to the immediate field, the allowed
3568  // range becomes 1..4. We'll only check the range here and will deal
3569  // with the addition/subtraction when actually decoding/encoding
3570  // the instruction.
3571  if (Val < 1 || Val > 4) {
3572  Error(S, "immediate not in range (1..4)");
3573  return MatchOperand_ParseFail;
3574  }
3575 
3576  Operands.push_back(
3577  MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3578  return MatchOperand_Success;
3579 }
3580 
3581 MipsAsmParser::OperandMatchResultTy
3582 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3583  MCAsmParser &Parser = getParser();
3585  unsigned RegNo;
3586  unsigned PrevReg = Mips::NoRegister;
3587  bool RegRange = false;
3589 
3590  if (Parser.getTok().isNot(AsmToken::Dollar))
3591  return MatchOperand_ParseFail;
3592 
3593  SMLoc S = Parser.getTok().getLoc();
3594  while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3595  SMLoc E = getLexer().getLoc();
3596  MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3597  RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3598  if (RegRange) {
3599  // Remove last register operand because registers from register range
3600  // should be inserted first.
3601  if (RegNo == Mips::RA) {
3602  Regs.push_back(RegNo);
3603  } else {
3604  unsigned TmpReg = PrevReg + 1;
3605  while (TmpReg <= RegNo) {
3606  if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3607  Error(E, "invalid register operand");
3608  return MatchOperand_ParseFail;
3609  }
3610 
3611  PrevReg = TmpReg;
3612  Regs.push_back(TmpReg++);
3613  }
3614  }
3615 
3616  RegRange = false;
3617  } else {
3618  if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3619  (RegNo != Mips::RA)) {
3620  Error(E, "$16 or $31 expected");
3621  return MatchOperand_ParseFail;
3622  } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3623  (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3624  Error(E, "invalid register operand");
3625  return MatchOperand_ParseFail;
3626  } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3627  (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3628  Error(E, "consecutive register numbers expected");
3629  return MatchOperand_ParseFail;
3630  }
3631 
3632  Regs.push_back(RegNo);
3633  }
3634 
3635  if (Parser.getTok().is(AsmToken::Minus))
3636  RegRange = true;
3637 
3638  if (!Parser.getTok().isNot(AsmToken::Minus) &&
3639  !Parser.getTok().isNot(AsmToken::Comma)) {
3640  Error(E, "',' or '-' expected");
3641  return MatchOperand_ParseFail;
3642  }
3643 
3644  Lex(); // Consume comma or minus
3645  if (Parser.getTok().isNot(AsmToken::Dollar))
3646  break;
3647 
3648  PrevReg = RegNo;
3649  }
3650 
3651  SMLoc E = Parser.getTok().getLoc();
3652  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3653  parseMemOperand(Operands);
3654  return MatchOperand_Success;
3655 }
3656 
3657 MipsAsmParser::OperandMatchResultTy
3658 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3659  MCAsmParser &Parser = getParser();
3660 
3661  SMLoc S = Parser.getTok().getLoc();
3662  if (parseAnyRegister(Operands) != MatchOperand_Success)
3663  return MatchOperand_ParseFail;
3664 
3665  SMLoc E = Parser.getTok().getLoc();
3666  MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3667  unsigned Reg = Op.getGPR32Reg();
3668  Operands.pop_back();
3669  Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3670  return MatchOperand_Success;
3671 }
3672 
3673 MipsAsmParser::OperandMatchResultTy
3674 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3675  MCAsmParser &Parser = getParser();
3678 
3679  if (Parser.getTok().isNot(AsmToken::Dollar))
3680  return MatchOperand_ParseFail;
3681 
3682  SMLoc S = Parser.getTok().getLoc();
3683 
3684  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3685  return MatchOperand_ParseFail;
3686 
3687  MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3688  unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3689  Regs.push_back(RegNo);
3690 
3691  SMLoc E = Parser.getTok().getLoc();
3692  if (Parser.getTok().isNot(AsmToken::Comma)) {
3693  Error(E, "',' expected");
3694  return MatchOperand_ParseFail;
3695  }
3696 
3697  // Remove comma.
3698  Parser.Lex();
3699 
3700  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3701  return MatchOperand_ParseFail;
3702 
3703  Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3704  RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3705  Regs.push_back(RegNo);
3706 
3707  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3708 
3709  return MatchOperand_Success;
3710 }
3711 
3713 
3716  .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3731  .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3732  .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3742 
3743  assert(VK != MCSymbolRefExpr::VK_None);
3744 
3745  return VK;
3746 }
3747 
3748 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3749 /// either this.
3750 /// ::= '(', register, ')'
3751 /// handle it before we iterate so we don't get tripped up by the lack of
3752 /// a comma.
3753 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3754  MCAsmParser &Parser = getParser();
3755  if (getLexer().is(AsmToken::LParen)) {
3756  Operands.push_back(
3757  MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3758  Parser.Lex();
3759  if (parseOperand(Operands, Name)) {
3760  SMLoc Loc = getLexer().getLoc();
3761  Parser.eatToEndOfStatement();
3762  return Error(Loc, "unexpected token in argument list");
3763  }
3764  if (Parser.getTok().isNot(AsmToken::RParen)) {
3765  SMLoc Loc = getLexer().getLoc();
3766  Parser.eatToEndOfStatement();
3767  return Error(Loc, "unexpected token, expected ')'");
3768  }
3769  Operands.push_back(
3770  MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3771  Parser.Lex();
3772  }
3773  return false;
3774 }
3775 
3776 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3777 /// either one of these.
3778 /// ::= '[', register, ']'
3779 /// ::= '[', integer, ']'
3780 /// handle it before we iterate so we don't get tripped up by the lack of
3781 /// a comma.
3782 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3783  OperandVector &Operands) {
3784  MCAsmParser &Parser = getParser();
3785  if (getLexer().is(AsmToken::LBrac)) {
3786  Operands.push_back(
3787  MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3788  Parser.Lex();
3789  if (parseOperand(Operands, Name)) {
3790  SMLoc Loc = getLexer().getLoc();
3791  Parser.eatToEndOfStatement();
3792  return Error(Loc, "unexpected token in argument list");
3793  }
3794  if (Parser.getTok().isNot(AsmToken::RBrac)) {
3795  SMLoc Loc = getLexer().getLoc();
3796  Parser.eatToEndOfStatement();
3797  return Error(Loc, "unexpected token, expected ']'");
3798  }
3799  Operands.push_back(
3800  MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3801  Parser.Lex();
3802  }
3803  return false;
3804 }
3805 
3806 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3807  SMLoc NameLoc, OperandVector &Operands) {
3808  MCAsmParser &Parser = getParser();
3809  DEBUG(dbgs() << "ParseInstruction\n");
3810 
3811  // We have reached first instruction, module directive are now forbidden.
3812  getTargetStreamer().forbidModuleDirective();
3813 
3814  // Check if we have valid mnemonic
3815  if (!mnemonicIsValid(Name, 0)) {
3816  Parser.eatToEndOfStatement();
3817  return Error(NameLoc, "unknown instruction");
3818  }
3819  // First operand in MCInst is instruction mnemonic.
3820  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3821 
3822  // Read the remaining operands.
3823  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3824  // Read the first operand.
3825  if (parseOperand(Operands, Name)) {
3826  SMLoc Loc = getLexer().getLoc();
3827  Parser.eatToEndOfStatement();
3828  return Error(Loc, "unexpected token in argument list");
3829  }
3830  if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3831  return true;
3832  // AFAIK, parenthesis suffixes are never on the first operand
3833 
3834  while (getLexer().is(AsmToken::Comma)) {
3835  Parser.Lex(); // Eat the comma.
3836  // Parse and remember the operand.
3837  if (parseOperand(Operands, Name)) {
3838  SMLoc Loc = getLexer().getLoc();
3839  Parser.eatToEndOfStatement();
3840  return Error(Loc, "unexpected token in argument list");
3841  }
3842  // Parse bracket and parenthesis suffixes before we iterate
3843  if (getLexer().is(AsmToken::LBrac)) {
3844  if (parseBracketSuffix(Name, Operands))
3845  return true;
3846  } else if (getLexer().is(AsmToken::LParen) &&
3847  parseParenSuffix(Name, Operands))
3848  return true;
3849  }
3850  }
3851  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3852  SMLoc Loc = getLexer().getLoc();
3853  Parser.eatToEndOfStatement();
3854  return Error(Loc, "unexpected token in argument list");
3855  }
3856  Parser.Lex(); // Consume the EndOfStatement.
3857  return false;
3858 }
3859 
3860 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3861  MCAsmParser &Parser = getParser();
3862  SMLoc Loc = getLexer().getLoc();
3863  Parser.eatToEndOfStatement();
3864  return Error(Loc, ErrorMsg);
3865 }
3866 
3867 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3868  return Error(Loc, ErrorMsg);
3869 }
3870 
3871 bool MipsAsmParser::parseSetNoAtDirective() {
3872  MCAsmParser &Parser = getParser();
3873  // Line should look like: ".set noat".
3874 
3875  // Set the $at register to $0.
3876  AssemblerOptions.back()->setATRegIndex(0);
3877 
3878  Parser.Lex(); // Eat "noat".
3879 
3880  // If this is not the end of the statement, report an error.
3881  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3882  reportParseError("unexpected token, expected end of statement");
3883  return false;
3884  }
3885 
3886  getTargetStreamer().emitDirectiveSetNoAt();
3887  Parser.Lex(); // Consume the EndOfStatement.
3888  return false;
3889 }
3890 
3891 bool MipsAsmParser::parseSetAtDirective() {
3892  // Line can be: ".set at", which sets $at to $1
3893  // or ".set at=$reg", which sets $at to $reg.
3894  MCAsmParser &Parser = getParser();
3895  Parser.Lex(); // Eat "at".
3896 
3897  if (getLexer().is(AsmToken::EndOfStatement)) {
3898  // No register was specified, so we set $at to $1.
3899  AssemblerOptions.back()->setATRegIndex(1);
3900 
3901  getTargetStreamer().emitDirectiveSetAt();
3902  Parser.Lex(); // Consume the EndOfStatement.
3903  return false;
3904  }
3905 
3906  if (getLexer().isNot(AsmToken::Equal)) {
3907  reportParseError("unexpected token, expected equals sign");
3908  return false;
3909  }
3910  Parser.Lex(); // Eat "=".
3911 
3912  if (getLexer().isNot(AsmToken::Dollar)) {
3913  if (getLexer().is(AsmToken::EndOfStatement)) {
3914  reportParseError("no register specified");
3915  return false;
3916  } else {
3917  reportParseError("unexpected token, expected dollar sign '$'");
3918  return false;
3919  }
3920  }
3921  Parser.Lex(); // Eat "$".
3922 
3923  // Find out what "reg" is.
3924  unsigned AtRegNo;
3925  const AsmToken &Reg = Parser.getTok();
3926  if (Reg.is(AsmToken::Identifier)) {
3927  AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3928  } else if (Reg.is(AsmToken::Integer)) {
3929  AtRegNo = Reg.getIntVal();
3930  } else {
3931  reportParseError("unexpected token, expected identifier or integer");
3932  return false;
3933  }
3934 
3935  // Check if $reg is a valid register. If it is, set $at to $reg.
3936  if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3937  reportParseError("invalid register");
3938  return false;
3939  }
3940  Parser.Lex(); // Eat "reg".
3941 
3942  // If this is not the end of the statement, report an error.
3943  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3944  reportParseError("unexpected token, expected end of statement");
3945  return false;
3946  }
3947 
3948  getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3949 
3950  Parser.Lex(); // Consume the EndOfStatement.
3951  return false;
3952 }
3953 
3954 bool MipsAsmParser::parseSetReorderDirective() {
3955  MCAsmParser &Parser = getParser();
3956  Parser.Lex();
3957  // If this is not the end of the statement, report an error.
3958  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3959  reportParseError("unexpected token, expected end of statement");
3960  return false;
3961  }
3962  AssemblerOptions.back()->setReorder();
3963  getTargetStreamer().emitDirectiveSetReorder();
3964  Parser.Lex(); // Consume the EndOfStatement.
3965  return false;
3966 }
3967 
3968 bool MipsAsmParser::parseSetNoReorderDirective() {
3969  MCAsmParser &Parser = getParser();
3970  Parser.Lex();
3971  // If this is not the end of the statement, report an error.
3972  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3973  reportParseError("unexpected token, expected end of statement");
3974  return false;
3975  }
3976  AssemblerOptions.back()->setNoReorder();
3977  getTargetStreamer().emitDirectiveSetNoReorder();
3978  Parser.Lex(); // Consume the EndOfStatement.
3979  return false;
3980 }
3981 
3982 bool MipsAsmParser::parseSetMacroDirective() {
3983  MCAsmParser &Parser = getParser();
3984  Parser.Lex();
3985  // If this is not the end of the statement, report an error.
3986  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3987  reportParseError("unexpected token, expected end of statement");
3988  return false;
3989  }
3990  AssemblerOptions.back()->setMacro();
3991  getTargetStreamer().emitDirectiveSetMacro();
3992  Parser.Lex(); // Consume the EndOfStatement.
3993  return false;
3994 }
3995 
3996 bool MipsAsmParser::parseSetNoMacroDirective() {
3997  MCAsmParser &Parser = getParser();
3998  Parser.Lex();
3999  // If this is not the end of the statement, report an error.
4000  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4001  reportParseError("unexpected token, expected end of statement");
4002  return false;
4003  }
4004  if (AssemblerOptions.back()->isReorder()) {
4005  reportParseError("`noreorder' must be set before `nomacro'");
4006  return false;
4007  }
4008  AssemblerOptions.back()->setNoMacro();
4009  getTargetStreamer().emitDirectiveSetNoMacro();
4010  Parser.Lex(); // Consume the EndOfStatement.
4011  return false;
4012 }
4013 
4014 bool MipsAsmParser::parseSetMsaDirective() {
4015  MCAsmParser &Parser = getParser();
4016  Parser.Lex();
4017 
4018  // If this is not the end of the statement, report an error.
4019  if (getLexer().isNot(AsmToken::EndOfStatement))
4020  return reportParseError("unexpected token, expected end of statement");
4021 
4022  setFeatureBits(Mips::FeatureMSA, "msa");
4023  getTargetStreamer().emitDirectiveSetMsa();
4024  return false;
4025 }
4026 
4027 bool MipsAsmParser::parseSetNoMsaDirective() {
4028  MCAsmParser &Parser = getParser();
4029  Parser.Lex();
4030 
4031  // If this is not the end of the statement, report an error.
4032  if (getLexer().isNot(AsmToken::EndOfStatement))
4033  return reportParseError("unexpected token, expected end of statement");
4034 
4035  clearFeatureBits(Mips::FeatureMSA, "msa");
4036  getTargetStreamer().emitDirectiveSetNoMsa();
4037  return false;
4038 }
4039 
4040 bool MipsAsmParser::parseSetNoDspDirective() {
4041  MCAsmParser &Parser = getParser();
4042  Parser.Lex(); // Eat "nodsp".
4043 
4044  // If this is not the end of the statement, report an error.
4045  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4046  reportParseError("unexpected token, expected end of statement");
4047  return false;
4048  }
4049 
4050  clearFeatureBits(Mips::FeatureDSP, "dsp");
4051  getTargetStreamer().emitDirectiveSetNoDsp();
4052  return false;
4053 }
4054 
4055 bool MipsAsmParser::parseSetMips16Directive() {
4056  MCAsmParser &Parser = getParser();
4057  Parser.Lex(); // Eat "mips16".
4058 
4059  // If this is not the end of the statement, report an error.
4060  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4061  reportParseError("unexpected token, expected end of statement");
4062  return false;
4063  }
4064 
4065  setFeatureBits(Mips::FeatureMips16, "mips16");
4066  getTargetStreamer().emitDirectiveSetMips16();
4067  Parser.Lex(); // Consume the EndOfStatement.
4068  return false;
4069 }
4070 
4071 bool MipsAsmParser::parseSetNoMips16Directive() {
4072  MCAsmParser &Parser = getParser();
4073  Parser.Lex(); // Eat "nomips16".
4074 
4075  // If this is not the end of the statement, report an error.
4076  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4077  reportParseError("unexpected token, expected end of statement");
4078  return false;
4079  }
4080 
4081  clearFeatureBits(Mips::FeatureMips16, "mips16");
4082  getTargetStreamer().emitDirectiveSetNoMips16();
4083  Parser.Lex(); // Consume the EndOfStatement.
4084  return false;
4085 }
4086 
4087 bool MipsAsmParser::parseSetFpDirective() {
4088  MCAsmParser &Parser = getParser();
4090  // Line can be: .set fp=32
4091  // .set fp=xx
4092  // .set fp=64
4093  Parser.Lex(); // Eat fp token
4094  AsmToken Tok = Parser.getTok();
4095  if (Tok.isNot(AsmToken::Equal)) {
4096  reportParseError("unexpected token, expected equals sign '='");
4097  return false;
4098  }
4099  Parser.Lex(); // Eat '=' token.
4100  Tok = Parser.getTok();
4101 
4102  if (!parseFpABIValue(FpAbiVal, ".set"))
4103  return false;
4104 
4105  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4106  reportParseError("unexpected token, expected end of statement");
4107  return false;
4108  }
4109  getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4110  Parser.Lex(); // Consume the EndOfStatement.
4111  return false;
4112 }
4113 
4114 bool MipsAsmParser::parseSetOddSPRegDirective() {
4115  MCAsmParser &Parser = getParser();
4116 
4117  Parser.Lex(); // Eat "oddspreg".
4118  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4119  reportParseError("unexpected token, expected end of statement");
4120  return false;
4121  }
4122 
4123  clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4124  getTargetStreamer().emitDirectiveSetOddSPReg();
4125  return false;
4126 }
4127 
4128 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4129  MCAsmParser &Parser = getParser();
4130 
4131  Parser.Lex(); // Eat "nooddspreg".
4132  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4133  reportParseError("unexpected token, expected end of statement");
4134  return false;
4135  }
4136 
4137  setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4138  getTargetStreamer().emitDirectiveSetNoOddSPReg();
4139  return false;
4140 }
4141 
4142 bool MipsAsmParser::parseSetPopDirective() {
4143  MCAsmParser &Parser = getParser();
4144  SMLoc Loc = getLexer().getLoc();
4145 
4146  Parser.Lex();
4147  if (getLexer().isNot(AsmToken::EndOfStatement))
4148  return reportParseError("unexpected token, expected end of statement");
4149 
4150  // Always keep an element on the options "stack" to prevent the user
4151  // from changing the initial options. This is how we remember them.
4152  if (AssemblerOptions.size() == 2)
4153  return reportParseError(Loc, ".set pop with no .set push");
4154 
4155  AssemblerOptions.pop_back();
4156  setAvailableFeatures(
4157  ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4158  STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4159 
4160  getTargetStreamer().emitDirectiveSetPop();
4161  return false;
4162 }
4163 
4164 bool MipsAsmParser::parseSetPushDirective() {
4165  MCAsmParser &Parser = getParser();
4166  Parser.Lex();
4167  if (getLexer().isNot(AsmToken::EndOfStatement))
4168  return reportParseError("unexpected token, expected end of statement");
4169 
4170  // Create a copy of the current assembler options environment and push it.
4171  AssemblerOptions.push_back(
4172  make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4173 
4174  getTargetStreamer().emitDirectiveSetPush();
4175  return false;
4176 }
4177 
4178 bool MipsAsmParser::parseSetSoftFloatDirective() {
4179  MCAsmParser &Parser = getParser();
4180  Parser.Lex();
4181  if (getLexer().isNot(AsmToken::EndOfStatement))
4182  return reportParseError("unexpected token, expected end of statement");
4183 
4184  setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4185  getTargetStreamer().emitDirectiveSetSoftFloat();
4186  return false;
4187 }
4188 
4189 bool MipsAsmParser::parseSetHardFloatDirective() {
4190  MCAsmParser &Parser = getParser();
4191  Parser.Lex();
4192  if (getLexer().isNot(AsmToken::EndOfStatement))
4193  return reportParseError("unexpected token, expected end of statement");
4194 
4195  clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4196  getTargetStreamer().emitDirectiveSetHardFloat();
4197  return false;
4198 }
4199 
4200 bool MipsAsmParser::parseSetAssignment() {
4201  StringRef Name;
4202  const MCExpr *Value;
4203  MCAsmParser &Parser = getParser();
4204 
4205  if (Parser.parseIdentifier(Name))
4206  reportParseError("expected identifier after .set");
4207 
4208  if (getLexer().isNot(AsmToken::Comma))
4209  return reportParseError("unexpected token, expected comma");
4210  Lex(); // Eat comma
4211 
4212  if (Parser.parseExpression(Value))
4213  return reportParseError("expected valid expression after comma");
4214 
4215  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4216  Sym->setVariableValue(Value);
4217 
4218  return false;
4219 }
4220 
4221 bool MipsAsmParser::parseSetMips0Directive() {
4222  MCAsmParser &Parser = getParser();
4223  Parser.Lex();
4224  if (getLexer().isNot(AsmToken::EndOfStatement))
4225  return reportParseError("unexpected token, expected end of statement");
4226 
4227  // Reset assembler options to their initial values.
4228  setAvailableFeatures(
4229  ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4230  STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4231  AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4232 
4233  getTargetStreamer().emitDirectiveSetMips0();
4234  return false;
4235 }
4236 
4237 bool MipsAsmParser::parseSetArchDirective() {
4238  MCAsmParser &Parser = getParser();
4239  Parser.Lex();
4240  if (getLexer().isNot(AsmToken::Equal))
4241  return reportParseError("unexpected token, expected equals sign");
4242 
4243  Parser.Lex();
4244  StringRef Arch;
4245  if (Parser.parseIdentifier(Arch))
4246  return reportParseError("expected arch identifier");
4247 
4248  StringRef ArchFeatureName =
4250  .Case("mips1", "mips1")
4251  .Case("mips2", "mips2")
4252  .Case("mips3", "mips3")
4253  .Case("mips4", "mips4")
4254  .Case("mips5", "mips5")
4255  .Case("mips32", "mips32")
4256  .Case("mips32r2", "mips32r2")
4257  .Case("mips32r3", "mips32r3")
4258  .Case("mips32r5", "mips32r5")
4259  .Case("mips32r6", "mips32r6")
4260  .Case("mips64", "mips64")
4261  .Case("mips64r2", "mips64r2")
4262  .Case("mips64r3", "mips64r3")
4263  .Case("mips64r5", "mips64r5")
4264  .Case("mips64r6", "mips64r6")
4265  .Case("cnmips", "cnmips")
4266  .Case("r4000", "mips3") // This is an implementation of Mips3.
4267  .Default("");
4268 
4269  if (ArchFeatureName.empty())
4270  return reportParseError("unsupported architecture");
4271 
4272  selectArch(ArchFeatureName);
4273  getTargetStreamer().emitDirectiveSetArch(Arch);
4274  return false;
4275 }
4276 
4277 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4278  MCAsmParser &Parser = getParser();
4279  Parser.Lex();
4280  if (getLexer().isNot(AsmToken::EndOfStatement))
4281  return reportParseError("unexpected token, expected end of statement");
4282 
4283  switch (Feature) {
4284  default:
4285  llvm_unreachable("Unimplemented feature");
4286  case Mips::FeatureDSP:
4287  setFeatureBits(Mips::FeatureDSP, "dsp");
4288  getTargetStreamer().emitDirectiveSetDsp();
4289  break;
4290  case Mips::FeatureMicroMips:
4291  getTargetStreamer().emitDirectiveSetMicroMips();
4292  break;
4293  case Mips::FeatureMips1:
4294  selectArch("mips1");
4295  getTargetStreamer().emitDirectiveSetMips1();
4296  break;
4297  case Mips::FeatureMips2:
4298  selectArch("mips2");
4299  getTargetStreamer().emitDirectiveSetMips2();
4300  break;
4301  case Mips::FeatureMips3:
4302  selectArch("mips3");
4303  getTargetStreamer().emitDirectiveSetMips3();
4304  break;
4305  case Mips::FeatureMips4:
4306  selectArch("mips4");
4307  getTargetStreamer().emitDirectiveSetMips4();
4308  break;
4309  case Mips::FeatureMips5:
4310  selectArch("mips5");
4311  getTargetStreamer().emitDirectiveSetMips5();
4312  break;
4313  case Mips::FeatureMips32:
4314  selectArch("mips32");
4315  getTargetStreamer().emitDirectiveSetMips32();
4316  break;
4317  case Mips::FeatureMips32r2:
4318  selectArch("mips32r2");
4319  getTargetStreamer().emitDirectiveSetMips32R2();
4320  break;
4321  case Mips::FeatureMips32r3:
4322  selectArch("mips32r3");
4323  getTargetStreamer().emitDirectiveSetMips32R3();
4324  break;
4325  case Mips::FeatureMips32r5:
4326  selectArch("mips32r5");
4327  getTargetStreamer().emitDirectiveSetMips32R5();
4328  break;
4329  case Mips::FeatureMips32r6:
4330  selectArch("mips32r6");
4331  getTargetStreamer().emitDirectiveSetMips32R6();
4332  break;
4333  case Mips::FeatureMips64:
4334  selectArch("mips64");
4335  getTargetStreamer().emitDirectiveSetMips64();
4336  break;
4337  case Mips::FeatureMips64r2:
4338  selectArch("mips64r2");
4339  getTargetStreamer().emitDirectiveSetMips64R2();
4340  break;
4341  case Mips::FeatureMips64r3:
4342  selectArch("mips64r3");
4343  getTargetStreamer().emitDirectiveSetMips64R3();
4344  break;
4345  case Mips::FeatureMips64r5:
4346  selectArch("mips64r5");
4347  getTargetStreamer().emitDirectiveSetMips64R5();
4348  break;
4349  case Mips::FeatureMips64r6:
4350  selectArch("mips64r6");
4351  getTargetStreamer().emitDirectiveSetMips64R6();
4352  break;
4353  }
4354  return false;
4355 }
4356 
4357 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4358  MCAsmParser &Parser = getParser();
4359  if (getLexer().isNot(AsmToken::Comma)) {
4360  SMLoc Loc = getLexer().getLoc();
4361  Parser.eatToEndOfStatement();
4362  return Error(Loc, ErrorStr);
4363  }
4364 
4365  Parser.Lex(); // Eat the comma.
4366  return true;
4367 }
4368 
4369 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4370  if (AssemblerOptions.back()->isReorder())
4371  Warning(Loc, ".cpload should be inside a noreorder section");
4372 
4373  if (inMips16Mode()) {
4374  reportParseError(".cpload is not supported in Mips16 mode");
4375  return false;
4376  }
4377 
4379  OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4380  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4381  reportParseError("expected register containing function address");
4382  return false;
4383  }
4384 
4385  MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4386  if (!RegOpnd.isGPRAsmReg()) {
4387  reportParseError(RegOpnd.getStartLoc(), "invalid register");
4388  return false;
4389  }
4390 
4391  // If this is not the end of the statement, report an error.
4392  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4393  reportParseError("unexpected token, expected end of statement");
4394  return false;
4395  }
4396 
4397  getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4398  return false;
4399 }
4400 
4401 bool MipsAsmParser::parseDirectiveCPSetup() {
4402  MCAsmParser &Parser = getParser();
4403  unsigned FuncReg;
4404  unsigned Save;
4405  bool SaveIsReg = true;
4406 
4408  OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4409  if (ResTy == MatchOperand_NoMatch) {
4410  reportParseError("expected register containing function address");
4411  Parser.eatToEndOfStatement();
4412  return false;
4413  }
4414 
4415  MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4416  if (!FuncRegOpnd.isGPRAsmReg()) {
4417  reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4418  Parser.eatToEndOfStatement();
4419  return false;
4420  }
4421 
4422  FuncReg = FuncRegOpnd.getGPR32Reg();
4423  TmpReg.clear();
4424 
4425  if (!eatComma("unexpected token, expected comma"))
4426  return true;
4427 
4428  ResTy = parseAnyRegister(TmpReg);
4429  if (ResTy == MatchOperand_NoMatch) {
4430  const AsmToken &Tok = Parser.getTok();
4431  if (Tok.is(AsmToken::Integer)) {
4432  Save = Tok.getIntVal();
4433  SaveIsReg = false;
4434  Parser.Lex();
4435  } else {
4436  reportParseError("expected save register or stack offset");
4437  Parser.eatToEndOfStatement();
4438  return false;
4439  }
4440  } else {
4441  MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4442  if (!SaveOpnd.isGPRAsmReg()) {
4443  reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4444  Parser.eatToEndOfStatement();
4445  return false;
4446  }
4447  Save = SaveOpnd.getGPR32Reg();
4448  }
4449 
4450  if (!eatComma("unexpected token, expected comma"))
4451  return true;
4452 
4453  const MCExpr *Expr;
4454  if (Parser.parseExpression(Expr)) {
4455  reportParseError("expected expression");
4456  return false;
4457  }
4458 
4459  if (Expr->getKind() != MCExpr::SymbolRef) {
4460  reportParseError("expected symbol");
4461  return false;
4462  }
4463  const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4464 
4465  getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4466  SaveIsReg);
4467  return false;
4468 }
4469 
4470 bool MipsAsmParser::parseDirectiveNaN() {
4471  MCAsmParser &Parser = getParser();
4472  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4473  const AsmToken &Tok = Parser.getTok();
4474 
4475  if (Tok.getString() == "2008") {
4476  Parser.Lex();
4477  getTargetStreamer().emitDirectiveNaN2008();
4478  return false;
4479  } else if (Tok.getString() == "legacy") {
4480  Parser.Lex();
4481  getTargetStreamer().emitDirectiveNaNLegacy();
4482  return false;
4483  }
4484  }
4485  // If we don't recognize the option passed to the .nan
4486  // directive (e.g. no option or unknown option), emit an error.
4487  reportParseError("invalid option in .nan directive");
4488  return false;
4489 }
4490 
4491 bool MipsAsmParser::parseDirectiveSet() {
4492  MCAsmParser &Parser = getParser();
4493  // Get the next token.
4494  const AsmToken &Tok = Parser.getTok();
4495 
4496  if (Tok.getString() == "noat") {
4497  return parseSetNoAtDirective();
4498  } else if (Tok.getString() == "at") {
4499  return parseSetAtDirective();
4500  } else if (Tok.getString() == "arch") {
4501  return parseSetArchDirective();
4502  } else if (Tok.getString() == "fp") {
4503  return parseSetFpDirective();
4504  } else if (Tok.getString() == "oddspreg") {
4505  return parseSetOddSPRegDirective();
4506  } else if (Tok.getString() == "nooddspreg") {
4507  return parseSetNoOddSPRegDirective();
4508  } else if (Tok.getString() == "pop") {
4509  return parseSetPopDirective();
4510  } else if (Tok.getString() == "push") {
4511  return parseSetPushDirective();
4512  } else if (Tok.getString() == "reorder") {
4513  return parseSetReorderDirective();
4514  } else if (Tok.getString() == "noreorder") {
4515  return parseSetNoReorderDirective();
4516  } else if (Tok.getString() == "macro") {
4517  return parseSetMacroDirective();
4518  } else if (Tok.getString() == "nomacro") {
4519  return parseSetNoMacroDirective();
4520  } else if (Tok.getString() == "mips16") {
4521  return parseSetMips16Directive();
4522  } else if (Tok.getString() == "nomips16") {
4523  return parseSetNoMips16Directive();
4524  } else if (Tok.getString() == "nomicromips") {
4525  getTargetStreamer().emitDirectiveSetNoMicroMips();
4526  Parser.eatToEndOfStatement();
4527  return false;
4528  } else if (Tok.getString() == "micromips") {
4529  return parseSetFeature(Mips::FeatureMicroMips);
4530  } else if (Tok.getString() == "mips0") {
4531  return parseSetMips0Directive();
4532  } else if (Tok.getString() == "mips1") {
4533  return parseSetFeature(Mips::FeatureMips1);
4534  } else if (Tok.getString() == "mips2") {
4535  return parseSetFeature(Mips::FeatureMips2);
4536  } else if (Tok.getString() == "mips3") {
4537  return parseSetFeature(Mips::FeatureMips3);
4538  } else if (Tok.getString() == "mips4") {
4539  return parseSetFeature(Mips::FeatureMips4);
4540  } else if (Tok.getString() == "mips5") {
4541  return parseSetFeature(Mips::FeatureMips5);
4542  } else if (Tok.getString() == "mips32") {
4543  return parseSetFeature(Mips::FeatureMips32);
4544  } else if (Tok.getString() == "mips32r2") {
4545  return parseSetFeature(Mips::FeatureMips32r2);
4546  } else if (Tok.getString() == "mips32r3") {
4547  return parseSetFeature(Mips::FeatureMips32r3);
4548  } else if (Tok.getString() == "mips32r5") {
4549  return parseSetFeature(Mips::FeatureMips32r5);
4550  } else if (Tok.getString() == "mips32r6") {
4551  return parseSetFeature(Mips::FeatureMips32r6);
4552  } else if (Tok.getString() == "mips64") {
4553  return parseSetFeature(Mips::FeatureMips64);
4554  } else if (Tok.getString() == "mips64r2") {
4555  return parseSetFeature(Mips::FeatureMips64r2);
4556  } else if (Tok.getString() == "mips64r3") {
4557  return parseSetFeature(Mips::FeatureMips64r3);
4558  } else if (Tok.getString() == "mips64r5") {
4559  return parseSetFeature(Mips::FeatureMips64r5);
4560  } else if (Tok.getString() == "mips64r6") {
4561  return parseSetFeature(Mips::FeatureMips64r6);
4562  } else if (Tok.getString() == "dsp") {
4563  return parseSetFeature(Mips::FeatureDSP);
4564  } else if (Tok.getString() == "nodsp") {
4565  return parseSetNoDspDirective();
4566  } else if (Tok.getString() == "msa") {
4567  return parseSetMsaDirective();
4568  } else if (Tok.getString() == "nomsa") {
4569  return parseSetNoMsaDirective();
4570  } else if (Tok.getString() == "softfloat") {
4571  return parseSetSoftFloatDirective();
4572  } else if (Tok.getString() == "hardfloat") {
4573  return parseSetHardFloatDirective();
4574  } else {
4575  // It is just an identifier, look for an assignment.
4576  parseSetAssignment();
4577  return false;
4578  }
4579 
4580  return true;
4581 }
4582 
4583 /// parseDataDirective
4584 /// ::= .word [ expression (, expression)* ]
4585 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4586  MCAsmParser &Parser = getParser();
4587  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4588  for (;;) {
4589  const MCExpr *Value;
4590  if (getParser().parseExpression(Value))
4591  return true;
4592 
4593  getParser().getStreamer().EmitValue(Value, Size);
4594 
4595  if (getLexer().is(AsmToken::EndOfStatement))
4596  break;
4597 
4598  if (getLexer().isNot(AsmToken::Comma))
4599  return Error(L, "unexpected token, expected comma");
4600  Parser.Lex();
4601  }
4602  }
4603 
4604  Parser.Lex();
4605  return false;
4606 }
4607 
4608 /// parseDirectiveGpWord
4609 /// ::= .gpword local_sym
4610 bool MipsAsmParser::parseDirectiveGpWord() {
4611  MCAsmParser &Parser = getParser();
4612  const MCExpr *Value;
4613  // EmitGPRel32Value requires an expression, so we are using base class
4614  // method to evaluate the expression.
4615  if (getParser().parseExpression(Value))
4616  return true;
4617  getParser().getStreamer().EmitGPRel32Value(Value);
4618 
4619  if (getLexer().isNot(AsmToken::EndOfStatement))
4620  return Error(getLexer().getLoc(),
4621  "unexpected token, expected end of statement");
4622  Parser.Lex(); // Eat EndOfStatement token.
4623  return false;
4624 }
4625 
4626 /// parseDirectiveGpDWord
4627 /// ::= .gpdword local_sym
4628 bool MipsAsmParser::parseDirectiveGpDWord() {
4629  MCAsmParser &Parser = getParser();
4630  const MCExpr *Value;
4631  // EmitGPRel64Value requires an expression, so we are using base class
4632  // method to evaluate the expression.
4633  if (getParser().parseExpression(Value))
4634  return true;
4635  getParser().getStreamer().EmitGPRel64Value(Value);
4636 
4637  if (getLexer().isNot(AsmToken::EndOfStatement))
4638  return Error(getLexer().getLoc(),
4639  "unexpected token, expected end of statement");
4640  Parser.Lex(); // Eat EndOfStatement token.
4641  return false;
4642 }
4643 
4644 bool MipsAsmParser::parseDirectiveOption() {
4645  MCAsmParser &Parser = getParser();
4646  // Get the option token.
4647  AsmToken Tok = Parser.getTok();
4648  // At the moment only identifiers are supported.
4649  if (Tok.isNot(AsmToken::Identifier)) {
4650  Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4651  Parser.eatToEndOfStatement();
4652  return false;
4653  }
4654 
4655  StringRef Option = Tok.getIdentifier();
4656 
4657  if (Option == "pic0") {
4658  getTargetStreamer().emitDirectiveOptionPic0();
4659  Parser.Lex();
4660  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4661  Error(Parser.getTok().getLoc(),
4662  "unexpected token, expected end of statement");
4663  Parser.eatToEndOfStatement();
4664  }
4665  return false;
4666  }
4667 
4668  if (Option == "pic2") {
4669  getTargetStreamer().emitDirectiveOptionPic2();
4670  Parser.Lex();
4671  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4672  Error(Parser.getTok().getLoc(),
4673  "unexpected token, expected end of statement");
4674  Parser.eatToEndOfStatement();
4675  }
4676  return false;
4677  }
4678 
4679  // Unknown option.
4680  Warning(Parser.getTok().getLoc(),
4681  "unknown option, expected 'pic0' or 'pic2'");
4682  Parser.eatToEndOfStatement();
4683  return false;
4684 }
4685 
4686 /// parseInsnDirective
4687 /// ::= .insn
4688 bool MipsAsmParser::parseInsnDirective() {
4689  // If this is not the end of the statement, report an error.
4690  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4691  reportParseError("unexpected token, expected end of statement");
4692  return false;
4693  }
4694 
4695  // The actual label marking happens in
4696  // MipsELFStreamer::createPendingLabelRelocs().
4697  getTargetStreamer().emitDirectiveInsn();
4698 
4699  getParser().Lex(); // Eat EndOfStatement token.
4700  return false;
4701 }
4702 
4703 /// parseDirectiveModule
4704 /// ::= .module oddspreg
4705 /// ::= .module nooddspreg
4706 /// ::= .module fp=value
4707 /// ::= .module softfloat
4708 /// ::= .module hardfloat
4709 bool MipsAsmParser::parseDirectiveModule() {
4710  MCAsmParser &Parser = getParser();
4711  MCAsmLexer &Lexer = getLexer();
4712  SMLoc L = Lexer.getLoc();
4713 
4714  if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4715  // TODO : get a better message.
4716  reportParseError(".module directive must appear before any code");
4717  return false;
4718  }
4719 
4720  StringRef Option;
4721  if (Parser.parseIdentifier(Option)) {
4722  reportParseError("expected .module option identifier");
4723  return false;
4724  }
4725 
4726  if (Option == "oddspreg") {
4727  clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4728 
4729  // Synchronize the abiflags information with the FeatureBits information we
4730  // changed above.
4731  getTargetStreamer().updateABIInfo(*this);
4732 
4733  // If printing assembly, use the recently updated abiflags information.
4734  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4735  // emitted at the end).
4736  getTargetStreamer().emitDirectiveModuleOddSPReg();
4737 
4738  // If this is not the end of the statement, report an error.
4739  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4740  reportParseError("unexpected token, expected end of statement");
4741  return false;
4742  }
4743 
4744  return false; // parseDirectiveModule has finished successfully.
4745  } else if (Option == "nooddspreg") {
4746  if (!isABI_O32()) {
4747  Error(L, "'.module nooddspreg' requires the O32 ABI");
4748  return false;
4749  }
4750 
4751  setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4752 
4753  // Synchronize the abiflags information with the FeatureBits information we
4754  // changed above.
4755  getTargetStreamer().updateABIInfo(*this);
4756 
4757  // If printing assembly, use the recently updated abiflags information.
4758  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4759  // emitted at the end).
4760  getTargetStreamer().emitDirectiveModuleOddSPReg();
4761 
4762  // If this is not the end of the statement, report an error.
4763  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4764  reportParseError("unexpected token, expected end of statement");
4765  return false;
4766  }
4767 
4768  return false; // parseDirectiveModule has finished successfully.
4769  } else if (Option == "fp") {
4770  return parseDirectiveModuleFP();
4771  } else if (Option == "softfloat") {
4772  setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4773 
4774  // Synchronize the ABI Flags information with the FeatureBits information we
4775  // updated above.
4776  getTargetStreamer().updateABIInfo(*this);
4777 
4778  // If printing assembly, use the recently updated ABI Flags information.
4779  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4780  // emitted later).
4781  getTargetStreamer().emitDirectiveModuleSoftFloat();
4782 
4783  // If this is not the end of the statement, report an error.
4784  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4785  reportParseError("unexpected token, expected end of statement");
4786  return false;
4787  }
4788 
4789  return false; // parseDirectiveModule has finished successfully.
4790  } else if (Option == "hardfloat") {
4791  clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4792 
4793  // Synchronize the ABI Flags information with the FeatureBits information we
4794  // updated above.
4795  getTargetStreamer().updateABIInfo(*this);
4796 
4797  // If printing assembly, use the recently updated ABI Flags information.
4798  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4799  // emitted later).
4800  getTargetStreamer().emitDirectiveModuleHardFloat();
4801 
4802  // If this is not the end of the statement, report an error.
4803  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4804  reportParseError("unexpected token, expected end of statement");
4805  return false;
4806  }
4807 
4808  return false; // parseDirectiveModule has finished successfully.
4809  } else {
4810  return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4811  }
4812 }
4813 
4814 /// parseDirectiveModuleFP
4815 /// ::= =32
4816 /// ::= =xx
4817 /// ::= =64
4818 bool MipsAsmParser::parseDirectiveModuleFP() {
4819  MCAsmParser &Parser = getParser();
4820  MCAsmLexer &Lexer = getLexer();
4821 
4822  if (Lexer.isNot(AsmToken::Equal)) {
4823  reportParseError("unexpected token, expected equals sign '='");
4824  return false;
4825  }
4826  Parser.Lex(); // Eat '=' token.
4827 
4829  if (!parseFpABIValue(FpABI, ".module"))
4830  return false;
4831 
4832  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4833  reportParseError("unexpected token, expected end of statement");
4834  return false;
4835  }
4836 
4837  // Synchronize the abiflags information with the FeatureBits information we
4838  // changed above.
4839  getTargetStreamer().updateABIInfo(*this);
4840 
4841  // If printing assembly, use the recently updated abiflags information.
4842  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4843  // emitted at the end).
4844  getTargetStreamer().emitDirectiveModuleFP();
4845 
4846  Parser.Lex(); // Consume the EndOfStatement.
4847  return false;
4848 }
4849 
4850 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4851  StringRef Directive) {
4852  MCAsmParser &Parser = getParser();
4853  MCAsmLexer &Lexer = getLexer();
4854  bool ModuleLevelOptions = Directive == ".module";
4855 
4856  if (Lexer.is(AsmToken::Identifier)) {
4857  StringRef Value = Parser.getTok().getString();
4858  Parser.Lex();
4859 
4860  if (Value != "xx") {
4861  reportParseError("unsupported value, expected 'xx', '32' or '64'");
4862  return false;
4863  }
4864 
4865  if (!isABI_O32()) {
4866  reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4867  return false;
4868  }
4869 
4871  if (ModuleLevelOptions) {
4872  setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4873  clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4874  } else {
4875  setFeatureBits(Mips::FeatureFPXX, "fpxx");
4876  clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4877  }
4878  return true;
4879  }
4880 
4881  if (Lexer.is(AsmToken::Integer)) {
4882  unsigned Value = Parser.getTok().getIntVal();
4883  Parser.Lex();
4884 
4885  if (Value != 32 && Value != 64) {
4886  reportParseError("unsupported value, expected 'xx', '32' or '64'");
4887  return false;
4888  }
4889 
4890  if (Value == 32) {
4891  if (!isABI_O32()) {
4892  reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4893  return false;
4894  }
4895 
4897  if (ModuleLevelOptions) {
4898  clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4899  clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4900  } else {
4901  clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4902  clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4903  }
4904  } else {
4906  if (ModuleLevelOptions) {
4907  clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4908  setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4909  } else {
4910  clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4911  setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4912  }
4913  }
4914 
4915  return true;
4916  }
4917 
4918  return false;
4919 }
4920 
4921 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4922  MCAsmParser &Parser = getParser();
4923  StringRef IDVal = DirectiveID.getString();
4924 
4925  if (IDVal == ".cpload")
4926  return parseDirectiveCpLoad(DirectiveID.getLoc());
4927  if (IDVal == ".dword") {
4928  parseDataDirective(8, DirectiveID.getLoc());
4929  return false;
4930  }
4931  if (IDVal == ".ent") {
4932  StringRef SymbolName;
4933 
4934  if (Parser.parseIdentifier(SymbolName)) {
4935  reportParseError("expected identifier after .ent");
4936  return false;
4937  }
4938 
4939  // There's an undocumented extension that allows an integer to
4940  // follow the name of the procedure which AFAICS is ignored by GAS.
4941  // Example: .ent foo,2
4942  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4943  if (getLexer().isNot(AsmToken::Comma)) {
4944  // Even though we accept this undocumented extension for compatibility
4945  // reasons, the additional integer argument does not actually change
4946  // the behaviour of the '.ent' directive, so we would like to discourage
4947  // its use. We do this by not referring to the extended version in
4948  // error messages which are not directly related to its use.
4949  reportParseError("unexpected token, expected end of statement");
4950  return false;
4951  }
4952  Parser.Lex(); // Eat the comma.
4953  const MCExpr *DummyNumber;
4954  int64_t DummyNumberVal;
4955  // If the user was explicitly trying to use the extended version,
4956  // we still give helpful extension-related error messages.
4957  if (Parser.parseExpression(DummyNumber)) {
4958  reportParseError("expected number after comma");
4959  return false;
4960  }
4961  if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4962  reportParseError("expected an absolute expression after comma");
4963  return false;
4964  }
4965  }
4966 
4967  // If this is not the end of the statement, report an error.
4968  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4969  reportParseError("unexpected token, expected end of statement");
4970  return false;
4971  }
4972 
4973  MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4974 
4975  getTargetStreamer().emitDirectiveEnt(*Sym);
4976  CurrentFn = Sym;
4977  return false;
4978  }
4979 
4980  if (IDVal == ".end") {
4981  StringRef SymbolName;
4982 
4983  if (Parser.parseIdentifier(SymbolName)) {
4984  reportParseError("expected identifier after .end");
4985  return false;
4986  }
4987 
4988  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4989  reportParseError("unexpected token, expected end of statement");
4990  return false;
4991  }
4992 
4993  if (CurrentFn == nullptr) {
4994  reportParseError(".end used without .ent");
4995  return false;
4996  }
4997 
4998  if ((SymbolName != CurrentFn->getName())) {
4999  reportParseError(".end symbol does not match .ent symbol");
5000  return false;
5001  }
5002 
5003  getTargetStreamer().emitDirectiveEnd(SymbolName);
5004  CurrentFn = nullptr;
5005  return false;
5006  }
5007 
5008  if (IDVal == ".frame") {
5009  // .frame $stack_reg, frame_size_in_bytes, $return_reg
5011  OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5012  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5013  reportParseError("expected stack register");
5014  return false;
5015  }
5016 
5017  MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5018  if (!StackRegOpnd.isGPRAsmReg()) {
5019  reportParseError(StackRegOpnd.getStartLoc(),
5020  "expected general purpose register");
5021  return false;
5022  }
5023  unsigned StackReg = StackRegOpnd.getGPR32Reg();
5024 
5025  if (Parser.getTok().is(AsmToken::Comma))
5026  Parser.Lex();
5027  else {
5028  reportParseError("unexpected token, expected comma");
5029  return false;
5030  }
5031 
5032  // Parse the frame size.
5033  const MCExpr *FrameSize;
5034  int64_t FrameSizeVal;
5035 
5036  if (Parser.parseExpression(FrameSize)) {
5037  reportParseError("expected frame size value");
5038  return false;
5039  }
5040 
5041  if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5042  reportParseError("frame size not an absolute expression");
5043  return false;
5044  }
5045 
5046  if (Parser.getTok().is(AsmToken::Comma))
5047  Parser.Lex();
5048  else {
5049  reportParseError("unexpected token, expected comma");
5050  return false;
5051  }
5052 
5053  // Parse the return register.
5054  TmpReg.clear();
5055  ResTy = parseAnyRegister(TmpReg);
5056  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5057  reportParseError("expected return register");
5058  return false;
5059  }
5060 
5061  MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5062  if (!ReturnRegOpnd.isGPRAsmReg()) {
5063  reportParseError(ReturnRegOpnd.getStartLoc(),
5064  "expected general purpose register");
5065  return false;
5066  }
5067 
5068  // If this is not the end of the statement, report an error.
5069  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5070  reportParseError("unexpected token, expected end of statement");
5071  return false;
5072  }
5073 
5074  getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5075  ReturnRegOpnd.getGPR32Reg());
5076  return false;
5077  }
5078 
5079  if (IDVal == ".set") {
5080  return parseDirectiveSet();
5081  }
5082 
5083  if (IDVal == ".mask" || IDVal == ".fmask") {
5084  // .mask bitmask, frame_offset
5085  // bitmask: One bit for each register used.
5086  // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5087  // first register is expected to be saved.
5088  // Examples:
5089  // .mask 0x80000000, -4
5090  // .fmask 0x80000000, -4
5091  //
5092 
5093  // Parse the bitmask
5094  const MCExpr *BitMask;
5095  int64_t BitMaskVal;
5096 
5097  if (Parser.parseExpression(BitMask)) {
5098  reportParseError("expected bitmask value");
5099  return false;
5100  }
5101 
5102  if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5103  reportParseError("bitmask not an absolute expression");
5104  return false;
5105  }
5106 
5107  if (Parser.getTok().is(AsmToken::Comma))
5108  Parser.Lex();
5109  else {
5110  reportParseError("unexpected token, expected comma");
5111  return false;
5112  }
5113 
5114  // Parse the frame_offset
5115  const MCExpr *FrameOffset;
5116  int64_t FrameOffsetVal;
5117 
5118  if (Parser.parseExpression(FrameOffset)) {
5119  reportParseError("expected frame offset value");
5120  return false;
5121  }
5122 
5123  if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5124  reportParseError("frame offset not an absolute expression");
5125  return false;
5126  }
5127 
5128  // If this is not the end of the statement, report an error.
5129  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5130  reportParseError("unexpected token, expected end of statement");
5131  return false;
5132  }
5133 
5134  if (IDVal == ".mask")
5135  getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5136  else
5137  getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5138  return false;
5139  }
5140 
5141  if (IDVal == ".nan")
5142  return parseDirectiveNaN();
5143 
5144  if (IDVal == ".gpword") {
5145  parseDirectiveGpWord();
5146  return false;
5147  }
5148 
5149  if (IDVal == ".gpdword") {
5150  parseDirectiveGpDWord();
5151  return false;
5152  }
5153 
5154  if (IDVal == ".word") {
5155  parseDataDirective(4, DirectiveID.getLoc());
5156  return false;
5157  }
5158 
5159  if (IDVal == ".option")
5160  return parseDirectiveOption();
5161 
5162  if (IDVal == ".abicalls") {
5163  getTargetStreamer().emitDirectiveAbiCalls();
5164  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5165  Error(Parser.getTok().getLoc(),
5166  "unexpected token, expected end of statement");
5167  // Clear line
5168  Parser.eatToEndOfStatement();
5169  }
5170  return false;
5171  }
5172 
5173  if (IDVal == ".cpsetup")
5174  return parseDirectiveCPSetup();
5175 
5176  if (IDVal == ".module")
5177  return parseDirectiveModule();
5178 
5179  if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5180  return parseInternalDirectiveReallowModule();
5181 
5182  if (IDVal == ".insn")
5183  return parseInsnDirective();
5184 
5185  return true;
5186 }
5187 
5188 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5189  // If this is not the end of the statement, report an error.
5190  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5191  reportParseError("unexpected token, expected end of statement");
5192  return false;
5193  }
5194 
5195  getTargetStreamer().reallowModuleDirective();
5196 
5197  getParser().Lex(); // Eat EndOfStatement token.
5198  return false;
5199 }
5200 
5201 extern "C" void LLVMInitializeMipsAsmParser() {
5206 }
5207 
5208 #define GET_REGISTER_MATCHER
5209 #define GET_MATCHER_IMPLEMENTATION
5210 #include "MipsGenAsmMatcher.inc"
static bool isReg(const MCInst &MI, unsigned OpNo)
bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:276
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:347
Represents a range in source code.
Definition: SMLoc.h:47
static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx)
Definition: MCExpr.cpp:145
const MCSymbol & getSymbol() const
Definition: MCExpr.h:328
virtual const AsmToken peekTok(bool ShouldSkipSpace=true)=0
Look ahead at the next token to be lexed.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
const char * getPointer() const
Definition: SMLoc.h:33
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
TokenKind getKind() const
Definition: MCAsmLexer.h:71
void clear()
Definition: MCInst.h:172
bool isReg() const
Definition: MCInst.h:56
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:64
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
MCTargetAsmParser - Generic interface to target specific assembly parsers.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:356
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:138
Target specific streamer interface.
Definition: MCStreamer.h:73
ExprKind getKind() const
Definition: MCExpr.h:69
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmLexer.h:100
const FeatureBitset Features
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:405
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool isNot(TokenKind K) const
Definition: MCAsmLexer.h:73
SMLoc getLoc() const
Get the current source location.
Definition: MCAsmLexer.cpp:22
static const MCInstrDesc & getInstDesc(unsigned Opcode)
#define op(i)
StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:55
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:639
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
SMLoc Start
Definition: SMLoc.h:49
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.cpp:140
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:119
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags)
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
Definition: MCSymbol.h:299
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
Definition: MCInstrDesc.h:233
bool isCall() const
Return true if the instruction is a call.
Definition: MCInstrDesc.h:214
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Definition: MCAsmLexer.h:22
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
Windows NT (Windows on ARM)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:317
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
This file implements a class to represent arbitrary precision integral constant values and operations...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:68
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:184
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
Target TheMips64elTarget
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:107
Unary assembler expressions.
Definition: MCExpr.h:352
static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, const SmallVectorImpl< BasicBlock * > &ExitBlocks, PredIteratorCache &PredCache, LoopInfo *LI)
Given an instruction in the loop, check to see if it has any uses that are outside the current loop...
Definition: LCSSA.cpp:62
int64_t getIntVal() const
Definition: MCAsmLexer.h:105
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:32
Unary expressions.
Definition: MCExpr.h:39
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
Target TheMips64Target
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isImm() const
Definition: MCInst.h:57
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
const MCExpr * getExpr() const
Definition: MCInst.h:93
void setImm(int64_t Val)
Definition: MCInst.h:78
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
#define true
Definition: ConvertUTF.c:66
Streaming machine code generation interface.
Definition: MCStreamer.h:157
static bool isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK, const MCBinaryExpr *BE)
Definition: MipsMCExpr.cpp:20
BranchInst - Conditional or Unconditional Branch instruction.
int64_t getValue() const
Definition: MCExpr.h:145
bool IsN32() const
Definition: MipsABIInfo.h:44
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
virtual MCAsmLexer & getLexer()=0
bool isExpr() const
Definition: MCInst.h:59
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
SI Fold Operands
Represents a single fixit, a replacement of one range of text with another.
Definition: SourceMgr.h:200
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:321
Binary assembler expressions.
Definition: MCExpr.h:405
void setLoc(SMLoc loc)
Definition: MCInst.h:161
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:181
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
static const MipsMCExpr * create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:44
static unsigned getRegClass(bool IsVgpr, unsigned RegWidth)
void setOpcode(unsigned Op)
Definition: MCInst.h:158
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:215
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:412
SMRange getLocRange() const
Definition: MCAsmLexer.cpp:34
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:350
bool is(TokenKind K) const
Definition: MCAsmLexer.h:72
void setVariableValue(const MCExpr *Value)
Definition: MCSymbol.cpp:40
R Default(const T &Value) const
Definition: StringSwitch.h:111
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
unsigned getOpcode() const
Definition: MCInst.h:159
bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:302
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:285
int64_t getImm() const
Definition: MCInst.h:74
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:35
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
Definition: MCAsmLexer.h:89
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:62
unsigned getNumOperands() const
Definition: MCInst.h:166
#define N
MCSubtargetInfo - Generic base class for all target subtargets.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Definition: MCInstrDesc.h:286
References to labels and assigned expressions.
Definition: MCExpr.h:38
static bool isMem(const MachineInstr *MI, unsigned Op)
Definition: X86InstrInfo.h:147
bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:272
const Triple & getTargetTriple() const
getTargetTriple - Return the target triple string.
Target TheMipselTarget
static bool hasShortDelaySlot(unsigned Opcode)
const MCInstrDesc MipsInsts[]
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:294
VariantKind getKind() const
Definition: MCExpr.h:330
char front() const
front - Get the first character in the string.
Definition: StringRef.h:116
const ARM::ArchExtKind Kind
LLVM Value Representation.
Definition: Value.h:69
Constant expressions.
Definition: MCExpr.h:37
Binary expressions.
Definition: MCExpr.h:36
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:185
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:149
bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:298
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: MathExtras.h:616
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
static TraceState * TS
#define DEBUG(X)
Definition: Debug.h:92
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
static FeatureBitset getFeatures(StringRef CPU, StringRef FS, ArrayRef< SubtargetFeatureKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Target specific expression.
Definition: MCExpr.h:40
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Represents a location in source code.
Definition: SMLoc.h:23
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:56
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:150
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164
Target TheMipsTarget
void LLVMInitializeMipsAsmParser()
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110