Coverage Report

Created: 2026-08-31 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/keystone/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Line
Count
Source
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
10
#include "MCTargetDesc/MipsABIInfo.h"
11
#include "MCTargetDesc/MipsMCExpr.h"
12
#include "MCTargetDesc/MipsMCTargetDesc.h"
13
#include "MipsTargetStreamer.h"
14
#include "llvm/ADT/APInt.h"
15
#include "llvm/ADT/SmallVector.h"
16
#include "llvm/ADT/StringSwitch.h"
17
#include "llvm/ADT/STLExtras.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"
22
#include "llvm/MC/MCInstrDesc.h"
23
#include "llvm/MC/MCParser/MCAsmLexer.h"
24
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
26
#include "llvm/MC/MCStreamer.h"
27
#include "llvm/MC/MCSubtargetInfo.h"
28
#include "llvm/MC/MCSymbol.h"
29
#include "llvm/Support/Debug.h"
30
#include "llvm/Support/MathExtras.h"
31
#include "llvm/Support/SourceMgr.h"
32
#include "llvm/Support/TargetRegistry.h"
33
#include "llvm/Support/raw_ostream.h"
34
#include <memory>
35
36
#include "keystone/mips.h"
37
38
using namespace llvm_ks;
39
40
#define DEBUG_TYPE "mips-asm-parser"
41
42
namespace llvm_ks {
43
class MCInstrInfo;
44
}
45
46
namespace {
47
class MipsAssemblerOptions {
48
public:
49
  MipsAssemblerOptions(const FeatureBitset &Features_) :
50
13.6k
    ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
51
52
11
  MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
53
11
    ATReg = Opts->getATRegIndex();
54
11
    Reorder = Opts->isReorder();
55
11
    Macro = Opts->isMacro();
56
11
    Features = Opts->getFeatures();
57
11
  }
58
59
6.30k
  unsigned getATRegIndex() const { return ATReg; }
60
413
  bool setATRegIndex(unsigned Reg) {
61
413
    if (Reg > 31)
62
132
      return false;
63
64
281
    ATReg = Reg;
65
281
    return true;
66
413
  }
67
68
12.1k
  bool isReorder() const { return Reorder; }
69
69
  void setReorder() { Reorder = true; }
70
106
  void setNoReorder() { Reorder = false; }
71
72
838
  bool isMacro() const { return Macro; }
73
31
  void setMacro() { Macro = true; }
74
0
  void setNoMacro() { Macro = false; }
75
76
1.05k
  const FeatureBitset &getFeatures() const { return Features; }
77
9.80k
  void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
78
79
  // Set of features that are either architecture features or referenced
80
  // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
81
  // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
82
  // The reason we need this mask is explained in the selectArch function.
83
  // FIXME: Ideally we would like TableGen to generate this information.
84
  static const FeatureBitset AllArchRelatedMask;
85
86
private:
87
  unsigned ATReg;
88
  bool Reorder;
89
  bool Macro;
90
  FeatureBitset Features;
91
};
92
}
93
94
const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
95
    Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
96
    Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
97
    Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
98
    Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
99
    Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
100
    Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
101
    Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
102
    Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103
};
104
105
namespace {
106
class MipsAsmParser : public MCTargetAsmParser {
107
0
  MipsTargetStreamer &getTargetStreamer() {
108
0
    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
109
0
    return static_cast<MipsTargetStreamer &>(TS);
110
0
  }
111
112
  MipsABIInfo ABI;
113
  SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
114
  MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
115
                       // nullptr, which indicates that no function is currently
116
                       // selected. This usually happens after an '.end func'
117
                       // directive.
118
  bool IsLittleEndian;
119
  bool IsPicEnabled;
120
  bool IsCpRestoreSet;
121
  int CpRestoreOffset;
122
  unsigned CpSaveLocation;
123
  /// If true, then CpSaveLocation is a register, otherwise it's an offset.
124
  bool     CpSaveLocationIsRegister;
125
126
  // Print a warning along with its fix-it message at the given range.
127
  void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
128
                             SMRange Range, bool ShowColors = true);
129
130
#define GET_ASSEMBLER_HEADER
131
#include "MipsGenAsmMatcher.inc"
132
133
  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
134
135
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
136
                               OperandVector &Operands, MCStreamer &Out,
137
                               uint64_t &ErrorInfo,
138
                               bool MatchingInlineAsm, unsigned int &ErrorCode, uint64_t &Address) override;
139
140
  /// Parse a register as used in CFI directives
141
  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, unsigned int &ErrorCode) override;
142
143
  bool parseParenSuffix(StringRef Name, OperandVector &Operands, unsigned int &ErrorCode);
144
145
  bool parseBracketSuffix(StringRef Name, OperandVector &Operands, unsigned int &ErrorCode);
146
147
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
148
                        SMLoc NameLoc, OperandVector &Operands, unsigned int &ErrorCode) override;
149
150
  bool ParseDirective(AsmToken DirectiveID) override;
151
152
  OperandMatchResultTy parseMemOperand(OperandVector &Operands);
153
  OperandMatchResultTy
154
  matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
155
                                    StringRef Identifier, SMLoc S);
156
  OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
157
                                                     SMLoc S);
158
  OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
159
  OperandMatchResultTy parseImm(OperandVector &Operands);
160
  OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
161
  OperandMatchResultTy parseInvNum(OperandVector &Operands);
162
  OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
163
  OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
164
  OperandMatchResultTy parseRegisterList(OperandVector &Operands);
165
166
  bool searchSymbolAlias(OperandVector &Operands);
167
168
  bool parseOperand(OperandVector &, StringRef Mnemonic, unsigned int &ErrorCode);
169
170
  enum MacroExpanderResultTy {
171
    MER_NotAMacro,
172
    MER_Success,
173
    MER_Fail,
174
  };
175
176
  // Expands assembly pseudo instructions.
177
  MacroExpanderResultTy
178
  tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
179
                       SmallVectorImpl<MCInst> &Instructions);
180
181
  bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
182
                         SmallVectorImpl<MCInst> &Instructions);
183
184
  bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
185
                     bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
186
                     SmallVectorImpl<MCInst> &Instructions);
187
188
  bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
189
                               unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
190
                               SmallVectorImpl<MCInst> &Instructions);
191
192
  bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193
                     SmallVectorImpl<MCInst> &Instructions);
194
195
  bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
196
                         const MCOperand &Offset, bool Is32BitAddress,
197
                         SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
198
199
  bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
200
                                  SmallVectorImpl<MCInst> &Instructions);
201
202
  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
203
                     SmallVectorImpl<MCInst> &Instructions, bool isLoad,
204
                     bool isImmOpnd);
205
206
  bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
207
                               SmallVectorImpl<MCInst> &Instructions);
208
209
  bool expandAliasImmediate(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 expandDiv(MCInst &Inst, SMLoc IDLoc,
219
                 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
220
                 const bool Signed);
221
222
  bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
223
                 SmallVectorImpl<MCInst> &Instructions);
224
225
  bool expandUlw(MCInst &Inst, SMLoc IDLoc,
226
                 SmallVectorImpl<MCInst> &Instructions);
227
228
  bool expandRotation(MCInst &Inst, SMLoc IDLoc,
229
                      SmallVectorImpl<MCInst> &Instructions);
230
  bool expandRotationImm(MCInst &Inst, SMLoc IDLoc,
231
                         SmallVectorImpl<MCInst> &Instructions);
232
  bool expandDRotation(MCInst &Inst, SMLoc IDLoc,
233
                       SmallVectorImpl<MCInst> &Instructions);
234
  bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
235
                          SmallVectorImpl<MCInst> &Instructions);
236
237
  bool expandAbs(MCInst &Inst, SMLoc IDLoc,
238
                 SmallVectorImpl<MCInst> &Instructions);
239
240
  void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
241
                 SmallVectorImpl<MCInst> &Instructions);
242
243
  void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
244
                  bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
245
246
  void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
247
                            SmallVectorImpl<MCInst> &Instructions);
248
249
  bool reportParseError(Twine ErrorMsg);
250
  bool reportParseError(SMLoc Loc, Twine ErrorMsg);
251
252
  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
253
  bool parseRelocOperand(const MCExpr *&Res);
254
255
  const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
256
257
  bool isEvaluated(const MCExpr *Expr);
258
  bool parseSetMips0Directive();
259
  bool parseSetArchDirective();
260
  bool parseSetFeature(uint64_t Feature);
261
  bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
262
  bool parseDirectiveCpLoad(SMLoc Loc);
263
  bool parseDirectiveCpRestore(SMLoc Loc);
264
  bool parseDirectiveCPSetup();
265
  bool parseDirectiveCPReturn();
266
  bool parseDirectiveNaN();
267
  bool parseDirectiveSet();
268
  bool parseDirectiveOption();
269
  bool parseInsnDirective();
270
271
  bool parseSetAtDirective();
272
  bool parseSetNoAtDirective();
273
  bool parseSetMacroDirective();
274
  bool parseSetNoMacroDirective();
275
  bool parseSetMsaDirective();
276
  bool parseSetNoMsaDirective();
277
  bool parseSetNoDspDirective();
278
  bool parseSetReorderDirective();
279
  bool parseSetNoReorderDirective();
280
  bool parseSetMips16Directive();
281
  bool parseSetNoMips16Directive();
282
  bool parseSetFpDirective();
283
  bool parseSetOddSPRegDirective();
284
  bool parseSetNoOddSPRegDirective();
285
  bool parseSetPopDirective();
286
  bool parseSetPushDirective();
287
  bool parseSetSoftFloatDirective();
288
  bool parseSetHardFloatDirective();
289
290
  bool parseSetAssignment();
291
292
  bool parseDataDirective(unsigned Size, SMLoc L);
293
  bool parseDirectiveGpWord();
294
  bool parseDirectiveGpDWord();
295
  bool parseDirectiveModule();
296
  bool parseDirectiveModuleFP();
297
  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
298
                       StringRef Directive);
299
300
  bool parseInternalDirectiveReallowModule();
301
302
  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
303
304
  bool eatComma(StringRef ErrorStr);
305
306
  int matchCPURegisterName(StringRef Symbol);
307
308
  int matchHWRegsRegisterName(StringRef Symbol);
309
310
  int matchFPURegisterName(StringRef Name);
311
312
  int matchFCCRegisterName(StringRef Name);
313
314
  int matchACRegisterName(StringRef Name);
315
316
  int matchMSA128RegisterName(StringRef Name);
317
318
  int matchMSA128CtrlRegisterName(StringRef Name);
319
320
  unsigned getReg(int RC, int RegNo);
321
322
  /// Returns the internal register number for the current AT. Also checks if
323
  /// the current AT is unavailable (set to $0) and gives an error if it is.
324
  /// This should be used in pseudo-instruction expansions which need AT.
325
  unsigned getATReg(SMLoc Loc);
326
327
  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
328
                          SmallVectorImpl<MCInst> &Instructions,
329
                          unsigned int &KsError);
330
331
  // Helper function that checks if the value of a vector index is within the
332
  // boundaries of accepted values for each RegisterKind
333
  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
334
  bool validateMSAIndex(int Val, int RegKind);
335
336
  // Selects a new architecture by updating the FeatureBits with the necessary
337
  // info including implied dependencies.
338
  // Internally, it clears all the feature bits related to *any* architecture
339
  // and selects the new one using the ToggleFeature functionality of the
340
  // MCSubtargetInfo object that handles implied dependencies. The reason we
341
  // clear all the arch related bits manually is because ToggleFeature only
342
  // clears the features that imply the feature being cleared and not the
343
  // features implied by the feature being cleared. This is easier to see
344
  // with an example:
345
  //  --------------------------------------------------
346
  // | Feature         | Implies                        |
347
  // | -------------------------------------------------|
348
  // | FeatureMips1    | None                           |
349
  // | FeatureMips2    | FeatureMips1                   |
350
  // | FeatureMips3    | FeatureMips2 | FeatureMipsGP64 |
351
  // | FeatureMips4    | FeatureMips3                   |
352
  // | ...             |                                |
353
  //  --------------------------------------------------
354
  //
355
  // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
356
  // FeatureMipsGP64 | FeatureMips1)
357
  // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
358
2.76k
  void selectArch(StringRef ArchFeature) {
359
2.76k
    MCSubtargetInfo &STI = copySTI();
360
2.76k
    FeatureBitset FeatureBits = STI.getFeatureBits();
361
2.76k
    FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
362
2.76k
    STI.setFeatureBits(FeatureBits);
363
2.76k
    setAvailableFeatures(
364
2.76k
        ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
365
2.76k
    AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
366
2.76k
  }
367
368
4.14k
  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
369
4.14k
    if (!(getSTI().getFeatureBits()[Feature])) {
370
3.40k
      MCSubtargetInfo &STI = copySTI();
371
3.40k
      setAvailableFeatures(
372
3.40k
          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
373
3.40k
      AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
374
3.40k
    }
375
4.14k
  }
376
377
6.97k
  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
378
6.97k
    if (getSTI().getFeatureBits()[Feature]) {
379
3.28k
      MCSubtargetInfo &STI = copySTI();
380
3.28k
      setAvailableFeatures(
381
3.28k
          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
382
3.28k
      AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
383
3.28k
    }
384
6.97k
  }
385
386
0
  void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
387
0
    setFeatureBits(Feature, FeatureString);
388
0
    AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
389
0
  }
390
391
4
  void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
392
4
    clearFeatureBits(Feature, FeatureString);
393
4
    AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
394
4
  }
395
396
public:
397
  enum MipsMatchResultTy {
398
    Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
399
#define GET_OPERAND_DIAGNOSTIC_TYPES
400
#include "MipsGenAsmMatcher.inc"
401
#undef GET_OPERAND_DIAGNOSTIC_TYPES
402
  };
403
404
  MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
405
                const MCInstrInfo &MII, const MCTargetOptions &Options)
406
6.81k
    : MCTargetAsmParser(Options, sti),
407
6.81k
        ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
408
6.81k
                                          sti.getCPU(), Options)) {
409
6.81k
    MCAsmParserExtension::Initialize(parser);
410
411
6.81k
    parser.addAliasForDirective(".asciiz", ".asciz");
412
413
    // Initialize the set of available features.
414
6.81k
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
415
416
    // Remember the initial assembler options. The user can not modify these.
417
6.81k
    AssemblerOptions.push_back(
418
6.81k
        llvm_ks::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
419
420
    // Create an assembler options environment for the user to modify.
421
6.81k
    AssemblerOptions.push_back(
422
6.81k
        llvm_ks::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
423
424
    //getTargetStreamer().updateABIInfo(*this);
425
426
    //if (!isABI_O32() && !useOddSPReg() != 0)
427
    //  report_fatal_error("-mno-odd-spreg requires the O32 ABI");
428
429
6.81k
    CurrentFn = nullptr;
430
431
    //IsPicEnabled =
432
    //    (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
433
434
6.81k
    IsCpRestoreSet = false;
435
6.81k
    CpRestoreOffset = -1;
436
437
6.81k
    Triple TheTriple(sti.getTargetTriple());
438
6.81k
    if ((TheTriple.getArch() == Triple::mips) ||
439
6.05k
        (TheTriple.getArch() == Triple::mips64))
440
919
      IsLittleEndian = false;
441
5.89k
    else
442
5.89k
      IsLittleEndian = true;
443
6.81k
  }
444
445
  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
446
2
  bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
447
448
1.66k
  bool isGP64bit() const {
449
1.66k
    return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
450
1.66k
  }
451
0
  bool isFP64bit() const {
452
0
    return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
453
0
  }
454
876
  const MipsABIInfo &getABI() const { return ABI; }
455
15.2k
  bool isABI_N32() const { return ABI.IsN32(); }
456
15.2k
  bool isABI_N64() const { return ABI.IsN64(); }
457
133
  bool isABI_O32() const { return ABI.IsO32(); }
458
0
  bool isABI_FPXX() const {
459
0
    return getSTI().getFeatureBits()[Mips::FeatureFPXX];
460
0
  }
461
462
12
  bool useOddSPReg() const {
463
12
    return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
464
12
  }
465
466
14.4k
  bool inMicroMipsMode() const {
467
14.4k
    return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
468
14.4k
  }
469
0
  bool hasMips1() const {
470
0
    return getSTI().getFeatureBits()[Mips::FeatureMips1];
471
0
  }
472
0
  bool hasMips2() const {
473
0
    return getSTI().getFeatureBits()[Mips::FeatureMips2];
474
0
  }
475
33
  bool hasMips3() const {
476
33
    return getSTI().getFeatureBits()[Mips::FeatureMips3];
477
33
  }
478
2
  bool hasMips4() const {
479
2
    return getSTI().getFeatureBits()[Mips::FeatureMips4];
480
2
  }
481
0
  bool hasMips5() const {
482
0
    return getSTI().getFeatureBits()[Mips::FeatureMips5];
483
0
  }
484
17
  bool hasMips32() const {
485
17
    return getSTI().getFeatureBits()[Mips::FeatureMips32];
486
17
  }
487
2
  bool hasMips64() const {
488
2
    return getSTI().getFeatureBits()[Mips::FeatureMips64];
489
2
  }
490
18
  bool hasMips32r2() const {
491
18
    return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
492
18
  }
493
2
  bool hasMips64r2() const {
494
2
    return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
495
2
  }
496
0
  bool hasMips32r3() const {
497
0
    return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
498
0
  }
499
0
  bool hasMips64r3() const {
500
0
    return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
501
0
  }
502
0
  bool hasMips32r5() const {
503
0
    return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
504
0
  }
505
0
  bool hasMips64r5() const {
506
0
    return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
507
0
  }
508
14.8k
  bool hasMips32r6() const {
509
14.8k
    return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
510
14.8k
  }
511
0
  bool hasMips64r6() const {
512
0
    return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
513
0
  }
514
515
0
  bool hasDSP() const {
516
0
    return getSTI().getFeatureBits()[Mips::FeatureDSP];
517
0
  }
518
0
  bool hasDSPR2() const {
519
0
    return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
520
0
  }
521
0
  bool hasDSPR3() const {
522
0
    return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
523
0
  }
524
0
  bool hasMSA() const {
525
0
    return getSTI().getFeatureBits()[Mips::FeatureMSA];
526
0
  }
527
14.8k
  bool hasCnMips() const {
528
14.8k
    return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
529
14.8k
  }
530
531
474
  bool inPicMode() {
532
474
    return IsPicEnabled;
533
474
  }
534
535
616
  bool inMips16Mode() const {
536
616
    return getSTI().getFeatureBits()[Mips::FeatureMips16];
537
616
  }
538
539
0
  bool useTraps() const {
540
0
    return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
541
0
  }
542
543
0
  bool useSoftFloat() const {
544
0
    return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
545
0
  }
546
547
  /// Warn if RegIndex is the same as the current AT.
548
  void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
549
550
  void warnIfNoMacro(SMLoc Loc);
551
552
0
  bool isLittle() const { return IsLittleEndian; }
553
};
554
}
555
556
namespace {
557
558
/// MipsOperand - Instances of this class represent a parsed Mips machine
559
/// instruction.
560
class MipsOperand : public MCParsedAsmOperand {
561
public:
562
  /// Broad categories of register classes
563
  /// The exact class is finalized by the render method.
564
  enum RegKind {
565
    RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
566
    RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context and
567
                          /// isFP64bit())
568
    RegKind_FCC = 4,      /// FCC
569
    RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
570
    RegKind_MSACtrl = 16, /// MSA control registers
571
    RegKind_COP2 = 32,    /// COP2
572
    RegKind_ACC = 64,     /// HI32DSP, LO32DSP, and ACC64DSP (depending on
573
                          /// context).
574
    RegKind_CCR = 128,    /// CCR
575
    RegKind_HWRegs = 256, /// HWRegs
576
    RegKind_COP3 = 512,   /// COP3
577
    RegKind_COP0 = 1024,  /// COP0
578
    /// Potentially any (e.g. $1)
579
    RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
580
                      RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
581
                      RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
582
  };
583
584
private:
585
  enum KindTy {
586
    k_Immediate,     /// An immediate (possibly involving symbol references)
587
    k_Memory,        /// Base + Offset Memory Address
588
    k_PhysRegister,  /// A physical register from the Mips namespace
589
    k_RegisterIndex, /// A register index in one or more RegKind.
590
    k_Token,         /// A simple token
591
    k_RegList,       /// A physical register list
592
    k_RegPair        /// A pair of physical register
593
  } Kind;
594
595
public:
596
  MipsOperand(KindTy K, MipsAsmParser &Parser)
597
71.8k
      : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
598
599
private:
600
  /// For diagnostics, and checking the assembler temporary
601
  MipsAsmParser &AsmParser;
602
603
  struct Token {
604
    const char *Data;
605
    unsigned Length;
606
  };
607
608
  struct PhysRegOp {
609
    unsigned Num; /// Register Number
610
  };
611
612
  struct RegIdxOp {
613
    unsigned Index; /// Index into the register class
614
    RegKind Kind;   /// Bitfield of the kinds it could possibly be
615
    const MCRegisterInfo *RegInfo;
616
  };
617
618
  struct ImmOp {
619
    const MCExpr *Val;
620
  };
621
622
  struct MemOp {
623
    MipsOperand *Base;
624
    const MCExpr *Off;
625
  };
626
627
  struct RegListOp {
628
    SmallVector<unsigned, 10> *List;
629
  };
630
631
  union {
632
    struct Token Tok;
633
    struct PhysRegOp PhysReg;
634
    struct RegIdxOp RegIdx;
635
    struct ImmOp Imm;
636
    struct MemOp Mem;
637
    struct RegListOp RegList;
638
  };
639
640
  SMLoc StartLoc, EndLoc;
641
642
  /// Internal constructor for register kinds
643
  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
644
                                                const MCRegisterInfo *RegInfo,
645
                                                SMLoc S, SMLoc E,
646
17.8k
                                                MipsAsmParser &Parser) {
647
17.8k
    auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
648
17.8k
    Op->RegIdx.Index = Index;
649
17.8k
    Op->RegIdx.RegInfo = RegInfo;
650
17.8k
    Op->RegIdx.Kind = RegKind;
651
17.8k
    Op->StartLoc = S;
652
17.8k
    Op->EndLoc = E;
653
17.8k
    return Op;
654
17.8k
  }
655
656
public:
657
  /// Coerce the register to GPR32 and return the real register for the current
658
  /// target.
659
5.86k
  unsigned getGPR32Reg() const {
660
5.86k
    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
661
5.86k
    AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
662
5.86k
    unsigned ClassID = Mips::GPR32RegClassID;
663
5.86k
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
664
5.86k
  }
665
666
  /// Coerce the register to GPR32 and return the real register for the current
667
  /// target.
668
0
  unsigned getGPRMM16Reg() const {
669
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
670
0
    unsigned ClassID = Mips::GPR32RegClassID;
671
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
672
0
  }
673
674
  /// Coerce the register to GPR64 and return the real register for the current
675
  /// target.
676
749
  unsigned getGPR64Reg() const {
677
749
    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
678
749
    unsigned ClassID = Mips::GPR64RegClassID;
679
749
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
680
749
  }
681
682
private:
683
  /// Coerce the register to AFGR64 and return the real register for the current
684
  /// target.
685
0
  unsigned getAFGR64Reg() const {
686
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
687
0
    if (RegIdx.Index % 2 != 0) {
688
      // AsmParser.Warning(StartLoc, "Float register should be even.");
689
0
    }
690
0
    return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
691
0
        .getRegister(RegIdx.Index / 2);
692
0
  }
693
694
  /// Coerce the register to FGR64 and return the real register for the current
695
  /// target.
696
6
  unsigned getFGR64Reg() const {
697
6
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
698
6
    return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
699
6
        .getRegister(RegIdx.Index);
700
6
  }
701
702
  /// Coerce the register to FGR32 and return the real register for the current
703
  /// target.
704
12
  unsigned getFGR32Reg() const {
705
12
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
706
12
    return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
707
12
        .getRegister(RegIdx.Index);
708
12
  }
709
710
  /// Coerce the register to FGRH32 and return the real register for the current
711
  /// target.
712
0
  unsigned getFGRH32Reg() const {
713
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
714
0
    return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
715
0
        .getRegister(RegIdx.Index);
716
0
  }
717
718
  /// Coerce the register to FCC and return the real register for the current
719
  /// target.
720
2
  unsigned getFCCReg() const {
721
2
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
722
2
    return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
723
2
        .getRegister(RegIdx.Index);
724
2
  }
725
726
  /// Coerce the register to MSA128 and return the real register for the current
727
  /// target.
728
0
  unsigned getMSA128Reg() const {
729
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
730
    // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
731
    // identical
732
0
    unsigned ClassID = Mips::MSA128BRegClassID;
733
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
734
0
  }
735
736
  /// Coerce the register to MSACtrl and return the real register for the
737
  /// current target.
738
0
  unsigned getMSACtrlReg() const {
739
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
740
0
    unsigned ClassID = Mips::MSACtrlRegClassID;
741
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
742
0
  }
743
744
  /// Coerce the register to COP0 and return the real register for the
745
  /// current target.
746
0
  unsigned getCOP0Reg() const {
747
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
748
0
    unsigned ClassID = Mips::COP0RegClassID;
749
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
750
0
  }
751
752
  /// Coerce the register to COP2 and return the real register for the
753
  /// current target.
754
167
  unsigned getCOP2Reg() const {
755
167
    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
756
167
    unsigned ClassID = Mips::COP2RegClassID;
757
167
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
758
167
  }
759
760
  /// Coerce the register to COP3 and return the real register for the
761
  /// current target.
762
30
  unsigned getCOP3Reg() const {
763
30
    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
764
30
    unsigned ClassID = Mips::COP3RegClassID;
765
30
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
766
30
  }
767
768
  /// Coerce the register to ACC64DSP and return the real register for the
769
  /// current target.
770
0
  unsigned getACC64DSPReg() const {
771
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
772
0
    unsigned ClassID = Mips::ACC64DSPRegClassID;
773
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
774
0
  }
775
776
  /// Coerce the register to HI32DSP and return the real register for the
777
  /// current target.
778
0
  unsigned getHI32DSPReg() const {
779
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
780
0
    unsigned ClassID = Mips::HI32DSPRegClassID;
781
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
782
0
  }
783
784
  /// Coerce the register to LO32DSP and return the real register for the
785
  /// current target.
786
0
  unsigned getLO32DSPReg() const {
787
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
788
0
    unsigned ClassID = Mips::LO32DSPRegClassID;
789
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
790
0
  }
791
792
  /// Coerce the register to CCR and return the real register for the
793
  /// current target.
794
0
  unsigned getCCRReg() const {
795
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
796
0
    unsigned ClassID = Mips::CCRRegClassID;
797
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
798
0
  }
799
800
  /// Coerce the register to HWRegs and return the real register for the
801
  /// current target.
802
0
  unsigned getHWRegsReg() const {
803
0
    assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
804
0
    unsigned ClassID = Mips::HWRegsRegClassID;
805
0
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
806
0
  }
807
808
public:
809
13.5k
  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
810
    // Add as immediate when possible.  Null MCExpr = 0.
811
13.5k
    if (!Expr)
812
0
      Inst.addOperand(MCOperand::createImm(0));
813
13.5k
    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
814
2.86k
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
815
10.6k
    else
816
10.6k
      Inst.addOperand(MCOperand::createExpr(Expr));
817
13.5k
  }
818
819
0
  void addRegOperands(MCInst &Inst, unsigned N) const {
820
0
    llvm_unreachable("Use a custom parser instead");
821
0
  }
822
823
  /// Render the operand to an MCInst as a GPR32
824
  /// Asserts if the wrong number of operands are requested, or the operand
825
  /// is not a k_RegisterIndex compatible with RegKind_GPR
826
5.37k
  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
827
5.37k
    assert(N == 1 && "Invalid number of operands!");
828
5.37k
    Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
829
5.37k
  }
830
831
0
  void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
832
0
    assert(N == 1 && "Invalid number of operands!");
833
0
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
834
0
  }
835
836
0
  void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
837
0
    assert(N == 1 && "Invalid number of operands!");
838
0
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
839
0
  }
840
841
0
  void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
842
0
    assert(N == 1 && "Invalid number of operands!");
843
0
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
844
0
  }
845
846
  /// Render the operand to an MCInst as a GPR64
847
  /// Asserts if the wrong number of operands are requested, or the operand
848
  /// is not a k_RegisterIndex compatible with RegKind_GPR
849
36
  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
850
36
    assert(N == 1 && "Invalid number of operands!");
851
36
    Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
852
36
  }
853
854
0
  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
855
0
    assert(N == 1 && "Invalid number of operands!");
856
0
    Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
857
0
  }
858
859
6
  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
860
6
    assert(N == 1 && "Invalid number of operands!");
861
6
    Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
862
6
  }
863
864
12
  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
865
12
    assert(N == 1 && "Invalid number of operands!");
866
12
    Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
867
    // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
868
12
    if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
869
0
      AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
870
0
                                "registers");
871
12
  }
872
873
0
  void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
874
0
    assert(N == 1 && "Invalid number of operands!");
875
0
    Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
876
0
  }
877
878
2
  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
879
2
    assert(N == 1 && "Invalid number of operands!");
880
2
    Inst.addOperand(MCOperand::createReg(getFCCReg()));
881
2
  }
882
883
0
  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
884
0
    assert(N == 1 && "Invalid number of operands!");
885
0
    Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
886
0
  }
887
888
0
  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
889
0
    assert(N == 1 && "Invalid number of operands!");
890
0
    Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
891
0
  }
892
893
0
  void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
894
0
    assert(N == 1 && "Invalid number of operands!");
895
0
    Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
896
0
  }
897
898
167
  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
899
167
    assert(N == 1 && "Invalid number of operands!");
900
167
    Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
901
167
  }
902
903
30
  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
904
30
    assert(N == 1 && "Invalid number of operands!");
905
30
    Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
906
30
  }
907
908
0
  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
909
0
    assert(N == 1 && "Invalid number of operands!");
910
0
    Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
911
0
  }
912
913
0
  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
914
0
    assert(N == 1 && "Invalid number of operands!");
915
0
    Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
916
0
  }
917
918
0
  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
919
0
    assert(N == 1 && "Invalid number of operands!");
920
0
    Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
921
0
  }
922
923
0
  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
924
0
    assert(N == 1 && "Invalid number of operands!");
925
0
    Inst.addOperand(MCOperand::createReg(getCCRReg()));
926
0
  }
927
928
0
  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
929
0
    assert(N == 1 && "Invalid number of operands!");
930
0
    Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
931
0
  }
932
933
  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
934
0
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
935
0
    assert(N == 1 && "Invalid number of operands!");
936
0
    uint64_t Imm = getConstantImm() - Offset;
937
0
    Imm &= (1 << Bits) - 1;
938
0
    Imm += Offset;
939
0
    Imm += AdjustOffset;
940
0
    Inst.addOperand(MCOperand::createImm(Imm));
941
0
  }
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<2u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<16u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 32, -32>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<10u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<4u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<3u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 1, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 33, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 32, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<6u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<2u, 1, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<1u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<7u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
Unexecuted instantiation: MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<8u, 0, 0>(llvm_ks::MCInst&, unsigned int) const
942
943
  template <unsigned Bits>
944
0
  void addUImmOperands(MCInst &Inst, unsigned N) const {
945
0
    if (isImm() && !isConstantImm()) {
946
0
      addExpr(Inst, getImm());
947
0
      return;
948
0
    }
949
0
    addConstantUImmOperands<Bits, 0, 0>(Inst, N);
950
0
  }
951
952
12.6k
  void addImmOperands(MCInst &Inst, unsigned N) const {
953
12.6k
    assert(N == 1 && "Invalid number of operands!");
954
12.6k
    const MCExpr *Expr = getImm();
955
12.6k
    addExpr(Inst, Expr);
956
12.6k
  }
957
958
876
  void addMemOperands(MCInst &Inst, unsigned N) const {
959
876
    assert(N == 2 && "Invalid number of operands!");
960
961
876
    Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
962
876
                                             ? getMemBase()->getGPR64Reg()
963
876
                                             : getMemBase()->getGPR32Reg()));
964
965
876
    const MCExpr *Expr = getMemOff();
966
876
    addExpr(Inst, Expr);
967
876
  }
968
969
0
  void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
970
0
    assert(N == 2 && "Invalid number of operands!");
971
972
0
    Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
973
974
0
    const MCExpr *Expr = getMemOff();
975
0
    addExpr(Inst, Expr);
976
0
  }
977
978
0
  void addRegListOperands(MCInst &Inst, unsigned N) const {
979
0
    assert(N == 1 && "Invalid number of operands!");
980
981
0
    for (auto RegNo : getRegList())
982
0
      Inst.addOperand(MCOperand::createReg(RegNo));
983
0
  }
984
985
0
  void addRegPairOperands(MCInst &Inst, unsigned N) const {
986
0
    assert(N == 2 && "Invalid number of operands!");
987
0
    unsigned RegNo = getRegPair();
988
0
    Inst.addOperand(MCOperand::createReg(RegNo++));
989
0
    Inst.addOperand(MCOperand::createReg(RegNo));
990
0
  }
991
992
0
  void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
993
0
    assert(N == 2 && "Invalid number of operands!");
994
0
    for (auto RegNo : getRegList())
995
0
      Inst.addOperand(MCOperand::createReg(RegNo));
996
0
  }
997
998
11.9k
  bool isReg() const override {
999
    // As a special case until we sort out the definition of div/divu, pretend
1000
    // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1001
11.9k
    if (isGPRAsmReg() && RegIdx.Index == 0)
1002
37
      return true;
1003
1004
11.9k
    return Kind == k_PhysRegister;
1005
11.9k
  }
1006
47.9k
  bool isRegIdx() const { return Kind == k_RegisterIndex; }
1007
30.8k
  bool isImm() const override { return Kind == k_Immediate; }
1008
14
  bool isConstantImm() const {
1009
14
    return isImm() && isa<MCConstantExpr>(getImm());
1010
14
  }
1011
0
  bool isConstantImmz() const {
1012
0
    return isConstantImm() && getConstantImm() == 0;
1013
0
  }
1014
14
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1015
14
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1016
14
  }
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<1u, 0>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<2u, 0>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<2u, 1>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<3u, 0>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<4u, 0>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 0>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 1>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 32>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 33>() const
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<6u, 0>() const
Line
Count
Source
1014
2
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1015
2
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1016
2
  }
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<7u, 0>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<8u, 0>() const
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<10u, 0>() const
Line
Count
Source
1014
12
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1015
12
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1016
12
  }
1017
0
  template <unsigned Bits> bool isUImm() const {
1018
0
    return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1019
0
  }
1020
0
  template <unsigned Bits> bool isAnyImm() const {
1021
0
    return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1022
0
                              isUInt<Bits>(getConstantImm()))
1023
0
                           : isImm();
1024
0
  }
1025
0
  template <unsigned Bits> bool isConstantSImm() const {
1026
0
    return isConstantImm() && isInt<Bits>(getConstantImm());
1027
0
  }
1028
56.0k
  bool isToken() const override {
1029
    // Note: It's not possible to pretend that other operand kinds are tokens.
1030
    // The matcher emitter checks tokens first.
1031
56.0k
    return Kind == k_Token;
1032
56.0k
  }
1033
2.68k
  bool isMem() const override { return Kind == k_Memory; }
1034
893
  bool isConstantMemOff() const {
1035
893
    return isMem() && isa<MCConstantExpr>(getMemOff());
1036
893
  }
1037
494
  template <unsigned Bits> bool isMemWithSimmOffset() const {
1038
494
    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1039
102
      && getMemBase()->isGPRAsmReg();
1040
494
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<11u>() const
Line
Count
Source
1037
167
  template <unsigned Bits> bool isMemWithSimmOffset() const {
1038
167
    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1039
34
      && getMemBase()->isGPRAsmReg();
1040
167
  }
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<16u>() const
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<9u>() const
Line
Count
Source
1037
327
  template <unsigned Bits> bool isMemWithSimmOffset() const {
1038
327
    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1039
68
      && getMemBase()->isGPRAsmReg();
1040
327
  }
1041
0
  template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
1042
0
    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
1043
0
           getMemBase()->isGPRAsmReg();
1044
0
  }
1045
0
  bool isMemWithGRPMM16Base() const {
1046
0
    return isMem() && getMemBase()->isMM16AsmReg();
1047
0
  }
1048
0
  template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1049
0
    return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1050
0
      && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1051
0
  }
1052
399
  template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1053
399
    return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1054
227
      && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1055
138
      && (getMemBase()->getGPR32Reg() == Mips::SP);
1056
399
  }
1057
  template <unsigned Bits, unsigned ShiftLeftAmount>
1058
0
  bool isScaledUImm() const {
1059
0
    return isConstantImm() &&
1060
0
           isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1061
0
  }
1062
0
  bool isRegList16() const {
1063
0
    if (!isRegList())
1064
0
      return false;
1065
1066
0
    int Size = RegList.List->size();
1067
0
    if (Size < 2 || Size > 5)
1068
0
      return false;
1069
1070
0
    unsigned R0 = RegList.List->front();
1071
0
    unsigned R1 = RegList.List->back();
1072
0
    if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1073
0
          (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1074
0
      return false;
1075
1076
0
    int PrevReg = *RegList.List->begin();
1077
0
    for (int i = 1; i < Size - 1; i++) {
1078
0
      int Reg = (*(RegList.List))[i];
1079
0
      if ( Reg != PrevReg + 1)
1080
0
        return false;
1081
0
      PrevReg = Reg;
1082
0
    }
1083
1084
0
    return true;
1085
0
  }
1086
0
  bool isInvNum() const { return Kind == k_Immediate; }
1087
0
  bool isLSAImm() const {
1088
0
    if (!isConstantImm())
1089
0
      return false;
1090
0
    int64_t Val = getConstantImm();
1091
0
    return 1 <= Val && Val <= 4;
1092
0
  }
1093
0
  bool isRegList() const { return Kind == k_RegList; }
1094
0
  bool isMovePRegPair() const {
1095
0
    if (Kind != k_RegList || RegList.List->size() != 2)
1096
0
      return false;
1097
1098
0
    unsigned R0 = RegList.List->front();
1099
0
    unsigned R1 = RegList.List->back();
1100
1101
0
    if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1102
0
        (R0 == Mips::A1 && R1 == Mips::A3) ||
1103
0
        (R0 == Mips::A2 && R1 == Mips::A3) ||
1104
0
        (R0 == Mips::A0 && R1 == Mips::S5) ||
1105
0
        (R0 == Mips::A0 && R1 == Mips::S6) ||
1106
0
        (R0 == Mips::A0 && R1 == Mips::A1) ||
1107
0
        (R0 == Mips::A0 && R1 == Mips::A2) ||
1108
0
        (R0 == Mips::A0 && R1 == Mips::A3))
1109
0
      return true;
1110
1111
0
    return false;
1112
0
  }
1113
1114
16.7k
  StringRef getToken() const {
1115
16.7k
    assert(Kind == k_Token && "Invalid access!");
1116
16.7k
    return StringRef(Tok.Data, Tok.Length);
1117
16.7k
  }
1118
0
  bool isRegPair() const { return Kind == k_RegPair; }
1119
1120
37
  unsigned getReg() const override {
1121
    // As a special case until we sort out the definition of div/divu, pretend
1122
    // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1123
37
    if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1124
37
        RegIdx.Kind & RegKind_GPR)
1125
37
      return getGPR32Reg(); // FIXME: GPR64 too
1126
1127
37
    assert(Kind == k_PhysRegister && "Invalid access!");
1128
0
    return PhysReg.Num;
1129
0
  }
1130
1131
12.6k
  const MCExpr *getImm() const {
1132
12.6k
    assert((Kind == k_Immediate) && "Invalid access!");
1133
12.6k
    return Imm.Val;
1134
12.6k
  }
1135
1136
12
  int64_t getConstantImm() const {
1137
12
    const MCExpr *Val = getImm();
1138
12
    return static_cast<const MCConstantExpr *>(Val)->getValue();
1139
12
  }
1140
1141
1.25k
  MipsOperand *getMemBase() const {
1142
1.25k
    assert((Kind == k_Memory) && "Invalid access!");
1143
1.25k
    return Mem.Base;
1144
1.25k
  }
1145
1146
2.64k
  const MCExpr *getMemOff() const {
1147
2.64k
    assert((Kind == k_Memory) && "Invalid access!");
1148
2.64k
    return Mem.Off;
1149
2.64k
  }
1150
1151
875
  int64_t getConstantMemOff() const {
1152
875
    return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1153
875
  }
1154
1155
0
  const SmallVectorImpl<unsigned> &getRegList() const {
1156
0
    assert((Kind == k_RegList) && "Invalid access!");
1157
0
    return *(RegList.List);
1158
0
  }
1159
1160
0
  unsigned getRegPair() const {
1161
0
    assert((Kind == k_RegPair) && "Invalid access!");
1162
0
    return RegIdx.Index;
1163
0
  }
1164
1165
  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1166
33.5k
                                                  MipsAsmParser &Parser) {
1167
33.5k
    auto Op = make_unique<MipsOperand>(k_Token, Parser);
1168
33.5k
    Op->Tok.Data = Str.data();
1169
33.5k
    Op->Tok.Length = Str.size();
1170
33.5k
    Op->StartLoc = S;
1171
33.5k
    Op->EndLoc = S;
1172
33.5k
    return Op;
1173
33.5k
  }
1174
1175
  /// Create a numeric register (e.g. $1). The exact register remains
1176
  /// unresolved until an instruction successfully matches
1177
  static std::unique_ptr<MipsOperand>
1178
  createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1179
10.2k
                   SMLoc E, MipsAsmParser &Parser) {
1180
10.2k
    DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1181
10.2k
    return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1182
10.2k
  }
1183
1184
  /// Create a register that is definitely a GPR.
1185
  /// This is typically only used for named registers such as $gp.
1186
  static std::unique_ptr<MipsOperand>
1187
  createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1188
7.11k
               MipsAsmParser &Parser) {
1189
7.11k
    return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1190
7.11k
  }
1191
1192
  /// Create a register that is definitely a FGR.
1193
  /// This is typically only used for named registers such as $f0.
1194
  static std::unique_ptr<MipsOperand>
1195
  createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1196
131
               MipsAsmParser &Parser) {
1197
131
    return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1198
131
  }
1199
1200
  /// Create a register that is definitely a HWReg.
1201
  /// This is typically only used for named registers such as $hwr_cpunum.
1202
  static std::unique_ptr<MipsOperand>
1203
  createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1204
21
                  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1205
21
    return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1206
21
  }
1207
1208
  /// Create a register that is definitely an FCC.
1209
  /// This is typically only used for named registers such as $fcc0.
1210
  static std::unique_ptr<MipsOperand>
1211
  createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1212
71
               MipsAsmParser &Parser) {
1213
71
    return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1214
71
  }
1215
1216
  /// Create a register that is definitely an ACC.
1217
  /// This is typically only used for named registers such as $ac0.
1218
  static std::unique_ptr<MipsOperand>
1219
  createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1220
52
               MipsAsmParser &Parser) {
1221
52
    return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1222
52
  }
1223
1224
  /// Create a register that is definitely an MSA128.
1225
  /// This is typically only used for named registers such as $w0.
1226
  static std::unique_ptr<MipsOperand>
1227
  createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1228
1
                  SMLoc E, MipsAsmParser &Parser) {
1229
1
    return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1230
1
  }
1231
1232
  /// Create a register that is definitely an MSACtrl.
1233
  /// This is typically only used for named registers such as $msaaccess.
1234
  static std::unique_ptr<MipsOperand>
1235
  createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1236
180
                   SMLoc E, MipsAsmParser &Parser) {
1237
180
    return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1238
180
  }
1239
1240
  static std::unique_ptr<MipsOperand>
1241
19.6k
  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1242
19.6k
    auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1243
19.6k
    Op->Imm.Val = Val;
1244
19.6k
    Op->StartLoc = S;
1245
19.6k
    Op->EndLoc = E;
1246
19.6k
    return Op;
1247
19.6k
  }
1248
1249
  static std::unique_ptr<MipsOperand>
1250
  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1251
878
            SMLoc E, MipsAsmParser &Parser) {
1252
878
    auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1253
878
    Op->Mem.Base = Base.release();
1254
878
    Op->Mem.Off = Off;
1255
878
    Op->StartLoc = S;
1256
878
    Op->EndLoc = E;
1257
878
    return Op;
1258
878
  }
1259
1260
  static std::unique_ptr<MipsOperand>
1261
  CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1262
0
                MipsAsmParser &Parser) {
1263
0
    assert (Regs.size() > 0 && "Empty list not allowed");
1264
1265
0
    auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1266
0
    Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1267
0
    Op->StartLoc = StartLoc;
1268
0
    Op->EndLoc = EndLoc;
1269
0
    return Op;
1270
0
  }
1271
1272
  static std::unique_ptr<MipsOperand>
1273
0
  CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1274
0
    auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1275
0
    Op->RegIdx.Index = RegNo;
1276
0
    Op->StartLoc = S;
1277
0
    Op->EndLoc = E;
1278
0
    return Op;
1279
0
  }
1280
1281
40.5k
  bool isGPRAsmReg() const {
1282
40.5k
    return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1283
40.5k
  }
1284
4
  bool isMM16AsmReg() const {
1285
4
    if (!(isRegIdx() && RegIdx.Kind))
1286
4
      return false;
1287
0
    return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1288
0
            || RegIdx.Index == 16 || RegIdx.Index == 17);
1289
4
  }
1290
0
  bool isMM16AsmRegZero() const {
1291
0
    if (!(isRegIdx() && RegIdx.Kind))
1292
0
      return false;
1293
0
    return (RegIdx.Index == 0 ||
1294
0
            (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1295
0
            RegIdx.Index == 17);
1296
0
  }
1297
0
  bool isMM16AsmRegMoveP() const {
1298
0
    if (!(isRegIdx() && RegIdx.Kind))
1299
0
      return false;
1300
0
    return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1301
0
      (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1302
0
  }
1303
24
  bool isFGRAsmReg() const {
1304
    // AFGR64 is $0-$15 but we handle this in getAFGR64()
1305
24
    return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1306
24
  }
1307
0
  bool isHWRegsAsmReg() const {
1308
0
    return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1309
0
  }
1310
0
  bool isCCRAsmReg() const {
1311
0
    return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1312
0
  }
1313
2
  bool isFCCAsmReg() const {
1314
2
    if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1315
0
      return false;
1316
2
    if (!AsmParser.hasEightFccRegisters())
1317
0
      return RegIdx.Index == 0;
1318
2
    return RegIdx.Index <= 7;
1319
2
  }
1320
0
  bool isACCAsmReg() const {
1321
0
    return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1322
0
  }
1323
0
  bool isCOP0AsmReg() const {
1324
0
    return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1325
0
  }
1326
333
  bool isCOP2AsmReg() const {
1327
333
    return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1328
333
  }
1329
31
  bool isCOP3AsmReg() const {
1330
31
    return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1331
31
  }
1332
0
  bool isMSA128AsmReg() const {
1333
0
    return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1334
0
  }
1335
0
  bool isMSACtrlAsmReg() const {
1336
0
    return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1337
0
  }
1338
1339
  /// getStartLoc - Get the location of the first token of this operand.
1340
781
  SMLoc getStartLoc() const override { return StartLoc; }
1341
  /// getEndLoc - Get the location of the last token of this operand.
1342
0
  SMLoc getEndLoc() const override { return EndLoc; }
1343
1344
71.8k
  virtual ~MipsOperand() {
1345
71.8k
    switch (Kind) {
1346
19.6k
    case k_Immediate:
1347
19.6k
      break;
1348
878
    case k_Memory:
1349
878
      delete Mem.Base;
1350
878
      break;
1351
0
    case k_RegList:
1352
0
      delete RegList.List;
1353
0
    case k_PhysRegister:
1354
17.8k
    case k_RegisterIndex:
1355
51.3k
    case k_Token:
1356
51.3k
    case k_RegPair:
1357
51.3k
      break;
1358
71.8k
    }
1359
71.8k
  }
1360
1361
0
  void print(raw_ostream &OS) const override {
1362
0
    switch (Kind) {
1363
0
    case k_Immediate:
1364
0
      OS << "Imm<";
1365
0
      OS << *Imm.Val;
1366
0
      OS << ">";
1367
0
      break;
1368
0
    case k_Memory:
1369
0
      OS << "Mem<";
1370
0
      Mem.Base->print(OS);
1371
0
      OS << ", ";
1372
0
      OS << *Mem.Off;
1373
0
      OS << ">";
1374
0
      break;
1375
0
    case k_PhysRegister:
1376
0
      OS << "PhysReg<" << PhysReg.Num << ">";
1377
0
      break;
1378
0
    case k_RegisterIndex:
1379
0
      OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1380
0
      break;
1381
0
    case k_Token:
1382
0
      OS << Tok.Data;
1383
0
      break;
1384
0
    case k_RegList:
1385
0
      OS << "RegList< ";
1386
0
      for (auto Reg : (*RegList.List))
1387
0
        OS << Reg << " ";
1388
0
      OS <<  ">";
1389
0
      break;
1390
0
    case k_RegPair:
1391
0
      OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1392
0
      break;
1393
0
    }
1394
0
  }
1395
}; // class MipsOperand
1396
} // namespace
1397
1398
namespace llvm_ks {
1399
extern const MCInstrDesc MipsInsts[];
1400
}
1401
15.3k
static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1402
15.3k
  return MipsInsts[Opcode];
1403
15.3k
}
1404
1405
11.8k
static bool hasShortDelaySlot(unsigned Opcode) {
1406
11.8k
  switch (Opcode) {
1407
0
    case Mips::JALS_MM:
1408
0
    case Mips::JALRS_MM:
1409
0
    case Mips::JALRS16_MM:
1410
0
    case Mips::BGEZALS_MM:
1411
0
    case Mips::BLTZALS_MM:
1412
0
      return true;
1413
11.8k
    default:
1414
11.8k
      return false;
1415
11.8k
  }
1416
11.8k
}
1417
1418
16
static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1419
16
  if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1420
10
    return &SRExpr->getSymbol();
1421
10
  }
1422
1423
6
  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1424
0
    const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1425
0
    const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1426
1427
0
    if (LHSSym)
1428
0
      return LHSSym;
1429
1430
0
    if (RHSSym)
1431
0
      return RHSSym;
1432
1433
0
    return nullptr;
1434
0
  }
1435
1436
6
  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1437
6
    return getSingleMCSymbol(UExpr->getSubExpr());
1438
1439
0
  return nullptr;
1440
6
}
1441
1442
16
static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1443
16
  if (isa<MCSymbolRefExpr>(Expr))
1444
10
    return 1;
1445
1446
6
  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1447
0
    return countMCSymbolRefExpr(BExpr->getLHS()) +
1448
0
           countMCSymbolRefExpr(BExpr->getRHS());
1449
1450
6
  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1451
6
    return countMCSymbolRefExpr(UExpr->getSubExpr());
1452
1453
0
  return 0;
1454
6
}
1455
1456
namespace {
1457
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1458
906
            SmallVectorImpl<MCInst> &Instructions) {
1459
906
  MCInst tmpInst;
1460
906
  tmpInst.setOpcode(Opcode);
1461
906
  tmpInst.addOperand(MCOperand::createReg(Reg0));
1462
906
  tmpInst.addOperand(Op1);
1463
906
  tmpInst.setLoc(IDLoc);
1464
906
  Instructions.push_back(tmpInst);
1465
906
}
1466
1467
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1468
322
            SmallVectorImpl<MCInst> &Instructions) {
1469
322
  emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1470
322
}
1471
1472
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1473
0
            SmallVectorImpl<MCInst> &Instructions) {
1474
0
  emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1475
0
}
1476
1477
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1478
0
            SmallVectorImpl<MCInst> &Instructions) {
1479
0
  MCInst tmpInst;
1480
0
  tmpInst.setOpcode(Opcode);
1481
0
  tmpInst.addOperand(MCOperand::createImm(Imm1));
1482
0
  tmpInst.addOperand(MCOperand::createImm(Imm2));
1483
0
  tmpInst.setLoc(IDLoc);
1484
0
  Instructions.push_back(tmpInst);
1485
0
}
1486
1487
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1488
0
           SmallVectorImpl<MCInst> &Instructions) {
1489
0
  MCInst tmpInst;
1490
0
  tmpInst.setOpcode(Opcode);
1491
0
  tmpInst.addOperand(MCOperand::createReg(Reg0));
1492
0
  tmpInst.setLoc(IDLoc);
1493
0
  Instructions.push_back(tmpInst);
1494
0
}
1495
1496
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1497
17.0k
             SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1498
17.0k
  MCInst tmpInst;
1499
17.0k
  tmpInst.setOpcode(Opcode);
1500
17.0k
  tmpInst.addOperand(MCOperand::createReg(Reg0));
1501
17.0k
  tmpInst.addOperand(MCOperand::createReg(Reg1));
1502
17.0k
  tmpInst.addOperand(Op2);
1503
17.0k
  tmpInst.setLoc(IDLoc);
1504
17.0k
  Instructions.push_back(tmpInst);
1505
17.0k
}
1506
1507
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1508
1.53k
             SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1509
1.53k
  emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1510
1.53k
          Instructions);
1511
1.53k
}
1512
1513
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1514
14.8k
             SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1515
14.8k
  emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1516
14.8k
          Instructions);
1517
14.8k
}
1518
1519
void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1520
979
                         SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1521
979
  if (ShiftAmount >= 32) {
1522
37
    emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1523
37
            Instructions);
1524
37
    return;
1525
37
  }
1526
1527
942
  emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1528
942
}
1529
} // end anonymous namespace.
1530
1531
// return true on error
1532
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1533
                                       SmallVectorImpl<MCInst> &Instructions,
1534
                                       unsigned int &KsError)
1535
14.8k
{
1536
14.8k
  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1537
14.8k
  bool ExpandedJalSym = false;
1538
1539
14.8k
  Inst.setLoc(IDLoc);
1540
1541
14.8k
  if (MCID.isBranch() || MCID.isCall()) {
1542
11.9k
    const unsigned Opcode = Inst.getOpcode();
1543
11.9k
    MCOperand Offset;
1544
1545
11.9k
    switch (Opcode) {
1546
4.85k
    default:
1547
4.85k
      break;
1548
4.85k
    case Mips::BBIT0:
1549
0
    case Mips::BBIT032:
1550
0
    case Mips::BBIT1:
1551
0
    case Mips::BBIT132:
1552
0
      assert(hasCnMips() && "instruction only valid for octeon cpus");
1553
      // Fall through
1554
1555
7.05k
    case Mips::BEQ:
1556
7.05k
    case Mips::BNE:
1557
7.05k
    case Mips::BEQ_MM:
1558
7.05k
    case Mips::BNE_MM:
1559
7.05k
      assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1560
7.05k
      Offset = Inst.getOperand(2);
1561
7.05k
      if (!Offset.isImm())
1562
6.97k
        break; // We'll deal with this situation later on when applying fixups.
1563
78
      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) {
1564
21
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1565
21
        return true;
1566
        //return Error(IDLoc, "branch target out of range");
1567
21
      }
1568
57
      if (OffsetToAlignment(Offset.getImm(),
1569
57
                            1LL << (inMicroMipsMode() ? 1 : 2))) {
1570
2
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1571
2
        return true;
1572
        //return Error(IDLoc, "branch to misaligned address");
1573
2
      }
1574
55
      break;
1575
55
    case Mips::BGEZ:
1576
0
    case Mips::BGTZ:
1577
0
    case Mips::BLEZ:
1578
0
    case Mips::BLTZ:
1579
84
    case Mips::BGEZAL:
1580
84
    case Mips::BLTZAL:
1581
86
    case Mips::BC1F:
1582
89
    case Mips::BC1T:
1583
89
    case Mips::BGEZ_MM:
1584
89
    case Mips::BGTZ_MM:
1585
89
    case Mips::BLEZ_MM:
1586
89
    case Mips::BLTZ_MM:
1587
89
    case Mips::BGEZAL_MM:
1588
89
    case Mips::BLTZAL_MM:
1589
89
    case Mips::BC1F_MM:
1590
89
    case Mips::BC1T_MM:
1591
89
      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1592
89
      Offset = Inst.getOperand(1);
1593
89
      if (!Offset.isImm())
1594
70
        break; // We'll deal with this situation later on when applying fixups.
1595
19
      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) {
1596
2
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1597
2
        return true;
1598
        //return Error(IDLoc, "branch target out of range");
1599
2
      }
1600
17
      if (OffsetToAlignment(Offset.getImm(),
1601
17
                            1LL << (inMicroMipsMode() ? 1 : 2))) {
1602
0
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1603
0
        return true;
1604
        //return Error(IDLoc, "branch to misaligned address");
1605
0
      }
1606
17
      break;
1607
17
    case Mips::BEQZ16_MM:
1608
0
    case Mips::BEQZC16_MMR6:
1609
0
    case Mips::BNEZ16_MM:
1610
0
    case Mips::BNEZC16_MMR6:
1611
0
      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1612
0
      Offset = Inst.getOperand(1);
1613
0
      if (!Offset.isImm())
1614
0
        break; // We'll deal with this situation later on when applying fixups.
1615
0
      if (!isInt<8>(Offset.getImm())) {
1616
0
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1617
0
        return true;
1618
        //return Error(IDLoc, "branch target out of range");
1619
0
      }
1620
0
      if (OffsetToAlignment(Offset.getImm(), 2LL)) {
1621
0
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1622
0
        return true;
1623
        //return Error(IDLoc, "branch to misaligned address");
1624
0
      }
1625
0
      break;
1626
11.9k
    }
1627
11.9k
  }
1628
1629
  // SSNOP is deprecated on MIPS32r6/MIPS64r6
1630
  // We still accept it but it is a normal nop.
1631
14.8k
  if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1632
    // std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1633
    // Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1634
    //                                                   "nop instruction");
1635
0
  }
1636
1637
14.8k
  if (hasCnMips()) {
1638
0
    const unsigned Opcode = Inst.getOpcode();
1639
0
    MCOperand Opnd;
1640
0
    int Imm;
1641
1642
0
    switch (Opcode) {
1643
0
      default:
1644
0
        break;
1645
1646
0
      case Mips::BBIT0:
1647
0
      case Mips::BBIT032:
1648
0
      case Mips::BBIT1:
1649
0
      case Mips::BBIT132:
1650
0
        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1651
        // The offset is handled above
1652
0
        Opnd = Inst.getOperand(1);
1653
0
        if (!Opnd.isImm()) {
1654
0
          KsError = KS_ERR_ASM_INVALIDOPERAND;
1655
0
          return true;
1656
          //return Error(IDLoc, "expected immediate operand kind");
1657
0
        }
1658
0
        Imm = Opnd.getImm();
1659
0
        if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1660
0
                              Opcode == Mips::BBIT1 ? 63 : 31)) {
1661
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1662
0
            return true;
1663
          //return Error(IDLoc, "immediate operand value out of range");
1664
0
        }
1665
0
        if (Imm > 31) {
1666
0
          Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1667
0
                                               : Mips::BBIT132);
1668
0
          Inst.getOperand(1).setImm(Imm - 32);
1669
0
        }
1670
0
        break;
1671
1672
0
      case Mips::SEQi:
1673
0
      case Mips::SNEi:
1674
0
        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1675
0
        Opnd = Inst.getOperand(2);
1676
0
        if (!Opnd.isImm()) {
1677
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1678
0
            return true;
1679
            //return Error(IDLoc, "expected immediate operand kind");
1680
0
        }
1681
0
        Imm = Opnd.getImm();
1682
0
        if (!isInt<10>(Imm)) {
1683
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1684
0
            return true;
1685
            //return Error(IDLoc, "immediate operand value out of range");
1686
0
        }
1687
0
        break;
1688
0
    }
1689
0
  }
1690
1691
  // This expansion is not in a function called by tryExpandInstruction()
1692
  // because the pseudo-instruction doesn't have a distinct opcode.
1693
14.8k
  if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1694
453
      inPicMode() && Inst.getOperand(0).isExpr()) {
1695
10
    warnIfNoMacro(IDLoc);
1696
1697
10
    const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1698
1699
    // We can do this expansion if there's only 1 symbol in the argument
1700
    // expression.
1701
10
    if (countMCSymbolRefExpr(JalExpr) > 1) {
1702
0
        KsError = KS_ERR_ASM_INVALIDOPERAND;
1703
0
        return true;
1704
        //return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1705
0
    }
1706
1707
    // FIXME: This is checking the expression can be handled by the later stages
1708
    //        of the assembler. We ought to leave it to those later stages but
1709
    //        we can't do that until we stop evaluateRelocExpr() rewriting the
1710
    //        expressions into non-equivalent forms.
1711
10
    const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1712
1713
    // FIXME: Add support for label+offset operands (currently causes an error).
1714
    // FIXME: Add support for forward-declared local symbols.
1715
    // FIXME: Add expansion for when the LargeGOT option is enabled.
1716
10
    if (JalSym->isInSection() || JalSym->isTemporary()) {
1717
8
      if (isABI_O32()) {
1718
        // If it's a local symbol and the O32 ABI is being used, we expand to:
1719
        //  lw $25, 0($gp)
1720
        //    R_(MICRO)MIPS_GOT16  label
1721
        //  addiu $25, $25, 0
1722
        //    R_(MICRO)MIPS_LO16   label
1723
        //  jalr  $25
1724
0
        const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1725
0
        const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1726
1727
0
        emitRRX(Mips::LW, Mips::T9, Mips::GP,
1728
0
                MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1729
0
        emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1730
0
                MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1731
8
      } else if (isABI_N32() || isABI_N64()) {
1732
        // If it's a local symbol and the N32/N64 ABIs are being used,
1733
        // we expand to:
1734
        //  lw/ld $25, 0($gp)
1735
        //    R_(MICRO)MIPS_GOT_DISP  label
1736
        //  jalr  $25
1737
8
        const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1738
1739
8
        emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1740
8
                MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1741
8
      }
1742
8
    } else {
1743
      // If it's an external/weak symbol, we expand to:
1744
      //  lw/ld    $25, 0($gp)
1745
      //    R_(MICRO)MIPS_CALL16  label
1746
      //  jalr  $25
1747
2
      const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1748
1749
2
      emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1750
2
              MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1751
2
    }
1752
1753
10
    MCInst JalrInst;
1754
10
    if (IsCpRestoreSet && inMicroMipsMode())
1755
0
      JalrInst.setOpcode(Mips::JALRS_MM);
1756
10
    else
1757
10
      JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1758
10
    JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1759
10
    JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1760
1761
    // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1762
    // This relocation is supposed to be an optimization hint for the linker
1763
    // and is not necessary for correctness.
1764
1765
10
    Inst = JalrInst;
1766
10
    ExpandedJalSym = true;
1767
10
  }
1768
1769
14.8k
  if (MCID.mayLoad() || MCID.mayStore()) {
1770
    // Check the offset of memory operand, if it is a symbol
1771
    // reference or immediate we may have to expand instructions.
1772
2.97k
    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1773
2.65k
      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1774
2.65k
      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1775
1.75k
          (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1776
1.75k
        MCOperand &Op = Inst.getOperand(i);
1777
1.75k
        if (Op.isImm()) {
1778
568
          int MemOffset = Op.getImm();
1779
568
          if (MemOffset < -32768 || MemOffset > 32767) {
1780
            // Offset can't exceed 16bit value.
1781
241
            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1782
241
            return false;
1783
241
          }
1784
1.18k
        } else if (Op.isExpr()) {
1785
308
          const MCExpr *Expr = Op.getExpr();
1786
308
          if (Expr->getKind() == MCExpr::SymbolRef) {
1787
107
            const MCSymbolRefExpr *SR =
1788
107
                static_cast<const MCSymbolRefExpr *>(Expr);
1789
107
            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1790
              // Expand symbol.
1791
107
              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1792
107
              return false;
1793
107
            }
1794
201
          } else if (!isEvaluated(Expr)) {
1795
201
            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1796
201
            return false;
1797
201
          }
1798
308
        }
1799
1.75k
      }
1800
2.65k
    } // for
1801
876
  }   // if load/store
1802
1803
14.2k
  if (inMicroMipsMode()) {
1804
0
    if (MCID.mayLoad()) {
1805
      // Try to create 16-bit GP relative load instruction.
1806
0
      for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1807
0
        const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1808
0
        if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1809
0
            (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1810
0
          MCOperand &Op = Inst.getOperand(i);
1811
0
          if (Op.isImm()) {
1812
0
            int MemOffset = Op.getImm();
1813
0
            MCOperand &DstReg = Inst.getOperand(0);
1814
0
            MCOperand &BaseReg = Inst.getOperand(1);
1815
0
            if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1816
0
                getContext().getRegisterInfo()->getRegClass(
1817
0
                  Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1818
0
                (BaseReg.getReg() == Mips::GP ||
1819
0
                BaseReg.getReg() == Mips::GP_64)) {
1820
1821
0
              emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1822
0
                      IDLoc, Instructions);
1823
0
              return false;
1824
0
            }
1825
0
          }
1826
0
        }
1827
0
      } // for
1828
0
    }   // if load
1829
1830
    // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1831
1832
0
    MCOperand Opnd;
1833
0
    int Imm;
1834
1835
0
    switch (Inst.getOpcode()) {
1836
0
      default:
1837
0
        break;
1838
0
      case Mips::ADDIUS5_MM:
1839
0
        Opnd = Inst.getOperand(2);
1840
0
        if (!Opnd.isImm()) {
1841
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1842
0
            return true;
1843
            //return Error(IDLoc, "expected immediate operand kind");
1844
0
        }
1845
0
        Imm = Opnd.getImm();
1846
0
        if (Imm < -8 || Imm > 7) {
1847
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1848
0
            return true;
1849
            //return Error(IDLoc, "immediate operand value out of range");
1850
0
        }
1851
0
        break;
1852
0
      case Mips::ADDIUSP_MM:
1853
0
        Opnd = Inst.getOperand(0);
1854
0
        if (!Opnd.isImm()) {
1855
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1856
0
            return true;
1857
            //return Error(IDLoc, "expected immediate operand kind");
1858
0
        }
1859
0
        Imm = Opnd.getImm();
1860
0
        if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1861
0
            Imm % 4 != 0) {
1862
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1863
0
            return true;
1864
            //return Error(IDLoc, "immediate operand value out of range");
1865
0
        }
1866
0
        break;
1867
0
      case Mips::SLL16_MM:
1868
0
      case Mips::SRL16_MM:
1869
0
        Opnd = Inst.getOperand(2);
1870
0
        if (!Opnd.isImm()) {
1871
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1872
0
            return true;
1873
            //return Error(IDLoc, "expected immediate operand kind");
1874
0
        }
1875
0
        Imm = Opnd.getImm();
1876
0
        if (Imm < 1 || Imm > 8) {
1877
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1878
0
            return true;
1879
            //return Error(IDLoc, "immediate operand value out of range");
1880
0
        }
1881
0
        break;
1882
0
      case Mips::LI16_MM:
1883
0
        Opnd = Inst.getOperand(1);
1884
0
        if (!Opnd.isImm()) {
1885
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1886
0
            return true;
1887
            //return Error(IDLoc, "expected immediate operand kind");
1888
0
        }
1889
0
        Imm = Opnd.getImm();
1890
0
        if (Imm < -1 || Imm > 126) {
1891
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1892
0
            return true;
1893
            //return Error(IDLoc, "immediate operand value out of range");
1894
0
        }
1895
0
        break;
1896
0
      case Mips::ADDIUR2_MM:
1897
0
        Opnd = Inst.getOperand(2);
1898
0
        if (!Opnd.isImm()) {
1899
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1900
0
            return true;
1901
            //return Error(IDLoc, "expected immediate operand kind");
1902
0
        }
1903
0
        Imm = Opnd.getImm();
1904
0
        if (!(Imm == 1 || Imm == -1 ||
1905
0
              ((Imm % 4 == 0) && Imm < 28 && Imm > 0))) {
1906
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1907
0
            return true;
1908
            //return Error(IDLoc, "immediate operand value out of range");
1909
0
        }
1910
0
        break;
1911
0
      case Mips::ADDIUR1SP_MM:
1912
0
        Opnd = Inst.getOperand(1);
1913
0
        if (!Opnd.isImm()) {
1914
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1915
0
            return true;
1916
            //return Error(IDLoc, "expected immediate operand kind");
1917
0
        }
1918
0
        Imm = Opnd.getImm();
1919
0
        if (OffsetToAlignment(Imm, 4LL)) {
1920
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1921
0
            return true;
1922
            //return Error(IDLoc, "misaligned immediate operand value");
1923
0
        }
1924
0
        if (Imm < 0 || Imm > 255) {
1925
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1926
0
            return true;
1927
            //return Error(IDLoc, "immediate operand value out of range");
1928
0
        }
1929
0
        break;
1930
0
      case Mips::ANDI16_MM:
1931
0
        Opnd = Inst.getOperand(2);
1932
0
        if (!Opnd.isImm()) {
1933
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1934
0
            return true;
1935
            //return Error(IDLoc, "expected immediate operand kind");
1936
0
        }
1937
0
        Imm = Opnd.getImm();
1938
0
        if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1939
0
              Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1940
0
              Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535)) {
1941
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1942
0
            return true;
1943
            //return Error(IDLoc, "immediate operand value out of range");
1944
0
        }
1945
0
        break;
1946
0
      case Mips::LBU16_MM:
1947
0
        Opnd = Inst.getOperand(2);
1948
0
        if (!Opnd.isImm()) {
1949
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1950
0
            return true;
1951
            //return Error(IDLoc, "expected immediate operand kind");
1952
0
        }
1953
0
        Imm = Opnd.getImm();
1954
0
        if (Imm < -1 || Imm > 14) {
1955
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1956
0
            return true;
1957
            //return Error(IDLoc, "immediate operand value out of range");
1958
0
        }
1959
0
        break;
1960
0
      case Mips::SB16_MM:
1961
0
      case Mips::SB16_MMR6:
1962
0
        Opnd = Inst.getOperand(2);
1963
0
        if (!Opnd.isImm()) {
1964
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1965
0
            return true;
1966
            //return Error(IDLoc, "expected immediate operand kind");
1967
0
        }
1968
0
        Imm = Opnd.getImm();
1969
0
        if (Imm < 0 || Imm > 15) {
1970
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1971
0
            return true;
1972
            //return Error(IDLoc, "immediate operand value out of range");
1973
0
        }
1974
0
        break;
1975
0
      case Mips::LHU16_MM:
1976
0
      case Mips::SH16_MM:
1977
0
      case Mips::SH16_MMR6:
1978
0
        Opnd = Inst.getOperand(2);
1979
0
        if (!Opnd.isImm()) {
1980
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1981
0
            return true;
1982
            //return Error(IDLoc, "expected immediate operand kind");
1983
0
        }
1984
0
        Imm = Opnd.getImm();
1985
0
        if (Imm < 0 || Imm > 30 || (Imm % 2 != 0)) {
1986
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1987
0
            return true;
1988
            //return Error(IDLoc, "immediate operand value out of range");
1989
0
         }
1990
0
        break;
1991
0
      case Mips::LW16_MM:
1992
0
      case Mips::SW16_MM:
1993
0
      case Mips::SW16_MMR6:
1994
0
        Opnd = Inst.getOperand(2);
1995
0
        if (!Opnd.isImm()) {
1996
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
1997
0
            return true;
1998
            //return Error(IDLoc, "expected immediate operand kind");
1999
0
        }
2000
0
        Imm = Opnd.getImm();
2001
0
        if (Imm < 0 || Imm > 60 || (Imm % 4 != 0)) {
2002
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
2003
0
            return true;
2004
            //return Error(IDLoc, "immediate operand value out of range");
2005
0
        }
2006
0
        break;
2007
0
      case Mips::ADDIUPC_MM:
2008
0
        MCOperand Opnd = Inst.getOperand(1);
2009
0
        if (!Opnd.isImm()) {
2010
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
2011
0
            return true;
2012
            //return Error(IDLoc, "expected immediate operand kind");
2013
0
        }
2014
0
        int Imm = Opnd.getImm();
2015
0
        if ((Imm % 4 != 0) || !isInt<25>(Imm)) {
2016
0
            KsError = KS_ERR_ASM_INVALIDOPERAND;
2017
0
            return true;
2018
            //return Error(IDLoc, "immediate operand value out of range");
2019
0
        }
2020
0
        break;
2021
0
    }
2022
0
  }
2023
2024
14.2k
  MacroExpanderResultTy ExpandResult =
2025
14.2k
      tryExpandInstruction(Inst, IDLoc, Instructions);
2026
14.2k
  switch (ExpandResult) {
2027
13.1k
  case MER_NotAMacro:
2028
13.1k
    Instructions.push_back(Inst);
2029
13.1k
    break;
2030
1.06k
  case MER_Success:
2031
1.06k
    break;
2032
7
  case MER_Fail:
2033
7
    return true;
2034
14.2k
  }
2035
2036
  // If this instruction has a delay slot and .set reorder is active,
2037
  // emit a NOP after it.
2038
14.2k
  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2039
11.8k
    createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
2040
2041
14.2k
  if ((Inst.getOpcode() == Mips::JalOneReg ||
2042
14.2k
       Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2043
21
      isPicAndNotNxxAbi()) {
2044
0
    if (IsCpRestoreSet) {
2045
      // We need a NOP between the JALR and the LW:
2046
      // If .set reorder has been used, we've already emitted a NOP.
2047
      // If .set noreorder has been used, we need to emit a NOP at this point.
2048
0
      if (!AssemblerOptions.back()->isReorder())
2049
0
        createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
2050
2051
      // Load the $gp from the stack.
2052
0
      SmallVector<MCInst, 3> LoadInsts;
2053
0
      createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
2054
0
                           IDLoc, LoadInsts);
2055
2056
0
      for (const MCInst &Inst : LoadInsts)
2057
0
        Instructions.push_back(Inst);
2058
2059
0
    } else {
2060
      // Warning(IDLoc, "no .cprestore used in PIC mode");
2061
0
    }
2062
0
  }
2063
2064
14.2k
  return false;
2065
14.2k
}
2066
2067
MipsAsmParser::MacroExpanderResultTy
2068
MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
2069
14.2k
                                    SmallVectorImpl<MCInst> &Instructions) {
2070
14.2k
  switch (Inst.getOpcode()) {
2071
12.4k
  default:
2072
12.4k
    return MER_NotAMacro;
2073
4
  case Mips::LoadImm32:
2074
4
    return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
2075
4
                                                          : MER_Success;
2076
0
  case Mips::LoadImm64:
2077
0
    return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
2078
0
                                                           : MER_Success;
2079
22
  case Mips::LoadAddrImm32:
2080
33
  case Mips::LoadAddrImm64:
2081
33
    assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2082
33
    assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2083
33
           "expected immediate operand kind");
2084
2085
33
    return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2086
33
                             Inst.getOperand(1),
2087
33
                             Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2088
33
                             Instructions)
2089
33
               ? MER_Fail
2090
33
               : MER_Success;
2091
0
  case Mips::LoadAddrReg32:
2092
0
  case Mips::LoadAddrReg64:
2093
0
    assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2094
0
    assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2095
0
    assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2096
0
           "expected immediate operand kind");
2097
2098
0
    return expandLoadAddress(Inst.getOperand(0).getReg(),
2099
0
                             Inst.getOperand(1).getReg(), Inst.getOperand(2),
2100
0
                             Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2101
0
                             Instructions)
2102
0
               ? MER_Fail
2103
0
               : MER_Success;
2104
0
  case Mips::B_MM_Pseudo:
2105
0
  case Mips::B_MMR6_Pseudo:
2106
0
    return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
2107
0
                                                                 : MER_Success;
2108
0
  case Mips::SWM_MM:
2109
0
  case Mips::LWM_MM:
2110
0
    return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
2111
0
                                                              : MER_Success;
2112
11
  case Mips::JalOneReg:
2113
11
  case Mips::JalTwoReg:
2114
11
    return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
2115
11
                                                        : MER_Success;
2116
0
  case Mips::BneImm:
2117
0
  case Mips::BeqImm:
2118
0
    return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2119
0
  case Mips::BLT:
2120
0
  case Mips::BLE:
2121
0
  case Mips::BGE:
2122
0
  case Mips::BGT:
2123
0
  case Mips::BLTU:
2124
0
  case Mips::BLEU:
2125
0
  case Mips::BGEU:
2126
0
  case Mips::BGTU:
2127
0
  case Mips::BLTL:
2128
0
  case Mips::BLEL:
2129
0
  case Mips::BGEL:
2130
0
  case Mips::BGTL:
2131
0
  case Mips::BLTUL:
2132
0
  case Mips::BLEUL:
2133
0
  case Mips::BGEUL:
2134
0
  case Mips::BGTUL:
2135
0
  case Mips::BLTImmMacro:
2136
0
  case Mips::BLEImmMacro:
2137
0
  case Mips::BGEImmMacro:
2138
0
  case Mips::BGTImmMacro:
2139
0
  case Mips::BLTUImmMacro:
2140
0
  case Mips::BLEUImmMacro:
2141
0
  case Mips::BGEUImmMacro:
2142
0
  case Mips::BGTUImmMacro:
2143
0
  case Mips::BLTLImmMacro:
2144
0
  case Mips::BLELImmMacro:
2145
0
  case Mips::BGELImmMacro:
2146
0
  case Mips::BGTLImmMacro:
2147
0
  case Mips::BLTULImmMacro:
2148
0
  case Mips::BLEULImmMacro:
2149
0
  case Mips::BGEULImmMacro:
2150
0
  case Mips::BGTULImmMacro:
2151
0
    return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2152
0
                                                         : MER_Success;
2153
0
  case Mips::SDivMacro:
2154
0
    return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2155
0
                                                             : MER_Success;
2156
0
  case Mips::DSDivMacro:
2157
0
    return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2158
0
                                                            : MER_Success;
2159
0
  case Mips::UDivMacro:
2160
0
    return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2161
0
                                                              : MER_Success;
2162
0
  case Mips::DUDivMacro:
2163
0
    return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2164
0
                                                             : MER_Success;
2165
0
  case Mips::Ulh:
2166
0
    return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2167
0
  case Mips::Ulhu:
2168
0
    return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2169
0
  case Mips::Ulw:
2170
0
    return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2171
0
  case Mips::NORImm:
2172
0
    return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2173
0
                                                           : MER_Success;
2174
0
  case Mips::ADDi:
2175
0
  case Mips::ADDiu:
2176
0
  case Mips::SLTi:
2177
0
  case Mips::SLTiu:
2178
0
    if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2179
0
        Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2180
0
      int64_t ImmValue = Inst.getOperand(2).getImm();
2181
0
      if (isInt<16>(ImmValue))
2182
0
        return MER_NotAMacro;
2183
0
      return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2184
0
                                                             : MER_Success;
2185
0
    }
2186
0
    return MER_NotAMacro;
2187
1
  case Mips::ANDi:
2188
1.72k
  case Mips::ORi:
2189
1.73k
  case Mips::XORi:
2190
1.73k
    if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2191
1.73k
        Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2192
1.17k
      int64_t ImmValue = Inst.getOperand(2).getImm();
2193
1.17k
      if (isUInt<16>(ImmValue))
2194
201
        return MER_NotAMacro;
2195
973
      return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2196
973
                                                             : MER_Success;
2197
1.17k
    }
2198
558
    return MER_NotAMacro;
2199
0
  case Mips::ROL:
2200
0
  case Mips::ROR:
2201
0
    return expandRotation(Inst, IDLoc, Instructions) ? MER_Fail
2202
0
                                                     : MER_Success;
2203
0
  case Mips::ROLImm:
2204
18
  case Mips::RORImm:
2205
18
    return expandRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2206
18
                                                        : MER_Success;
2207
0
  case Mips::DROL:
2208
0
  case Mips::DROR:
2209
0
    return expandDRotation(Inst, IDLoc, Instructions) ? MER_Fail
2210
0
                                                      : MER_Success;
2211
2
  case Mips::DROLImm:
2212
2
  case Mips::DRORImm:
2213
2
    return expandDRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
2214
2
                                                         : MER_Success;
2215
32
  case Mips::ABSMacro:
2216
32
    return expandAbs(Inst, IDLoc, Instructions) ? MER_Fail
2217
32
                                                : MER_Success;
2218
14.2k
  }
2219
14.2k
}
2220
2221
bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2222
11
                                      SmallVectorImpl<MCInst> &Instructions) {
2223
  // Create a JALR instruction which is going to replace the pseudo-JAL.
2224
11
  MCInst JalrInst;
2225
11
  JalrInst.setLoc(IDLoc);
2226
11
  const MCOperand FirstRegOp = Inst.getOperand(0);
2227
11
  const unsigned Opcode = Inst.getOpcode();
2228
2229
11
  if (Opcode == Mips::JalOneReg) {
2230
    // jal $rs => jalr $rs
2231
11
    if (IsCpRestoreSet && inMicroMipsMode()) {
2232
0
      JalrInst.setOpcode(Mips::JALRS16_MM);
2233
0
      JalrInst.addOperand(FirstRegOp);
2234
11
    } else if (inMicroMipsMode()) {
2235
0
      JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2236
0
      JalrInst.addOperand(FirstRegOp);
2237
11
    } else {
2238
11
      JalrInst.setOpcode(Mips::JALR);
2239
11
      JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2240
11
      JalrInst.addOperand(FirstRegOp);
2241
11
    }
2242
11
  } else if (Opcode == Mips::JalTwoReg) {
2243
    // jal $rd, $rs => jalr $rd, $rs
2244
0
    if (IsCpRestoreSet && inMicroMipsMode())
2245
0
      JalrInst.setOpcode(Mips::JALRS_MM);
2246
0
    else
2247
0
      JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2248
0
    JalrInst.addOperand(FirstRegOp);
2249
0
    const MCOperand SecondRegOp = Inst.getOperand(1);
2250
0
    JalrInst.addOperand(SecondRegOp);
2251
0
  }
2252
11
  Instructions.push_back(JalrInst);
2253
2254
  // If .set reorder is active and branch instruction has a delay slot,
2255
  // emit a NOP after it.
2256
11
  const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2257
11
  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2258
11
    createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2259
11
  }
2260
2261
11
  return false;
2262
11
}
2263
2264
/// Can the value be represented by a unsigned N-bit value and a shift left?
2265
661
template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2266
661
  unsigned BitNum = findFirstSet(x);
2267
2268
661
  return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2269
661
}
2270
2271
/// Load (or add) an immediate into a register.
2272
///
2273
/// @param ImmValue     The immediate to load.
2274
/// @param DstReg       The register that will hold the immediate.
2275
/// @param SrcReg       A register to add to the immediate or Mips::NoRegister
2276
///                     for a simple initialization.
2277
/// @param Is32BitImm   Is ImmValue 32-bit or 64-bit?
2278
/// @param IsAddress    True if the immediate represents an address. False if it
2279
///                     is an integer.
2280
/// @param IDLoc        Location of the immediate in the source file.
2281
/// @param Instructions The instructions emitted by this expansion.
2282
bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2283
                                  unsigned SrcReg, bool Is32BitImm,
2284
                                  bool IsAddress, SMLoc IDLoc,
2285
1.49k
                                  SmallVectorImpl<MCInst> &Instructions) {
2286
1.49k
  if (!Is32BitImm && !isGP64bit()) {
2287
1
    Error(IDLoc, "instruction requires a 64-bit architecture");
2288
1
    return true;
2289
1
  }
2290
2291
1.49k
  if (Is32BitImm) {
2292
822
    if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2293
      // Sign extend up to 64-bit so that the predicates match the hardware
2294
      // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2295
      // true.
2296
819
      ImmValue = SignExtend64<32>(ImmValue);
2297
819
    } else {
2298
3
      Error(IDLoc, "instruction requires a 32-bit immediate");
2299
3
      return true;
2300
3
    }
2301
822
  }
2302
2303
1.49k
  unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2304
1.49k
  unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2305
2306
1.49k
  bool UseSrcReg = false;
2307
1.49k
  if (SrcReg != Mips::NoRegister)
2308
0
    UseSrcReg = true;
2309
2310
1.49k
  unsigned TmpReg = DstReg;
2311
1.49k
  if (UseSrcReg &&
2312
0
      getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2313
    // At this point we need AT to perform the expansions and we exit if it is
2314
    // not available.
2315
0
    unsigned ATReg = getATReg(IDLoc);
2316
0
    if (!ATReg)
2317
0
      return true;
2318
0
    TmpReg = ATReg;
2319
0
  }
2320
2321
1.49k
  if (isInt<16>(ImmValue)) {
2322
531
    if (!UseSrcReg)
2323
531
      SrcReg = ZeroReg;
2324
2325
    // This doesn't quite follow the usual ABI expectations for N32 but matches
2326
    // traditional assembler behaviour. N32 would normally use addiu for both
2327
    // integers and addresses.
2328
531
    if (IsAddress && !Is32BitImm) {
2329
4
      emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2330
4
      return false;
2331
4
    }
2332
2333
527
    emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2334
527
    return false;
2335
531
  }
2336
2337
962
  if (isUInt<16>(ImmValue)) {
2338
11
    unsigned TmpReg = DstReg;
2339
11
    if (SrcReg == DstReg) {
2340
0
      TmpReg = getATReg(IDLoc);
2341
0
      if (!TmpReg)
2342
0
        return true;
2343
0
    }
2344
2345
11
    emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2346
11
    if (UseSrcReg)
2347
0
      emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2348
11
    return false;
2349
11
  }
2350
2351
951
  if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2352
290
    warnIfNoMacro(IDLoc);
2353
2354
290
    uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2355
290
    uint16_t Bits15To0 = ImmValue & 0xffff;
2356
2357
290
    if (!Is32BitImm && !isInt<32>(ImmValue)) {
2358
      // Traditional behaviour seems to special case this particular value. It's
2359
      // not clear why other masks are handled differently.
2360
0
      if (ImmValue == 0xffffffff) {
2361
0
        emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2362
0
        emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2363
0
        if (UseSrcReg)
2364
0
          emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2365
0
        return false;
2366
0
      }
2367
2368
      // Expand to an ORi instead of a LUi to avoid sign-extending into the
2369
      // upper 32 bits.
2370
0
      emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2371
0
      emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2372
0
      if (Bits15To0)
2373
0
        emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2374
0
      if (UseSrcReg)
2375
0
        emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2376
0
      return false;
2377
0
    }
2378
2379
290
    emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2380
290
    if (Bits15To0)
2381
265
      emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2382
290
    if (UseSrcReg)
2383
0
      emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2384
290
    return false;
2385
290
  }
2386
2387
661
  if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2388
153
    if (Is32BitImm) {
2389
0
      Error(IDLoc, "instruction requires a 32-bit immediate");
2390
0
      return true;
2391
0
    }
2392
2393
    // Traditionally, these immediates are shifted as little as possible and as
2394
    // such we align the most significant bit to bit 15 of our temporary.
2395
153
    unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2396
153
    unsigned LastSet = findLastSet((uint64_t)ImmValue);
2397
153
    unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2398
153
    uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2399
153
    emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2400
153
    emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2401
2402
153
    if (UseSrcReg)
2403
0
      emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2404
2405
153
    return false;
2406
153
  }
2407
2408
508
  warnIfNoMacro(IDLoc);
2409
2410
  // The remaining case is packed with a sequence of dsll and ori with zeros
2411
  // being omitted and any neighbouring dsll's being coalesced.
2412
  // The highest 32-bit's are equivalent to a 32-bit immediate load.
2413
2414
  // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2415
508
  if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2416
508
                    IDLoc, Instructions))
2417
0
    return false;
2418
2419
  // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2420
  // skip it and defer the shift to the next chunk.
2421
508
  unsigned ShiftCarriedForwards = 16;
2422
1.52k
  for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2423
1.01k
    uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2424
2425
1.01k
    if (ImmChunk != 0) {
2426
871
      emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2427
871
                          Instructions);
2428
871
      emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2429
871
      ShiftCarriedForwards = 0;
2430
871
    }
2431
2432
1.01k
    ShiftCarriedForwards += 16;
2433
1.01k
  }
2434
508
  ShiftCarriedForwards -= 16;
2435
2436
  // Finish any remaining shifts left by trailing zeros.
2437
508
  if (ShiftCarriedForwards)
2438
108
    emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2439
108
                        Instructions);
2440
2441
508
  if (UseSrcReg)
2442
0
    emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2443
2444
508
  return false;
2445
508
}
2446
2447
bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2448
4
                                  SmallVectorImpl<MCInst> &Instructions) {
2449
4
  const MCOperand &ImmOp = Inst.getOperand(1);
2450
4
  assert(ImmOp.isImm() && "expected immediate operand kind");
2451
4
  const MCOperand &DstRegOp = Inst.getOperand(0);
2452
4
  assert(DstRegOp.isReg() && "expected register operand kind");
2453
2454
4
  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2455
4
                    Is32BitImm, false, IDLoc, Instructions))
2456
3
    return true;
2457
2458
1
  return false;
2459
4
}
2460
2461
bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2462
                                      const MCOperand &Offset,
2463
                                      bool Is32BitAddress, SMLoc IDLoc,
2464
33
                                      SmallVectorImpl<MCInst> &Instructions) {
2465
  // la can't produce a usable address when addresses are 64-bit.
2466
33
  if (Is32BitAddress && ABI.ArePtrs64bit()) {
2467
    // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2468
    //        We currently can't do this because we depend on the equality
2469
    //        operator and N64 can end up with a GPR32/GPR64 mismatch.
2470
22
    Error(IDLoc, "la used to load 64-bit address");
2471
    // Continue as if we had 'dla' instead.
2472
22
    Is32BitAddress = false;
2473
22
  }
2474
2475
  // dla requires 64-bit addresses.
2476
33
  if (!Is32BitAddress && !hasMips3()) {
2477
1
    Error(IDLoc, "instruction requires a 64-bit architecture");
2478
1
    return true;
2479
1
  }
2480
2481
32
  if (!Offset.isImm())
2482
19
    return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2483
19
                                   Is32BitAddress, IDLoc, Instructions);
2484
2485
13
  if (!ABI.ArePtrs64bit()) {
2486
    // Continue as if we had 'la' whether we had 'la' or 'dla'.
2487
0
    Is32BitAddress = true;
2488
0
  }
2489
2490
13
  return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2491
13
                       IDLoc, Instructions);
2492
32
}
2493
2494
bool MipsAsmParser::loadAndAddSymbolAddress(
2495
    const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2496
19
    SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2497
19
  warnIfNoMacro(IDLoc);
2498
2499
19
  const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2500
19
  const MipsMCExpr *HiExpr = MipsMCExpr::create(
2501
19
      MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2502
19
  const MipsMCExpr *LoExpr = MipsMCExpr::create(
2503
19
      MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2504
2505
19
  bool UseSrcReg = SrcReg != Mips::NoRegister;
2506
2507
  // This is the 64-bit symbol address expansion.
2508
19
  if (ABI.ArePtrs64bit() && isGP64bit()) {
2509
    // We always need AT for the 64-bit expansion.
2510
    // If it is not available we exit.
2511
19
    unsigned ATReg = getATReg(IDLoc);
2512
19
    if (!ATReg)
2513
1
      return true;
2514
2515
18
    const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2516
18
        MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2517
18
    const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2518
18
        MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2519
2520
18
    if (UseSrcReg &&
2521
0
        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2522
0
                                                               SrcReg)) {
2523
      // If $rs is the same as $rd:
2524
      // (d)la $rd, sym($rd) => lui    $at, %highest(sym)
2525
      //                        daddiu $at, $at, %higher(sym)
2526
      //                        dsll   $at, $at, 16
2527
      //                        daddiu $at, $at, %hi(sym)
2528
      //                        dsll   $at, $at, 16
2529
      //                        daddiu $at, $at, %lo(sym)
2530
      //                        daddu  $rd, $at, $rd
2531
0
      emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2532
0
             Instructions);
2533
0
      emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2534
0
              IDLoc, Instructions);
2535
0
      emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2536
0
      emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2537
0
              Instructions);
2538
0
      emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2539
0
      emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2540
0
              Instructions);
2541
0
      emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2542
2543
0
      return false;
2544
0
    }
2545
2546
    // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2547
    // (d)la $rd, sym/sym($rs) => lui    $rd, %highest(sym)
2548
    //                            lui    $at, %hi(sym)
2549
    //                            daddiu $rd, $rd, %higher(sym)
2550
    //                            daddiu $at, $at, %lo(sym)
2551
    //                            dsll32 $rd, $rd, 0
2552
    //                            daddu  $rd, $rd, $at
2553
    //                            (daddu  $rd, $rd, $rs)
2554
18
    emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2555
18
           Instructions);
2556
18
    emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2557
18
           Instructions);
2558
18
    emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2559
18
            IDLoc, Instructions);
2560
18
    emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2561
18
            Instructions);
2562
18
    emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2563
18
    emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2564
18
    if (UseSrcReg)
2565
0
      emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2566
2567
18
    return false;
2568
18
  }
2569
2570
  // And now, the 32-bit symbol address expansion:
2571
  // If $rs is the same as $rd:
2572
  // (d)la $rd, sym($rd)     => lui   $at, %hi(sym)
2573
  //                            ori   $at, $at, %lo(sym)
2574
  //                            addu  $rd, $at, $rd
2575
  // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2576
  // (d)la $rd, sym/sym($rs) => lui   $rd, %hi(sym)
2577
  //                            ori   $rd, $rd, %lo(sym)
2578
  //                            (addu $rd, $rd, $rs)
2579
0
  unsigned TmpReg = DstReg;
2580
0
  if (UseSrcReg &&
2581
0
      getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2582
    // If $rs is the same as $rd, we need to use AT.
2583
    // If it is not available we exit.
2584
0
    unsigned ATReg = getATReg(IDLoc);
2585
0
    if (!ATReg)
2586
0
      return true;
2587
0
    TmpReg = ATReg;
2588
0
  }
2589
2590
0
  emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2591
0
  emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2592
0
          Instructions);
2593
2594
0
  if (UseSrcReg)
2595
0
    emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2596
0
  else
2597
0
    assert(
2598
0
        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2599
2600
0
  return false;
2601
0
}
2602
2603
bool MipsAsmParser::expandUncondBranchMMPseudo(
2604
0
    MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2605
0
  assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2606
0
         "unexpected number of operands");
2607
2608
0
  MCOperand Offset = Inst.getOperand(0);
2609
0
  if (Offset.isExpr()) {
2610
0
    Inst.clear();
2611
0
    Inst.setOpcode(Mips::BEQ_MM);
2612
0
    Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2613
0
    Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2614
0
    Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2615
0
  } else {
2616
0
    assert(Offset.isImm() && "expected immediate operand kind");
2617
0
    if (isInt<11>(Offset.getImm())) {
2618
      // If offset fits into 11 bits then this instruction becomes microMIPS
2619
      // 16-bit unconditional branch instruction.
2620
0
      if (inMicroMipsMode())
2621
0
        Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2622
0
    } else {
2623
0
      if (!isInt<17>(Offset.getImm()))
2624
0
        Error(IDLoc, "branch target out of range");
2625
0
      if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2626
0
        Error(IDLoc, "branch to misaligned address");
2627
0
      Inst.clear();
2628
0
      Inst.setOpcode(Mips::BEQ_MM);
2629
0
      Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2630
0
      Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2631
0
      Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2632
0
    }
2633
0
  }
2634
0
  Instructions.push_back(Inst);
2635
2636
  // If .set reorder is active and branch instruction has a delay slot,
2637
  // emit a NOP after it.
2638
0
  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2639
0
  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2640
0
    createNop(true, IDLoc, Instructions);
2641
2642
0
  return false;
2643
0
}
2644
2645
bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2646
0
                                    SmallVectorImpl<MCInst> &Instructions) {
2647
0
  const MCOperand &DstRegOp = Inst.getOperand(0);
2648
0
  assert(DstRegOp.isReg() && "expected register operand kind");
2649
2650
0
  const MCOperand &ImmOp = Inst.getOperand(1);
2651
0
  assert(ImmOp.isImm() && "expected immediate operand kind");
2652
2653
0
  const MCOperand &MemOffsetOp = Inst.getOperand(2);
2654
0
  assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2655
2656
0
  unsigned OpCode = 0;
2657
0
  switch(Inst.getOpcode()) {
2658
0
    case Mips::BneImm:
2659
0
      OpCode = Mips::BNE;
2660
0
      break;
2661
0
    case Mips::BeqImm:
2662
0
      OpCode = Mips::BEQ;
2663
0
      break;
2664
0
    default:
2665
0
      llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2666
0
      break;
2667
0
  }
2668
2669
0
  int64_t ImmValue = ImmOp.getImm();
2670
0
  if (ImmValue == 0)
2671
0
    emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2672
0
            Instructions);
2673
0
  else {
2674
0
    warnIfNoMacro(IDLoc);
2675
2676
0
    unsigned ATReg = getATReg(IDLoc);
2677
0
    if (!ATReg)
2678
0
      return true;
2679
2680
0
    if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2681
0
                      IDLoc, Instructions))
2682
0
      return true;
2683
2684
0
    emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2685
0
  }
2686
0
  return false;
2687
0
}
2688
2689
void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2690
                                  SmallVectorImpl<MCInst> &Instructions,
2691
551
                                  bool isLoad, bool isImmOpnd) {
2692
551
  unsigned ImmOffset, HiOffset, LoOffset;
2693
551
  const MCExpr *ExprOffset;
2694
551
  unsigned TmpRegNum;
2695
  // 1st operand is either the source or destination register.
2696
551
  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2697
551
  unsigned RegOpNum = Inst.getOperand(0).getReg();
2698
  // 2nd operand is the base register.
2699
551
  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2700
551
  unsigned BaseRegNum = Inst.getOperand(1).getReg();
2701
  // 3rd operand is either an immediate or expression.
2702
551
  if (isImmOpnd) {
2703
243
    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2704
243
    ImmOffset = Inst.getOperand(2).getImm();
2705
243
    LoOffset = ImmOffset & 0x0000ffff;
2706
243
    HiOffset = (ImmOffset & 0xffff0000) >> 16;
2707
    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2708
243
    if (LoOffset & 0x8000)
2709
79
      HiOffset++;
2710
243
  } else
2711
308
    ExprOffset = Inst.getOperand(2).getExpr();
2712
  // These are some of the types of expansions we perform here:
2713
  // 1) lw $8, sym        => lui $8, %hi(sym)
2714
  //                         lw $8, %lo(sym)($8)
2715
  // 2) lw $8, offset($9) => lui $8, %hi(offset)
2716
  //                         add $8, $8, $9
2717
  //                         lw $8, %lo(offset)($9)
2718
  // 3) lw $8, offset($8) => lui $at, %hi(offset)
2719
  //                         add $at, $at, $8
2720
  //                         lw $8, %lo(offset)($at)
2721
  // 4) sw $8, sym        => lui $at, %hi(sym)
2722
  //                         sw $8, %lo(sym)($at)
2723
  // 5) sw $8, offset($8) => lui $at, %hi(offset)
2724
  //                         add $at, $at, $8
2725
  //                         sw $8, %lo(offset)($at)
2726
  // 6) ldc1 $f0, sym     => lui $at, %hi(sym)
2727
  //                         ldc1 $f0, %lo(sym)($at)
2728
  //
2729
  // For load instructions we can use the destination register as a temporary
2730
  // if base and dst are different (examples 1 and 2) and if the base register
2731
  // is general purpose otherwise we must use $at (example 6) and error if it's
2732
  // not available. For stores we must use $at (examples 4 and 5) because we
2733
  // must not clobber the source register setting up the offset.
2734
551
  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2735
551
  int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2736
551
  unsigned RegClassIDOp0 =
2737
551
      getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2738
551
  bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2739
137
               (RegClassIDOp0 == Mips::GPR64RegClassID);
2740
551
  if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2741
359
    TmpRegNum = RegOpNum;
2742
192
  else {
2743
    // At this point we need AT to perform the expansions and we exit if it is
2744
    // not available.
2745
192
    TmpRegNum = getATReg(IDLoc);
2746
192
    if (!TmpRegNum)
2747
3
      return;
2748
192
  }
2749
2750
548
  emitRX(Mips::LUi, TmpRegNum,
2751
548
         isImmOpnd ? MCOperand::createImm(HiOffset)
2752
548
                   : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2753
548
         IDLoc, Instructions);
2754
  // Add temp register to base.
2755
548
  if (BaseRegNum != Mips::ZERO)
2756
464
    emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2757
  // And finally, create original instruction with low part
2758
  // of offset and new base.
2759
548
  emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2760
548
          isImmOpnd
2761
548
              ? MCOperand::createImm(LoOffset)
2762
548
              : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2763
548
          IDLoc, Instructions);
2764
548
}
2765
2766
bool
2767
MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2768
0
                                       SmallVectorImpl<MCInst> &Instructions) {
2769
0
  unsigned OpNum = Inst.getNumOperands();
2770
0
  unsigned Opcode = Inst.getOpcode();
2771
0
  unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2772
2773
0
  assert (Inst.getOperand(OpNum - 1).isImm() &&
2774
0
          Inst.getOperand(OpNum - 2).isReg() &&
2775
0
          Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2776
2777
0
  if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2778
0
      Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2779
0
      (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2780
0
       Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2781
0
      (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2782
0
       Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2783
    // It can be implemented as SWM16 or LWM16 instruction.
2784
0
    if (inMicroMipsMode() && hasMips32r6())
2785
0
      NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2786
0
    else
2787
0
      NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2788
0
  }
2789
2790
0
  Inst.setOpcode(NewOpcode);
2791
0
  Instructions.push_back(Inst);
2792
0
  return false;
2793
0
}
2794
2795
bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2796
0
                                       SmallVectorImpl<MCInst> &Instructions) {
2797
0
  bool EmittedNoMacroWarning = false;
2798
0
  unsigned PseudoOpcode = Inst.getOpcode();
2799
0
  unsigned SrcReg = Inst.getOperand(0).getReg();
2800
0
  const MCOperand &TrgOp = Inst.getOperand(1);
2801
0
  const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2802
2803
0
  unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2804
0
  bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2805
2806
0
  unsigned TrgReg;
2807
0
  if (TrgOp.isReg())
2808
0
    TrgReg = TrgOp.getReg();
2809
0
  else if (TrgOp.isImm()) {
2810
0
    warnIfNoMacro(IDLoc);
2811
0
    EmittedNoMacroWarning = true;
2812
2813
0
    TrgReg = getATReg(IDLoc);
2814
0
    if (!TrgReg)
2815
0
      return true;
2816
2817
0
    switch(PseudoOpcode) {
2818
0
    default:
2819
0
      llvm_unreachable("unknown opcode for branch pseudo-instruction");
2820
0
    case Mips::BLTImmMacro:
2821
0
      PseudoOpcode = Mips::BLT;
2822
0
      break;
2823
0
    case Mips::BLEImmMacro:
2824
0
      PseudoOpcode = Mips::BLE;
2825
0
      break;
2826
0
    case Mips::BGEImmMacro:
2827
0
      PseudoOpcode = Mips::BGE;
2828
0
      break;
2829
0
    case Mips::BGTImmMacro:
2830
0
      PseudoOpcode = Mips::BGT;
2831
0
      break;
2832
0
    case Mips::BLTUImmMacro:
2833
0
      PseudoOpcode = Mips::BLTU;
2834
0
      break;
2835
0
    case Mips::BLEUImmMacro:
2836
0
      PseudoOpcode = Mips::BLEU;
2837
0
      break;
2838
0
    case Mips::BGEUImmMacro:
2839
0
      PseudoOpcode = Mips::BGEU;
2840
0
      break;
2841
0
    case Mips::BGTUImmMacro:
2842
0
      PseudoOpcode = Mips::BGTU;
2843
0
      break;
2844
0
    case Mips::BLTLImmMacro:
2845
0
      PseudoOpcode = Mips::BLTL;
2846
0
      break;
2847
0
    case Mips::BLELImmMacro:
2848
0
      PseudoOpcode = Mips::BLEL;
2849
0
      break;
2850
0
    case Mips::BGELImmMacro:
2851
0
      PseudoOpcode = Mips::BGEL;
2852
0
      break;
2853
0
    case Mips::BGTLImmMacro:
2854
0
      PseudoOpcode = Mips::BGTL;
2855
0
      break;
2856
0
    case Mips::BLTULImmMacro:
2857
0
      PseudoOpcode = Mips::BLTUL;
2858
0
      break;
2859
0
    case Mips::BLEULImmMacro:
2860
0
      PseudoOpcode = Mips::BLEUL;
2861
0
      break;
2862
0
    case Mips::BGEULImmMacro:
2863
0
      PseudoOpcode = Mips::BGEUL;
2864
0
      break;
2865
0
    case Mips::BGTULImmMacro:
2866
0
      PseudoOpcode = Mips::BGTUL;
2867
0
      break;
2868
0
    }
2869
2870
0
    if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2871
0
                      false, IDLoc, Instructions))
2872
0
      return true;
2873
0
  }
2874
2875
0
  switch (PseudoOpcode) {
2876
0
  case Mips::BLT:
2877
0
  case Mips::BLTU:
2878
0
  case Mips::BLTL:
2879
0
  case Mips::BLTUL:
2880
0
    AcceptsEquality = false;
2881
0
    ReverseOrderSLT = false;
2882
0
    IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2883
0
    IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2884
0
    ZeroSrcOpcode = Mips::BGTZ;
2885
0
    ZeroTrgOpcode = Mips::BLTZ;
2886
0
    break;
2887
0
  case Mips::BLE:
2888
0
  case Mips::BLEU:
2889
0
  case Mips::BLEL:
2890
0
  case Mips::BLEUL:
2891
0
    AcceptsEquality = true;
2892
0
    ReverseOrderSLT = true;
2893
0
    IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2894
0
    IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2895
0
    ZeroSrcOpcode = Mips::BGEZ;
2896
0
    ZeroTrgOpcode = Mips::BLEZ;
2897
0
    break;
2898
0
  case Mips::BGE:
2899
0
  case Mips::BGEU:
2900
0
  case Mips::BGEL:
2901
0
  case Mips::BGEUL:
2902
0
    AcceptsEquality = true;
2903
0
    ReverseOrderSLT = false;
2904
0
    IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2905
0
    IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2906
0
    ZeroSrcOpcode = Mips::BLEZ;
2907
0
    ZeroTrgOpcode = Mips::BGEZ;
2908
0
    break;
2909
0
  case Mips::BGT:
2910
0
  case Mips::BGTU:
2911
0
  case Mips::BGTL:
2912
0
  case Mips::BGTUL:
2913
0
    AcceptsEquality = false;
2914
0
    ReverseOrderSLT = true;
2915
0
    IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2916
0
    IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2917
0
    ZeroSrcOpcode = Mips::BLTZ;
2918
0
    ZeroTrgOpcode = Mips::BGTZ;
2919
0
    break;
2920
0
  default:
2921
0
    llvm_unreachable("unknown opcode for branch pseudo-instruction");
2922
0
  }
2923
2924
0
  bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2925
0
  bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2926
0
  if (IsSrcRegZero && IsTrgRegZero) {
2927
    // FIXME: All of these Opcode-specific if's are needed for compatibility
2928
    // with GAS' behaviour. However, they may not generate the most efficient
2929
    // code in some circumstances.
2930
0
    if (PseudoOpcode == Mips::BLT) {
2931
0
      emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2932
0
             Instructions);
2933
0
      return false;
2934
0
    }
2935
0
    if (PseudoOpcode == Mips::BLE) {
2936
0
      emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2937
0
             Instructions);
2938
      // Warning(IDLoc, "branch is always taken");
2939
0
      return false;
2940
0
    }
2941
0
    if (PseudoOpcode == Mips::BGE) {
2942
0
      emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2943
0
             Instructions);
2944
      // Warning(IDLoc, "branch is always taken");
2945
0
      return false;
2946
0
    }
2947
0
    if (PseudoOpcode == Mips::BGT) {
2948
0
      emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2949
0
             Instructions);
2950
0
      return false;
2951
0
    }
2952
0
    if (PseudoOpcode == Mips::BGTU) {
2953
0
      emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2954
0
              MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2955
0
      return false;
2956
0
    }
2957
0
    if (AcceptsEquality) {
2958
      // If both registers are $0 and the pseudo-branch accepts equality, it
2959
      // will always be taken, so we emit an unconditional branch.
2960
0
      emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2961
0
              MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2962
      // Warning(IDLoc, "branch is always taken");
2963
0
      return false;
2964
0
    }
2965
    // If both registers are $0 and the pseudo-branch does not accept
2966
    // equality, it will never be taken, so we don't have to emit anything.
2967
0
    return false;
2968
0
  }
2969
0
  if (IsSrcRegZero || IsTrgRegZero) {
2970
0
    if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2971
0
        (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2972
      // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2973
      // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2974
      // the pseudo-branch will never be taken, so we don't emit anything.
2975
      // This only applies to unsigned pseudo-branches.
2976
0
      return false;
2977
0
    }
2978
0
    if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2979
0
        (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2980
      // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2981
      // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2982
      // the pseudo-branch will always be taken, so we emit an unconditional
2983
      // branch.
2984
      // This only applies to unsigned pseudo-branches.
2985
0
      emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2986
0
              MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2987
      // Warning(IDLoc, "branch is always taken");
2988
0
      return false;
2989
0
    }
2990
0
    if (IsUnsigned) {
2991
      // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2992
      // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2993
      // the pseudo-branch will be taken only when the non-zero register is
2994
      // different from 0, so we emit a BNEZ.
2995
      //
2996
      // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2997
      // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2998
      // the pseudo-branch will be taken only when the non-zero register is
2999
      // equal to 0, so we emit a BEQZ.
3000
      //
3001
      // Because only BLEU and BGEU branch on equality, we can use the
3002
      // AcceptsEquality variable to decide when to emit the BEQZ.
3003
0
      emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3004
0
              IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3005
0
              MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
3006
0
      return false;
3007
0
    }
3008
    // If we have a signed pseudo-branch and one of the registers is $0,
3009
    // we can use an appropriate compare-to-zero branch. We select which one
3010
    // to use in the switch statement above.
3011
0
    emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3012
0
           IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
3013
0
           IDLoc, Instructions);
3014
0
    return false;
3015
0
  }
3016
3017
  // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3018
  // expansions. If it is not available, we return.
3019
0
  unsigned ATRegNum = getATReg(IDLoc);
3020
0
  if (!ATRegNum)
3021
0
    return true;
3022
3023
0
  if (!EmittedNoMacroWarning)
3024
0
    warnIfNoMacro(IDLoc);
3025
3026
  // SLT fits well with 2 of our 4 pseudo-branches:
3027
  //   BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3028
  //   BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3029
  // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3030
  // This is accomplished by using a BNEZ with the result of the SLT.
3031
  //
3032
  // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3033
  // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3034
  // Because only BGE and BLE branch on equality, we can use the
3035
  // AcceptsEquality variable to decide when to emit the BEQZ.
3036
  // Note that the order of the SLT arguments doesn't change between
3037
  // opposites.
3038
  //
3039
  // The same applies to the unsigned variants, except that SLTu is used
3040
  // instead of SLT.
3041
0
  emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3042
0
          ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
3043
0
          IDLoc, Instructions);
3044
3045
0
  emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3046
0
                   : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3047
0
          ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3048
0
          Instructions);
3049
0
  return false;
3050
0
}
3051
3052
bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
3053
                              SmallVectorImpl<MCInst> &Instructions,
3054
0
                              const bool IsMips64, const bool Signed) {
3055
0
  if (hasMips32r6()) {
3056
0
    Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3057
0
    return false;
3058
0
  }
3059
3060
0
  warnIfNoMacro(IDLoc);
3061
3062
0
  const MCOperand &RsRegOp = Inst.getOperand(0);
3063
0
  assert(RsRegOp.isReg() && "expected register operand kind");
3064
0
  unsigned RsReg = RsRegOp.getReg();
3065
3066
0
  const MCOperand &RtRegOp = Inst.getOperand(1);
3067
0
  assert(RtRegOp.isReg() && "expected register operand kind");
3068
0
  unsigned RtReg = RtRegOp.getReg();
3069
0
  unsigned DivOp;
3070
0
  unsigned ZeroReg;
3071
3072
0
  if (IsMips64) {
3073
0
    DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3074
0
    ZeroReg = Mips::ZERO_64;
3075
0
  } else {
3076
0
    DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3077
0
    ZeroReg = Mips::ZERO;
3078
0
  }
3079
3080
0
  bool UseTraps = useTraps();
3081
3082
0
  if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3083
0
    if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3084
      // Warning(IDLoc, "dividing zero by zero");
3085
0
    }
3086
0
    if (IsMips64) {
3087
0
      if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3088
0
        if (UseTraps) {
3089
0
          emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
3090
0
          return false;
3091
0
        }
3092
3093
0
        emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3094
0
        return false;
3095
0
      }
3096
0
    } else {
3097
0
      emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
3098
0
      return false;
3099
0
    }
3100
0
  }
3101
3102
0
  if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3103
    // Warning(IDLoc, "division by zero");
3104
0
    if (Signed) {
3105
0
      if (UseTraps) {
3106
0
        emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
3107
0
        return false;
3108
0
      }
3109
3110
0
      emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3111
0
      return false;
3112
0
    }
3113
0
  }
3114
3115
  // FIXME: The values for these two BranchTarget variables may be different in
3116
  // micromips. These magic numbers need to be removed.
3117
0
  unsigned BranchTargetNoTraps;
3118
0
  unsigned BranchTarget;
3119
3120
0
  if (UseTraps) {
3121
0
    BranchTarget = IsMips64 ? 12 : 8;
3122
0
    emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
3123
0
  } else {
3124
0
    BranchTarget = IsMips64 ? 20 : 16;
3125
0
    BranchTargetNoTraps = 8;
3126
    // Branch to the li instruction.
3127
0
    emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
3128
0
            Instructions);
3129
0
  }
3130
3131
0
  emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
3132
3133
0
  if (!UseTraps)
3134
0
    emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3135
3136
0
  if (!Signed) {
3137
0
    emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3138
0
    return false;
3139
0
  }
3140
3141
0
  unsigned ATReg = getATReg(IDLoc);
3142
0
  if (!ATReg)
3143
0
    return true;
3144
3145
0
  emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
3146
0
  if (IsMips64) {
3147
    // Branch to the mflo instruction.
3148
0
    emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3149
0
    emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3150
0
    emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3151
0
  } else {
3152
    // Branch to the mflo instruction.
3153
0
    emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3154
0
    emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3155
0
  }
3156
3157
0
  if (UseTraps)
3158
0
    emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3159
0
  else {
3160
    // Branch to the mflo instruction.
3161
0
    emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3162
0
    emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3163
0
    emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3164
0
  }
3165
0
  emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3166
0
  return false;
3167
0
}
3168
3169
bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3170
0
                              SmallVectorImpl<MCInst> &Instructions) {
3171
0
  if (hasMips32r6() || hasMips64r6()) {
3172
0
    Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3173
0
    return false;
3174
0
  }
3175
3176
0
  warnIfNoMacro(IDLoc);
3177
3178
0
  const MCOperand &DstRegOp = Inst.getOperand(0);
3179
0
  assert(DstRegOp.isReg() && "expected register operand kind");
3180
3181
0
  const MCOperand &SrcRegOp = Inst.getOperand(1);
3182
0
  assert(SrcRegOp.isReg() && "expected register operand kind");
3183
3184
0
  const MCOperand &OffsetImmOp = Inst.getOperand(2);
3185
0
  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3186
3187
0
  unsigned DstReg = DstRegOp.getReg();
3188
0
  unsigned SrcReg = SrcRegOp.getReg();
3189
0
  int64_t OffsetValue = OffsetImmOp.getImm();
3190
3191
  // NOTE: We always need AT for ULHU, as it is always used as the source
3192
  // register for one of the LBu's.
3193
0
  unsigned ATReg = getATReg(IDLoc);
3194
0
  if (!ATReg)
3195
0
    return true;
3196
3197
  // When the value of offset+1 does not fit in 16 bits, we have to load the
3198
  // offset in AT, (D)ADDu the original source register (if there was one), and
3199
  // then use AT as the source register for the 2 generated LBu's.
3200
0
  bool LoadedOffsetInAT = false;
3201
0
  if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3202
0
    LoadedOffsetInAT = true;
3203
3204
0
    if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3205
0
                      true, IDLoc, Instructions))
3206
0
      return true;
3207
3208
    // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3209
    // because it will make our output more similar to GAS'. For example,
3210
    // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3211
    // instead of just an "ori $1, $9, 32768".
3212
    // NOTE: If there is no source register specified in the ULHU, the parser
3213
    // will interpret it as $0.
3214
0
    if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3215
0
      createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3216
0
  }
3217
3218
0
  unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3219
0
  unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3220
0
  unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3221
3222
0
  int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3223
0
  if (isLittle()) {
3224
0
    FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3225
0
    SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3226
0
  } else {
3227
0
    FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3228
0
    SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3229
0
  }
3230
3231
0
  unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3232
3233
0
  emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3234
0
          FirstLbuOffset, IDLoc, Instructions);
3235
3236
0
  emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3237
0
          Instructions);
3238
3239
0
  emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3240
3241
0
  emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3242
3243
0
  return false;
3244
0
}
3245
3246
bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3247
0
                              SmallVectorImpl<MCInst> &Instructions) {
3248
0
  if (hasMips32r6() || hasMips64r6()) {
3249
0
    Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3250
0
    return false;
3251
0
  }
3252
3253
0
  const MCOperand &DstRegOp = Inst.getOperand(0);
3254
0
  assert(DstRegOp.isReg() && "expected register operand kind");
3255
3256
0
  const MCOperand &SrcRegOp = Inst.getOperand(1);
3257
0
  assert(SrcRegOp.isReg() && "expected register operand kind");
3258
3259
0
  const MCOperand &OffsetImmOp = Inst.getOperand(2);
3260
0
  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3261
3262
0
  unsigned SrcReg = SrcRegOp.getReg();
3263
0
  int64_t OffsetValue = OffsetImmOp.getImm();
3264
0
  unsigned ATReg = 0;
3265
3266
  // When the value of offset+3 does not fit in 16 bits, we have to load the
3267
  // offset in AT, (D)ADDu the original source register (if there was one), and
3268
  // then use AT as the source register for the generated LWL and LWR.
3269
0
  bool LoadedOffsetInAT = false;
3270
0
  if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3271
0
    ATReg = getATReg(IDLoc);
3272
0
    if (!ATReg)
3273
0
      return true;
3274
0
    LoadedOffsetInAT = true;
3275
3276
0
    warnIfNoMacro(IDLoc);
3277
3278
0
    if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3279
0
                      true, IDLoc, Instructions))
3280
0
      return true;
3281
3282
    // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3283
    // because it will make our output more similar to GAS'. For example,
3284
    // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3285
    // instead of just an "ori $1, $9, 32768".
3286
    // NOTE: If there is no source register specified in the ULW, the parser
3287
    // will interpret it as $0.
3288
0
    if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3289
0
      createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3290
0
  }
3291
3292
0
  unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3293
0
  int64_t LeftLoadOffset = 0, RightLoadOffset  = 0;
3294
0
  if (isLittle()) {
3295
0
    LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3296
0
    RightLoadOffset  = LoadedOffsetInAT ? 0 : OffsetValue;
3297
0
  } else {
3298
0
    LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3299
0
    RightLoadOffset  = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3300
0
  }
3301
3302
0
  emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3303
0
          Instructions);
3304
3305
0
  emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3306
0
          Instructions);
3307
3308
0
  return false;
3309
0
}
3310
3311
bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3312
973
                                         SmallVectorImpl<MCInst> &Instructions) {
3313
3314
973
  assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3315
973
  assert (Inst.getOperand(0).isReg() &&
3316
973
          Inst.getOperand(1).isReg() &&
3317
973
          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3318
3319
973
  unsigned ATReg = Mips::NoRegister;
3320
973
  unsigned FinalDstReg = Mips::NoRegister;
3321
973
  unsigned DstReg = Inst.getOperand(0).getReg();
3322
973
  unsigned SrcReg = Inst.getOperand(1).getReg();
3323
973
  int64_t ImmValue = Inst.getOperand(2).getImm();
3324
3325
973
  bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3326
3327
973
  unsigned FinalOpcode = Inst.getOpcode();
3328
3329
973
  if (DstReg == SrcReg) {
3330
750
    ATReg = getATReg(Inst.getLoc());
3331
750
    if (!ATReg)
3332
1
      return true;
3333
749
    FinalDstReg = DstReg;
3334
749
    DstReg = ATReg;
3335
749
  }
3336
3337
972
  if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3338
971
    switch (FinalOpcode) {
3339
0
    default:
3340
0
      llvm_unreachable("unimplemented expansion");
3341
0
    case (Mips::ADDi):
3342
0
      FinalOpcode = Mips::ADD;
3343
0
      break;
3344
0
    case (Mips::ADDiu):
3345
0
      FinalOpcode = Mips::ADDu;
3346
0
      break;
3347
0
    case (Mips::ANDi):
3348
0
      FinalOpcode = Mips::AND;
3349
0
      break;
3350
0
    case (Mips::NORImm):
3351
0
      FinalOpcode = Mips::NOR;
3352
0
      break;
3353
967
    case (Mips::ORi):
3354
967
      FinalOpcode = Mips::OR;
3355
967
      break;
3356
0
    case (Mips::SLTi):
3357
0
      FinalOpcode = Mips::SLT;
3358
0
      break;
3359
0
    case (Mips::SLTiu):
3360
0
      FinalOpcode = Mips::SLTu;
3361
0
      break;
3362
4
    case (Mips::XORi):
3363
4
      FinalOpcode = Mips::XOR;
3364
4
      break;
3365
971
    }
3366
3367
971
    if (FinalDstReg == Mips::NoRegister)
3368
223
      emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3369
748
    else
3370
748
      emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3371
748
              Instructions);
3372
971
    return false;
3373
971
  }
3374
1
  return true;
3375
972
}
3376
3377
bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc,
3378
0
                                   SmallVectorImpl<MCInst> &Instructions) {
3379
0
  unsigned ATReg = Mips::NoRegister;
3380
0
  unsigned DReg = Inst.getOperand(0).getReg();
3381
0
  unsigned SReg = Inst.getOperand(1).getReg();
3382
0
  unsigned TReg = Inst.getOperand(2).getReg();
3383
0
  unsigned TmpReg = DReg;
3384
3385
0
  unsigned FirstShift = Mips::NOP;
3386
0
  unsigned SecondShift = Mips::NOP;
3387
3388
0
  if (hasMips32r2()) {
3389
3390
0
    if (DReg == SReg) {
3391
0
      TmpReg = getATReg(Inst.getLoc());
3392
0
      if (!TmpReg)
3393
0
        return true;
3394
0
    }
3395
3396
0
    if (Inst.getOpcode() == Mips::ROL) {
3397
0
      emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3398
0
      emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3399
0
      return false;
3400
0
    }
3401
3402
0
    if (Inst.getOpcode() == Mips::ROR) {
3403
0
      emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3404
0
      return false;
3405
0
    }
3406
3407
0
    return true;
3408
0
  }
3409
3410
0
  if (hasMips32()) {
3411
3412
0
    switch (Inst.getOpcode()) {
3413
0
    default:
3414
0
      llvm_unreachable("unexpected instruction opcode");
3415
0
    case Mips::ROL:
3416
0
      FirstShift = Mips::SRLV;
3417
0
      SecondShift = Mips::SLLV;
3418
0
      break;
3419
0
    case Mips::ROR:
3420
0
      FirstShift = Mips::SLLV;
3421
0
      SecondShift = Mips::SRLV;
3422
0
      break;
3423
0
    }
3424
3425
0
    ATReg = getATReg(Inst.getLoc());
3426
0
    if (!ATReg)
3427
0
      return true;
3428
3429
0
    emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3430
0
    emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3431
0
    emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3432
0
    emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3433
3434
0
    return false;
3435
0
  }
3436
3437
0
  return true;
3438
0
}
3439
3440
bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3441
18
                                      SmallVectorImpl<MCInst> &Instructions) {
3442
3443
18
  unsigned ATReg = Mips::NoRegister;
3444
18
  unsigned DReg = Inst.getOperand(0).getReg();
3445
18
  unsigned SReg = Inst.getOperand(1).getReg();
3446
18
  int64_t ImmValue = Inst.getOperand(2).getImm();
3447
3448
18
  unsigned FirstShift = Mips::NOP;
3449
18
  unsigned SecondShift = Mips::NOP;
3450
3451
18
  if (hasMips32r2()) {
3452
3453
1
    if (Inst.getOpcode() == Mips::ROLImm) {
3454
0
      uint64_t MaxShift = 32;
3455
0
      uint64_t ShiftValue = ImmValue;
3456
0
      if (ImmValue != 0)
3457
0
        ShiftValue = MaxShift - ImmValue;
3458
0
      emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3459
0
      return false;
3460
0
    }
3461
3462
1
    if (Inst.getOpcode() == Mips::RORImm) {
3463
1
      emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3464
1
      return false;
3465
1
    }
3466
3467
0
    return true;
3468
1
  }
3469
3470
17
  if (hasMips32()) {
3471
3472
17
    if (ImmValue == 0) {
3473
3
      emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3474
3
      return false;
3475
3
    }
3476
3477
14
    switch (Inst.getOpcode()) {
3478
0
    default:
3479
0
      llvm_unreachable("unexpected instruction opcode");
3480
0
    case Mips::ROLImm:
3481
0
      FirstShift = Mips::SLL;
3482
0
      SecondShift = Mips::SRL;
3483
0
      break;
3484
14
    case Mips::RORImm:
3485
14
      FirstShift = Mips::SRL;
3486
14
      SecondShift = Mips::SLL;
3487
14
      break;
3488
14
    }
3489
3490
14
    ATReg = getATReg(Inst.getLoc());
3491
14
    if (!ATReg)
3492
0
      return true;
3493
3494
14
    emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), Instructions);
3495
14
    emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), Instructions);
3496
14
    emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3497
3498
14
    return false;
3499
14
  }
3500
3501
0
  return true;
3502
17
}
3503
3504
bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc,
3505
0
                                    SmallVectorImpl<MCInst> &Instructions) {
3506
3507
0
  unsigned ATReg = Mips::NoRegister;
3508
0
  unsigned DReg = Inst.getOperand(0).getReg();
3509
0
  unsigned SReg = Inst.getOperand(1).getReg();
3510
0
  unsigned TReg = Inst.getOperand(2).getReg();
3511
0
  unsigned TmpReg = DReg;
3512
3513
0
  unsigned FirstShift = Mips::NOP;
3514
0
  unsigned SecondShift = Mips::NOP;
3515
3516
0
  if (hasMips64r2()) {
3517
3518
0
    if (TmpReg == SReg) {
3519
0
      TmpReg = getATReg(Inst.getLoc());
3520
0
      if (!TmpReg)
3521
0
        return true;
3522
0
    }
3523
3524
0
    if (Inst.getOpcode() == Mips::DROL) {
3525
0
      emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3526
0
      emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Instructions);
3527
0
      return false;
3528
0
    }
3529
3530
0
    if (Inst.getOpcode() == Mips::DROR) {
3531
0
      emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3532
0
      return false;
3533
0
    }
3534
3535
0
    return true;
3536
0
  }
3537
3538
0
  if (hasMips64()) {
3539
3540
0
    switch (Inst.getOpcode()) {
3541
0
    default:
3542
0
      llvm_unreachable("unexpected instruction opcode");
3543
0
    case Mips::DROL:
3544
0
      FirstShift = Mips::DSRLV;
3545
0
      SecondShift = Mips::DSLLV;
3546
0
      break;
3547
0
    case Mips::DROR:
3548
0
      FirstShift = Mips::DSLLV;
3549
0
      SecondShift = Mips::DSRLV;
3550
0
      break;
3551
0
    }
3552
3553
0
    ATReg = getATReg(Inst.getLoc());
3554
0
    if (!ATReg)
3555
0
      return true;
3556
3557
0
    emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Instructions);
3558
0
    emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Instructions);
3559
0
    emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Instructions);
3560
0
    emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3561
3562
0
    return false;
3563
0
  }
3564
3565
0
  return true;
3566
0
}
3567
3568
bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3569
2
                                       SmallVectorImpl<MCInst> &Instructions) {
3570
3571
2
  unsigned ATReg = Mips::NoRegister;
3572
2
  unsigned DReg = Inst.getOperand(0).getReg();
3573
2
  unsigned SReg = Inst.getOperand(1).getReg();
3574
2
  int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3575
3576
2
  unsigned FirstShift = Mips::NOP;
3577
2
  unsigned SecondShift = Mips::NOP;
3578
3579
2
  MCInst TmpInst;
3580
3581
2
  if (hasMips64r2()) {
3582
3583
0
    unsigned FinalOpcode = Mips::NOP;
3584
0
    if (ImmValue == 0)
3585
0
      FinalOpcode = Mips::DROTR;
3586
0
    else if (ImmValue % 32 == 0)
3587
0
      FinalOpcode = Mips::DROTR32;
3588
0
    else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3589
0
      if (Inst.getOpcode() == Mips::DROLImm)
3590
0
        FinalOpcode = Mips::DROTR32;
3591
0
      else
3592
0
        FinalOpcode = Mips::DROTR;
3593
0
    } else if (ImmValue >= 33) {
3594
0
      if (Inst.getOpcode() == Mips::DROLImm)
3595
0
        FinalOpcode = Mips::DROTR;
3596
0
      else
3597
0
        FinalOpcode = Mips::DROTR32;
3598
0
    }
3599
3600
0
    uint64_t ShiftValue = ImmValue % 32;
3601
0
    if (Inst.getOpcode() == Mips::DROLImm)
3602
0
      ShiftValue = (32 - ImmValue % 32) % 32;
3603
3604
0
    emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), Instructions);
3605
3606
0
    return false;
3607
0
  }
3608
3609
2
  if (hasMips64()) {
3610
3611
2
    if (ImmValue == 0) {
3612
0
      emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), Instructions);
3613
0
      return false;
3614
0
    }
3615
3616
2
    switch (Inst.getOpcode()) {
3617
0
    default:
3618
0
      llvm_unreachable("unexpected instruction opcode");
3619
2
    case Mips::DROLImm:
3620
2
      if ((ImmValue >= 1) && (ImmValue <= 31)) {
3621
2
        FirstShift = Mips::DSLL;
3622
2
        SecondShift = Mips::DSRL32;
3623
2
      }
3624
2
      if (ImmValue == 32) {
3625
0
        FirstShift = Mips::DSLL32;
3626
0
        SecondShift = Mips::DSRL32;
3627
0
      }
3628
2
      if ((ImmValue >= 33) && (ImmValue <= 63)) {
3629
0
        FirstShift = Mips::DSLL32;
3630
0
        SecondShift = Mips::DSRL;
3631
0
      }
3632
2
      break;
3633
0
    case Mips::DRORImm:
3634
0
      if ((ImmValue >= 1) && (ImmValue <= 31)) {
3635
0
        FirstShift = Mips::DSRL;
3636
0
        SecondShift = Mips::DSLL32;
3637
0
      }
3638
0
      if (ImmValue == 32) {
3639
0
        FirstShift = Mips::DSRL32;
3640
0
        SecondShift = Mips::DSLL32;
3641
0
      }
3642
0
      if ((ImmValue >= 33) && (ImmValue <= 63)) {
3643
0
        FirstShift = Mips::DSRL32;
3644
0
        SecondShift = Mips::DSLL;
3645
0
      }
3646
0
      break;
3647
2
    }
3648
3649
2
    ATReg = getATReg(Inst.getLoc());
3650
2
    if (!ATReg)
3651
0
      return true;
3652
3653
2
    emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), Instructions);
3654
2
    emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, Inst.getLoc(), Instructions);
3655
2
    emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Instructions);
3656
3657
2
    return false;
3658
2
  }
3659
3660
0
  return true;
3661
2
}
3662
3663
bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc,
3664
32
                              SmallVectorImpl<MCInst> &Instructions) {
3665
3666
32
  unsigned FirstRegOp = Inst.getOperand(0).getReg();
3667
32
  unsigned SecondRegOp = Inst.getOperand(1).getReg();
3668
3669
32
  emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, Instructions);
3670
32
  if (FirstRegOp != SecondRegOp)
3671
32
    emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, Instructions);
3672
0
  else
3673
0
    createNop(false, IDLoc, Instructions);
3674
32
  emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, Instructions);
3675
3676
32
  return false;
3677
32
}
3678
3679
void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3680
11.8k
                              SmallVectorImpl<MCInst> &Instructions) {
3681
11.8k
  if (hasShortDelaySlot)
3682
0
    emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3683
11.8k
  else
3684
11.8k
    emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3685
11.8k
}
3686
3687
void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3688
                               unsigned TrgReg, bool Is64Bit,
3689
0
                               SmallVectorImpl<MCInst> &Instructions) {
3690
0
  emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3691
0
          Instructions);
3692
0
}
3693
3694
void MipsAsmParser::createCpRestoreMemOp(
3695
    bool IsLoad, int StackOffset, SMLoc IDLoc,
3696
20
    SmallVectorImpl<MCInst> &Instructions) {
3697
  // If the offset can not fit into 16 bits, we need to expand.
3698
20
  if (!isInt<16>(StackOffset)) {
3699
2
    MCInst MemInst;
3700
2
    MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3701
2
    MemInst.addOperand(MCOperand::createReg(Mips::GP));
3702
2
    MemInst.addOperand(MCOperand::createReg(Mips::SP));
3703
2
    MemInst.addOperand(MCOperand::createImm(StackOffset));
3704
2
    expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3705
2
    return;
3706
2
  }
3707
3708
18
  emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3709
18
          Instructions);
3710
18
}
3711
3712
14.8k
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3713
  // As described by the Mips32r2 spec, the registers Rd and Rs for
3714
  // jalr.hb must be different.
3715
14.8k
  unsigned Opcode = Inst.getOpcode();
3716
3717
14.8k
  if (Opcode == Mips::JALR_HB &&
3718
0
      (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3719
0
    return Match_RequiresDifferentSrcAndDst;
3720
3721
14.8k
  return Match_Success;
3722
14.8k
}
3723
3724
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3725
5
                            uint64_t ErrorInfo) {
3726
5
  if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3727
5
    SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3728
5
    if (ErrorLoc == SMLoc())
3729
0
      return Loc;
3730
5
    return ErrorLoc;
3731
5
  }
3732
0
  return Loc;
3733
5
}
3734
3735
bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3736
                                            OperandVector &Operands,
3737
                                            MCStreamer &Out,
3738
                                            uint64_t &ErrorInfo,
3739
                                            bool MatchingInlineAsm, unsigned int &ErrorCode, uint64_t &Address)
3740
14.9k
{
3741
14.9k
  MCInst Inst(Address);
3742
14.9k
  SmallVector<MCInst, 8> Instructions;
3743
14.9k
  unsigned MatchResult =
3744
14.9k
      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3745
3746
14.9k
  switch (MatchResult) {
3747
14.8k
  case Match_Success: {
3748
14.8k
    if (processInstruction(Inst, IDLoc, Instructions, ErrorCode))
3749
32
      return true;
3750
45.8k
    for (unsigned i = 0; i < Instructions.size(); i++)
3751
31.0k
      Out.EmitInstruction(Instructions[i], getSTI(), ErrorCode);
3752
14.8k
    if (ErrorCode == 0) {
3753
14.8k
        Address = Inst.getAddress(); // Keystone update address
3754
14.8k
        return false;
3755
14.8k
    } else
3756
0
        return true;
3757
3758
14.8k
  }
3759
0
  case Match_MissingFeature:
3760
0
    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3761
0
    return true;
3762
143
  case Match_InvalidOperand: {
3763
143
    SMLoc ErrorLoc = IDLoc;
3764
143
    if (ErrorInfo != ~0ULL) {
3765
143
      if (ErrorInfo >= Operands.size())
3766
37
        return Error(IDLoc, "too few operands for instruction");
3767
3768
106
      ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3769
106
      if (ErrorLoc == SMLoc())
3770
0
        ErrorLoc = IDLoc;
3771
106
    }
3772
3773
106
    return Error(ErrorLoc, "invalid operand for instruction");
3774
143
  }
3775
0
  case Match_MnemonicFail:
3776
0
    return Error(IDLoc, "invalid instruction");
3777
0
  case Match_RequiresDifferentSrcAndDst:
3778
0
    return Error(IDLoc, "source and destination must be different");
3779
0
  case Match_Immz:
3780
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3781
0
  case Match_UImm1_0:
3782
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3783
0
                 "expected 1-bit unsigned immediate");
3784
0
  case Match_UImm2_0:
3785
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3786
0
                 "expected 2-bit unsigned immediate");
3787
0
  case Match_UImm2_1:
3788
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3789
0
                 "expected immediate in range 1 .. 4");
3790
0
  case Match_UImm3_0:
3791
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3792
0
                 "expected 3-bit unsigned immediate");
3793
0
  case Match_UImm4_0:
3794
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3795
0
                 "expected 4-bit unsigned immediate");
3796
0
  case Match_UImm5_0:
3797
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3798
0
                 "expected 5-bit unsigned immediate");
3799
0
  case Match_UImm5_1:
3800
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3801
0
                 "expected immediate in range 1 .. 32");
3802
0
  case Match_UImm5_32:
3803
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3804
0
                 "expected immediate in range 32 .. 63");
3805
0
  case Match_UImm5_33:
3806
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3807
0
                 "expected immediate in range 33 .. 64");
3808
0
  case Match_UImm5_0_Report_UImm6:
3809
    // This is used on UImm5 operands that have a corresponding UImm5_32
3810
    // operand to avoid confusing the user.
3811
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3812
0
                 "expected 6-bit unsigned immediate");
3813
0
  case Match_UImm5_Lsl2:
3814
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3815
0
                 "expected both 7-bit unsigned immediate and multiple of 4");
3816
2
  case Match_UImm6_0:
3817
2
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3818
2
                 "expected 6-bit unsigned immediate");
3819
0
  case Match_SImm6:
3820
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3821
0
                 "expected 6-bit signed immediate");
3822
0
  case Match_UImm7_0:
3823
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3824
0
                 "expected 7-bit unsigned immediate");
3825
0
  case Match_UImm8_0:
3826
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3827
0
                 "expected 8-bit unsigned immediate");
3828
3
  case Match_UImm10_0:
3829
3
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3830
3
                 "expected 10-bit unsigned immediate");
3831
0
  case Match_UImm16:
3832
0
  case Match_UImm16_Relaxed:
3833
0
    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3834
0
                 "expected 16-bit unsigned immediate");
3835
14.9k
  }
3836
3837
14.9k
  llvm_unreachable("Implement any new match types added!");
3838
14.9k
}
3839
3840
5.86k
void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3841
5.86k
  if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex) {
3842
    // Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3843
    //                  ") without \".set noat\"");
3844
788
  }
3845
5.86k
}
3846
3847
827
void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3848
827
  if (!AssemblerOptions.back()->isMacro()) {
3849
    // Warning(Loc, "macro instruction expanded into multiple instructions");
3850
0
  }
3851
827
}
3852
3853
void
3854
MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3855
1.02k
                                     SMRange Range, bool ShowColors) {
3856
1.02k
  getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3857
1.02k
                                  Range, SMFixIt(Range, FixMsg),
3858
1.02k
                                  ShowColors);
3859
1.02k
}
3860
3861
15.1k
int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3862
15.1k
  int CC;
3863
3864
15.1k
  CC = StringSwitch<unsigned>(Name)
3865
15.1k
           .Case("zero", 0)
3866
15.1k
           .Case("at", 1)
3867
15.1k
           .Case("a0", 4)
3868
15.1k
           .Case("a1", 5)
3869
15.1k
           .Case("a2", 6)
3870
15.1k
           .Case("a3", 7)
3871
15.1k
           .Case("v0", 2)
3872
15.1k
           .Case("v1", 3)
3873
15.1k
           .Case("s0", 16)
3874
15.1k
           .Case("s1", 17)
3875
15.1k
           .Case("s2", 18)
3876
15.1k
           .Case("s3", 19)
3877
15.1k
           .Case("s4", 20)
3878
15.1k
           .Case("s5", 21)
3879
15.1k
           .Case("s6", 22)
3880
15.1k
           .Case("s7", 23)
3881
15.1k
           .Case("k0", 26)
3882
15.1k
           .Case("k1", 27)
3883
15.1k
           .Case("gp", 28)
3884
15.1k
           .Case("sp", 29)
3885
15.1k
           .Case("fp", 30)
3886
15.1k
           .Case("s8", 30)
3887
15.1k
           .Case("ra", 31)
3888
15.1k
           .Case("t0", 8)
3889
15.1k
           .Case("t1", 9)
3890
15.1k
           .Case("t2", 10)
3891
15.1k
           .Case("t3", 11)
3892
15.1k
           .Case("t4", 12)
3893
15.1k
           .Case("t5", 13)
3894
15.1k
           .Case("t6", 14)
3895
15.1k
           .Case("t7", 15)
3896
15.1k
           .Case("t8", 24)
3897
15.1k
           .Case("t9", 25)
3898
15.1k
           .Default(-1);
3899
3900
15.1k
  if (!(isABI_N32() || isABI_N64()))
3901
5.25k
    return CC;
3902
3903
9.93k
  if (12 <= CC && CC <= 15) {
3904
    // Name is one of t4-t7
3905
1.02k
    AsmToken RegTok = getLexer().peekTok();
3906
1.02k
    SMRange RegRange = RegTok.getLocRange();
3907
3908
1.02k
    StringRef FixedName = StringSwitch<StringRef>(Name)
3909
1.02k
                              .Case("t4", "t0")
3910
1.02k
                              .Case("t5", "t1")
3911
1.02k
                              .Case("t6", "t2")
3912
1.02k
                              .Case("t7", "t3")
3913
1.02k
                              .Default("");
3914
1.02k
    assert(FixedName != "" &&  "Register name is not one of t4-t7.");
3915
3916
1.02k
    printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3917
1.02k
                          "Did you mean $" + FixedName + "?", RegRange);
3918
1.02k
  }
3919
3920
  // Although SGI documentation just cuts out t0-t3 for n32/n64,
3921
  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3922
  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3923
9.93k
  if (8 <= CC && CC <= 11)
3924
259
    CC += 4;
3925
3926
9.93k
  if (CC == -1)
3927
6.53k
    CC = StringSwitch<unsigned>(Name)
3928
6.53k
             .Case("a4", 8)
3929
6.53k
             .Case("a5", 9)
3930
6.53k
             .Case("a6", 10)
3931
6.53k
             .Case("a7", 11)
3932
6.53k
             .Case("kt0", 26)
3933
6.53k
             .Case("kt1", 27)
3934
6.53k
             .Default(-1);
3935
3936
9.93k
  return CC;
3937
9.93k
}
3938
3939
8.91k
int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3940
8.91k
  int CC;
3941
3942
8.91k
  CC = StringSwitch<unsigned>(Name)
3943
8.91k
            .Case("hwr_cpunum", 0)
3944
8.91k
            .Case("hwr_synci_step", 1)
3945
8.91k
            .Case("hwr_cc", 2)
3946
8.91k
            .Case("hwr_ccres", 3)
3947
8.91k
            .Case("hwr_ulr", 29)
3948
8.91k
            .Default(-1);
3949
3950
8.91k
  return CC;
3951
8.91k
}
3952
3953
8.88k
int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3954
3955
8.88k
  if (Name[0] == 'f') {
3956
1.89k
    StringRef NumString = Name.substr(1);
3957
1.89k
    unsigned IntVal;
3958
1.89k
    if (NumString.getAsInteger(10, IntVal))
3959
1.47k
      return -1;     // This is not an integer.
3960
420
    if (IntVal > 31) // Maximum index for fpu register.
3961
289
      return -1;
3962
131
    return IntVal;
3963
420
  }
3964
6.99k
  return -1;
3965
8.88k
}
3966
3967
8.75k
int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3968
3969
8.75k
  if (Name.startswith("fcc")) {
3970
269
    StringRef NumString = Name.substr(3);
3971
269
    unsigned IntVal;
3972
269
    if (NumString.getAsInteger(10, IntVal))
3973
197
      return -1;    // This is not an integer.
3974
72
    if (IntVal > 7) // There are only 8 fcc registers.
3975
1
      return -1;
3976
71
    return IntVal;
3977
72
  }
3978
8.48k
  return -1;
3979
8.75k
}
3980
3981
8.68k
int MipsAsmParser::matchACRegisterName(StringRef Name) {
3982
3983
8.68k
  if (Name.startswith("ac")) {
3984
289
    StringRef NumString = Name.substr(2);
3985
289
    unsigned IntVal;
3986
289
    if (NumString.getAsInteger(10, IntVal))
3987
130
      return -1;    // This is not an integer.
3988
159
    if (IntVal > 3) // There are only 3 acc registers.
3989
107
      return -1;
3990
52
    return IntVal;
3991
159
  }
3992
8.39k
  return -1;
3993
8.68k
}
3994
3995
8.63k
int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3996
8.63k
  unsigned IntVal;
3997
3998
8.63k
  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3999
8.63k
    return -1;
4000
4001
3
  if (IntVal > 31)
4002
2
    return -1;
4003
4004
1
  return IntVal;
4005
3
}
4006
4007
8.63k
int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4008
8.63k
  int CC;
4009
4010
8.63k
  CC = StringSwitch<unsigned>(Name)
4011
8.63k
           .Case("msair", 0)
4012
8.63k
           .Case("msacsr", 1)
4013
8.63k
           .Case("msaaccess", 2)
4014
8.63k
           .Case("msasave", 3)
4015
8.63k
           .Case("msamodify", 4)
4016
8.63k
           .Case("msarequest", 5)
4017
8.63k
           .Case("msamap", 6)
4018
8.63k
           .Case("msaunmap", 7)
4019
8.63k
           .Default(-1);
4020
4021
8.63k
  return CC;
4022
8.63k
}
4023
4024
977
unsigned MipsAsmParser::getATReg(SMLoc Loc) {
4025
977
  unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4026
977
  if (ATIndex == 0) {
4027
5
    reportParseError(Loc,
4028
5
                     "pseudo-instruction requires $at, which is not available");
4029
5
    return 0;
4030
5
  }
4031
972
  unsigned AT = getReg(
4032
972
      (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4033
972
  return AT;
4034
977
}
4035
4036
972
unsigned MipsAsmParser::getReg(int RC, int RegNo) {
4037
972
  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4038
972
}
4039
4040
bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic, unsigned int &ErrorCode)
4041
47.9k
{
4042
47.9k
  MCAsmParser &Parser = getParser();
4043
47.9k
  DEBUG(dbgs() << "parseOperand\n");
4044
4045
  // Check if the current operand has a custom associated parser, if so, try to
4046
  // custom parse the operand, or fallback to the general approach.
4047
47.9k
  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4048
47.9k
  if (ResTy == MatchOperand_Success)
4049
17.4k
    return false;
4050
  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4051
  // there was a match, but an error occurred, in which case, just return that
4052
  // the operand parsing failed.
4053
30.5k
  if (ResTy == MatchOperand_ParseFail)
4054
13.1k
    return true;
4055
4056
17.4k
  DEBUG(dbgs() << ".. Generic Parser\n");
4057
4058
17.4k
  switch (getLexer().getKind()) {
4059
86
  default:
4060
    // Error(Parser.getTok().getLoc(), "unexpected token in operand");
4061
86
    ErrorCode = KS_ERR_ASM_MIPS_INVALIDOPERAND;
4062
86
    return true;
4063
13.3k
  case AsmToken::Dollar: {
4064
    // Parse the register.
4065
13.3k
    SMLoc S = Parser.getTok().getLoc();
4066
4067
    // Almost all registers have been parsed by custom parsers. There is only
4068
    // one exception to this. $zero (and it's alias $0) will reach this point
4069
    // for div, divu, and similar instructions because it is not an operand
4070
    // to the instruction definition but an explicit register. Special case
4071
    // this situation for now.
4072
13.3k
    if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
4073
4.77k
      return false;
4074
4075
    // Maybe it is a symbol reference.
4076
8.59k
    StringRef Identifier;
4077
8.59k
    if (Parser.parseIdentifier(Identifier))
4078
4.19k
      return true;
4079
4080
4.40k
    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4081
4.40k
    MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
4082
    // Otherwise create a symbol reference.
4083
4.40k
    const MCExpr *Res =
4084
4.40k
        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
4085
4086
4.40k
    Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
4087
4.40k
    return false;
4088
8.59k
  }
4089
  // Else drop to expression parsing.
4090
75
  case AsmToken::LParen:
4091
1.80k
  case AsmToken::Minus:
4092
2.16k
  case AsmToken::Plus:
4093
3.82k
  case AsmToken::Integer:
4094
3.88k
  case AsmToken::Tilde:
4095
3.94k
  case AsmToken::String: {
4096
3.94k
    DEBUG(dbgs() << ".. generic integer\n");
4097
3.94k
    OperandMatchResultTy ResTy = parseImm(Operands);
4098
3.94k
    return ResTy != MatchOperand_Success;
4099
3.88k
  }
4100
12
  case AsmToken::Percent: {
4101
    // It is a symbol reference or constant expression.
4102
12
    const MCExpr *IdVal;
4103
12
    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
4104
12
    if (parseRelocOperand(IdVal))
4105
12
      return true;
4106
4107
0
    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4108
4109
0
    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4110
0
    return false;
4111
12
  } // case AsmToken::Percent
4112
17.4k
  } // switch(getLexer().getKind())
4113
0
  return true;
4114
17.4k
}
4115
4116
const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
4117
12.7k
                                               StringRef RelocStr) {
4118
12.7k
  const MCExpr *Res;
4119
  // Check the type of the expression.
4120
12.7k
  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
4121
    // It's a constant, evaluate reloc value.
4122
2.29k
    int16_t Val;
4123
2.29k
    switch (getVariantKind(RelocStr)) {
4124
1.14k
    case MCSymbolRefExpr::VK_Mips_ABS_LO:
4125
      // Get the 1st 16-bits.
4126
1.14k
      Val = MCE->getValue() & 0xffff;
4127
1.14k
      break;
4128
1.14k
    case MCSymbolRefExpr::VK_Mips_ABS_HI:
4129
      // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
4130
      // 16 bits being negative.
4131
1.14k
      Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
4132
1.14k
      break;
4133
0
    case MCSymbolRefExpr::VK_Mips_HIGHER:
4134
      // Get the 3rd 16-bits.
4135
0
      Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
4136
0
      break;
4137
0
    case MCSymbolRefExpr::VK_Mips_HIGHEST:
4138
      // Get the 4th 16-bits.
4139
0
      Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
4140
0
      break;
4141
0
    default:
4142
0
      report_fatal_error("unsupported reloc value");
4143
2.29k
    }
4144
2.29k
    return MCConstantExpr::create(Val, getContext());
4145
2.29k
  }
4146
4147
10.4k
  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
4148
    // It's a symbol, create a symbolic expression from the symbol.
4149
3.43k
    const MCSymbol *Symbol = &MSRE->getSymbol();
4150
3.43k
    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
4151
3.43k
    Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
4152
3.43k
    return Res;
4153
3.43k
  }
4154
4155
7.03k
  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4156
5.65k
    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
4157
4158
    // Try to create target expression.
4159
5.65k
    if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
4160
274
      return MipsMCExpr::create(VK, Expr, getContext());
4161
4162
5.38k
    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
4163
5.38k
    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
4164
5.38k
    Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
4165
5.38k
    return Res;
4166
5.65k
  }
4167
4168
1.38k
  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
4169
1.38k
    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
4170
1.38k
    Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
4171
1.38k
    return Res;
4172
1.38k
  }
4173
  // Just return the original expression.
4174
0
  return Expr;
4175
1.38k
}
4176
4177
3.35k
bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4178
4179
3.35k
  switch (Expr->getKind()) {
4180
194
  case MCExpr::Constant:
4181
194
    return true;
4182
203
  case MCExpr::SymbolRef:
4183
203
    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4184
2.64k
  case MCExpr::Binary:
4185
2.64k
    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4186
2.64k
      if (!isEvaluated(BE->getLHS()))
4187
2.45k
        return false;
4188
196
      return isEvaluated(BE->getRHS());
4189
2.64k
    }
4190
305
  case MCExpr::Unary:
4191
305
    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4192
0
  case MCExpr::Target:
4193
0
    return true;
4194
3.35k
  }
4195
0
  return false;
4196
3.35k
}
4197
4198
13
bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
4199
13
  MCAsmParser &Parser = getParser();
4200
13
  Parser.Lex();                          // Eat the % token.
4201
13
  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
4202
13
  if (Tok.isNot(AsmToken::Identifier))
4203
0
    return true;
4204
4205
13
  std::string Str = Tok.getIdentifier();
4206
4207
13
  Parser.Lex(); // Eat the identifier.
4208
  // Now make an expression from the rest of the operand.
4209
13
  const MCExpr *IdVal;
4210
13
  SMLoc EndLoc;
4211
4212
13
  if (getLexer().getKind() == AsmToken::LParen) {
4213
10
    while (1) {
4214
10
      Parser.Lex(); // Eat the '(' token.
4215
10
      if (getLexer().getKind() == AsmToken::Percent) {
4216
3
        Parser.Lex(); // Eat the % token.
4217
3
        const AsmToken &nextTok = Parser.getTok();
4218
3
        if (nextTok.isNot(AsmToken::Identifier))
4219
0
          return true;
4220
3
        Str += "(%";
4221
3
        Str += nextTok.getIdentifier();
4222
3
        Parser.Lex(); // Eat the identifier.
4223
3
        if (getLexer().getKind() != AsmToken::LParen)
4224
1
          return true;
4225
3
      } else
4226
7
        break;
4227
10
    }
4228
7
    if (getParser().parseParenExpression(IdVal, EndLoc))
4229
7
      return true;
4230
4231
0
    while (getLexer().getKind() == AsmToken::RParen)
4232
0
      Parser.Lex(); // Eat the ')' token.
4233
4234
0
  } else
4235
5
    return true; // Parenthesis must follow the relocation operand.
4236
4237
0
  Res = evaluateRelocExpr(IdVal, Str);
4238
0
  return false;
4239
13
}
4240
4241
bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4242
0
                                  SMLoc &EndLoc, unsigned int &ErrorCode) {
4243
0
  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4244
0
  OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4245
0
  if (ResTy == MatchOperand_Success) {
4246
0
    assert(Operands.size() == 1);
4247
0
    MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4248
0
    StartLoc = Operand.getStartLoc();
4249
0
    EndLoc = Operand.getEndLoc();
4250
4251
    // AFAIK, we only support numeric registers and named GPR's in CFI
4252
    // directives.
4253
    // Don't worry about eating tokens before failing. Using an unrecognised
4254
    // register is a parse error.
4255
0
    if (Operand.isGPRAsmReg()) {
4256
      // Resolve to GPR32 or GPR64 appropriately.
4257
0
      RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4258
0
    }
4259
4260
0
    return (RegNo == (unsigned)-1);
4261
0
  }
4262
4263
0
  assert(Operands.size() == 0);
4264
0
  return (RegNo == (unsigned)-1);
4265
0
}
4266
4267
1.05k
bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4268
1.05k
  MCAsmParser &Parser = getParser();
4269
1.05k
  SMLoc S;
4270
1.05k
  bool Result = true;
4271
1.05k
  unsigned NumOfLParen = 0;
4272
4273
1.10k
  while (getLexer().getKind() == AsmToken::LParen) {
4274
46
    Parser.Lex();
4275
46
    ++NumOfLParen;
4276
46
  }
4277
4278
1.05k
  switch (getLexer().getKind()) {
4279
7
  default:
4280
7
    return true;
4281
195
  case AsmToken::Identifier:
4282
195
  case AsmToken::LParen:
4283
812
  case AsmToken::Integer:
4284
973
  case AsmToken::Minus:
4285
1.05k
  case AsmToken::Plus:
4286
1.05k
    if (isParenExpr)
4287
42
      Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
4288
1.00k
    else
4289
1.00k
      Result = (getParser().parseExpression(Res));
4290
1.36k
    while (getLexer().getKind() == AsmToken::RParen)
4291
310
      Parser.Lex();
4292
1.05k
    break;
4293
1
  case AsmToken::Percent:
4294
1
    Result = parseRelocOperand(Res);
4295
1.05k
  }
4296
1.05k
  return Result;
4297
1.05k
}
4298
4299
MipsAsmParser::OperandMatchResultTy
4300
1.11k
MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4301
1.11k
  MCAsmParser &Parser = getParser();
4302
1.11k
  DEBUG(dbgs() << "parseMemOperand\n");
4303
1.11k
  const MCExpr *IdVal = nullptr;
4304
1.11k
  SMLoc S;
4305
1.11k
  bool isParenExpr = false;
4306
1.11k
  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
4307
  // First operand is the offset.
4308
1.11k
  S = Parser.getTok().getLoc();
4309
4310
1.11k
  if (getLexer().getKind() == AsmToken::LParen) {
4311
45
    Parser.Lex();
4312
45
    isParenExpr = true;
4313
45
  }
4314
4315
1.11k
  if (getLexer().getKind() != AsmToken::Dollar) {
4316
1.05k
    if (parseMemOffset(IdVal, isParenExpr))
4317
130
      return MatchOperand_ParseFail;
4318
4319
928
    const AsmToken &Tok = Parser.getTok(); // Get the next token.
4320
928
    if (Tok.isNot(AsmToken::LParen)) {
4321
927
      MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4322
927
      if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4323
34
        SMLoc E =
4324
34
            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4325
34
        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4326
34
        return MatchOperand_Success;
4327
34
      }
4328
893
      if (Tok.is(AsmToken::EndOfStatement)) {
4329
878
        SMLoc E =
4330
878
            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4331
4332
        // Zero register assumed, add a memory operand with ZERO as its base.
4333
        // "Base" will be managed by k_Memory.
4334
878
        auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
4335
878
                                              S, E, *this);
4336
878
        Operands.push_back(
4337
878
            MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4338
878
        return MatchOperand_Success;
4339
878
      }
4340
15
      Error(Parser.getTok().getLoc(), "'(' expected");
4341
15
      return MatchOperand_ParseFail;
4342
893
    }
4343
4344
1
    Parser.Lex(); // Eat the '(' token.
4345
1
  }
4346
4347
55
  Res = parseAnyRegister(Operands);
4348
55
  if (Res != MatchOperand_Success)
4349
55
    return Res;
4350
4351
0
  if (Parser.getTok().isNot(AsmToken::RParen)) {
4352
0
    Error(Parser.getTok().getLoc(), "')' expected");
4353
0
    return MatchOperand_ParseFail;
4354
0
  }
4355
4356
0
  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4357
4358
0
  Parser.Lex(); // Eat the ')' token.
4359
4360
0
  if (!IdVal)
4361
0
    IdVal = MCConstantExpr::create(0, getContext());
4362
4363
  // Replace the register operand with the memory operand.
4364
0
  std::unique_ptr<MipsOperand> op(
4365
0
      static_cast<MipsOperand *>(Operands.back().release()));
4366
  // Remove the register from the operands.
4367
  // "op" will be managed by k_Memory.
4368
0
  Operands.pop_back();
4369
  // Add the memory operand.
4370
0
  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4371
0
    int64_t Imm;
4372
0
    if (IdVal->evaluateAsAbsolute(Imm))
4373
0
      IdVal = MCConstantExpr::create(Imm, getContext());
4374
0
    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4375
0
      IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4376
0
                                   getContext());
4377
0
  }
4378
4379
0
  Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4380
0
  return MatchOperand_Success;
4381
0
}
4382
4383
9.44k
bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4384
9.44k
  MCAsmParser &Parser = getParser();
4385
9.44k
  MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4386
9.44k
  if (Sym) {
4387
5.72k
    SMLoc S = Parser.getTok().getLoc();
4388
5.72k
    const MCExpr *Expr;
4389
5.72k
    if (Sym->isVariable())
4390
566
      Expr = Sym->getVariableValue();
4391
5.16k
    else
4392
5.16k
      return false;
4393
566
    if (Expr->getKind() == MCExpr::SymbolRef) {
4394
486
      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4395
486
      StringRef DefSymbol = Ref->getSymbol().getName();
4396
486
      if (DefSymbol.startswith("$")) {
4397
387
        OperandMatchResultTy ResTy =
4398
387
            matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4399
387
        if (ResTy == MatchOperand_Success) {
4400
1
          Parser.Lex();
4401
1
          return true;
4402
386
        } else if (ResTy == MatchOperand_ParseFail)
4403
0
          llvm_unreachable("Should never ParseFail");
4404
386
        return false;
4405
387
      }
4406
486
    } else if (Expr->getKind() == MCExpr::Constant) {
4407
49
      Parser.Lex();
4408
49
      const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
4409
49
      Operands.push_back(
4410
49
          MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
4411
49
      return true;
4412
49
    }
4413
566
  }
4414
3.85k
  return false;
4415
9.44k
}
4416
4417
MipsAsmParser::OperandMatchResultTy
4418
MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4419
                                                 StringRef Identifier,
4420
15.1k
                                                 SMLoc S) {
4421
15.1k
  int Index = matchCPURegisterName(Identifier);
4422
15.1k
  if (Index != -1) {
4423
6.23k
    Operands.push_back(MipsOperand::createGPRReg(
4424
6.23k
        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4425
6.23k
    return MatchOperand_Success;
4426
6.23k
  }
4427
4428
8.91k
  Index = matchHWRegsRegisterName(Identifier);
4429
8.91k
  if (Index != -1) {
4430
21
    Operands.push_back(MipsOperand::createHWRegsReg(
4431
21
        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4432
21
    return MatchOperand_Success;
4433
21
  }
4434
4435
8.88k
  Index = matchFPURegisterName(Identifier);
4436
8.88k
  if (Index != -1) {
4437
131
    Operands.push_back(MipsOperand::createFGRReg(
4438
131
        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4439
131
    return MatchOperand_Success;
4440
131
  }
4441
4442
8.75k
  Index = matchFCCRegisterName(Identifier);
4443
8.75k
  if (Index != -1) {
4444
71
    Operands.push_back(MipsOperand::createFCCReg(
4445
71
        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4446
71
    return MatchOperand_Success;
4447
71
  }
4448
4449
8.68k
  Index = matchACRegisterName(Identifier);
4450
8.68k
  if (Index != -1) {
4451
52
    Operands.push_back(MipsOperand::createACCReg(
4452
52
        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4453
52
    return MatchOperand_Success;
4454
52
  }
4455
4456
8.63k
  Index = matchMSA128RegisterName(Identifier);
4457
8.63k
  if (Index != -1) {
4458
1
    Operands.push_back(MipsOperand::createMSA128Reg(
4459
1
        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4460
1
    return MatchOperand_Success;
4461
1
  }
4462
4463
8.63k
  Index = matchMSA128CtrlRegisterName(Identifier);
4464
8.63k
  if (Index != -1) {
4465
180
    Operands.push_back(MipsOperand::createMSACtrlReg(
4466
180
        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4467
180
    return MatchOperand_Success;
4468
180
  }
4469
4470
8.45k
  return MatchOperand_NoMatch;
4471
8.63k
}
4472
4473
MipsAsmParser::OperandMatchResultTy
4474
MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S)
4475
47.6k
{
4476
47.6k
  MCAsmParser &Parser = getParser();
4477
47.6k
  auto Token = Parser.getLexer().peekTok(false);
4478
4479
47.6k
  if (Token.is(AsmToken::Identifier)) {
4480
14.7k
    DEBUG(dbgs() << ".. identifier\n");
4481
14.7k
    StringRef Identifier = Token.getIdentifier();
4482
14.7k
    OperandMatchResultTy ResTy =
4483
14.7k
        matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4484
14.7k
    return ResTy;
4485
32.9k
  } else if (Token.is(AsmToken::Integer)) {
4486
10.2k
    DEBUG(dbgs() << ".. integer\n");
4487
10.2k
    bool valid;
4488
10.2k
    unsigned Value = Token.getIntVal(valid);
4489
10.2k
    if (!valid)
4490
0
        return MatchOperand_NoMatch;
4491
10.2k
    Operands.push_back(MipsOperand::createNumericReg(
4492
10.2k
        Value, getContext().getRegisterInfo(), S, Token.getLoc(),
4493
10.2k
        *this));
4494
10.2k
    return MatchOperand_Success;
4495
10.2k
  }
4496
4497
22.6k
  DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4498
4499
22.6k
  return MatchOperand_NoMatch;
4500
47.6k
}
4501
4502
MipsAsmParser::OperandMatchResultTy
4503
79.6k
MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4504
79.6k
  MCAsmParser &Parser = getParser();
4505
79.6k
  DEBUG(dbgs() << "parseAnyRegister\n");
4506
4507
79.6k
  auto Token = Parser.getTok();
4508
4509
79.6k
  SMLoc S = Token.getLoc();
4510
4511
79.6k
  if (Token.isNot(AsmToken::Dollar)) {
4512
31.9k
    DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4513
31.9k
    if (Token.is(AsmToken::Identifier)) {
4514
9.44k
      if (searchSymbolAlias(Operands))
4515
50
        return MatchOperand_Success;
4516
9.44k
    }
4517
31.9k
    DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4518
31.9k
    return MatchOperand_NoMatch;
4519
31.9k
  }
4520
47.6k
  DEBUG(dbgs() << ".. $\n");
4521
4522
47.6k
  OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4523
47.6k
  if (ResTy == MatchOperand_Success) {
4524
16.9k
    Parser.Lex(); // $
4525
16.9k
    Parser.Lex(); // identifier
4526
16.9k
  }
4527
47.6k
  return ResTy;
4528
79.6k
}
4529
4530
MipsAsmParser::OperandMatchResultTy
4531
28.8k
MipsAsmParser::parseImm(OperandVector &Operands) {
4532
28.8k
  MCAsmParser &Parser = getParser();
4533
28.8k
  switch (getLexer().getKind()) {
4534
9.49k
  default:
4535
9.49k
    return MatchOperand_NoMatch;
4536
186
  case AsmToken::LParen:
4537
12.6k
  case AsmToken::Minus:
4538
17.0k
  case AsmToken::Plus:
4539
19.1k
  case AsmToken::Integer:
4540
19.2k
  case AsmToken::Tilde:
4541
19.3k
  case AsmToken::String:
4542
19.3k
    break;
4543
28.8k
  }
4544
4545
19.3k
  const MCExpr *IdVal;
4546
19.3k
  SMLoc S = Parser.getTok().getLoc();
4547
19.3k
  if (getParser().parseExpression(IdVal))
4548
11.4k
    return MatchOperand_ParseFail;
4549
4550
7.88k
  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4551
7.88k
  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4552
7.88k
  return MatchOperand_Success;
4553
19.3k
}
4554
4555
MipsAsmParser::OperandMatchResultTy
4556
24.8k
MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4557
24.8k
  MCAsmParser &Parser = getParser();
4558
24.8k
  DEBUG(dbgs() << "parseJumpTarget\n");
4559
4560
24.8k
  SMLoc S = getLexer().getLoc();
4561
4562
  // Integers and expressions are acceptable
4563
24.8k
  OperandMatchResultTy ResTy = parseImm(Operands);
4564
24.8k
  if (ResTy != MatchOperand_NoMatch)
4565
15.3k
    return ResTy;
4566
4567
  // Registers are a valid target and have priority over symbols.
4568
9.49k
  ResTy = parseAnyRegister(Operands);
4569
9.49k
  if (ResTy != MatchOperand_NoMatch)
4570
375
    return ResTy;
4571
4572
9.11k
  const MCExpr *Expr = nullptr;
4573
9.11k
  if (Parser.parseExpression(Expr)) {
4574
    // We have no way of knowing if a symbol was consumed so we must ParseFail
4575
1.88k
    return MatchOperand_ParseFail;
4576
1.88k
  }
4577
7.23k
  Operands.push_back(
4578
7.23k
      MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4579
7.23k
  return MatchOperand_Success;
4580
9.11k
}
4581
4582
MipsAsmParser::OperandMatchResultTy
4583
19
MipsAsmParser::parseInvNum(OperandVector &Operands) {
4584
19
  MCAsmParser &Parser = getParser();
4585
19
  const MCExpr *IdVal;
4586
  // If the first token is '$' we may have register operand.
4587
19
  if (Parser.getTok().is(AsmToken::Dollar))
4588
17
    return MatchOperand_NoMatch;
4589
2
  SMLoc S = Parser.getTok().getLoc();
4590
2
  if (getParser().parseExpression(IdVal))
4591
2
    return MatchOperand_ParseFail;
4592
0
  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4593
0
  assert(MCE && "Unexpected MCExpr type.");
4594
0
  int64_t Val = MCE->getValue();
4595
0
  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4596
0
  Operands.push_back(MipsOperand::CreateImm(
4597
0
      MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4598
0
  return MatchOperand_Success;
4599
0
}
4600
4601
MipsAsmParser::OperandMatchResultTy
4602
0
MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4603
0
  MCAsmParser &Parser = getParser();
4604
0
  SmallVector<unsigned, 10> Regs;
4605
0
  unsigned RegNo;
4606
0
  unsigned PrevReg = Mips::NoRegister;
4607
0
  bool RegRange = false;
4608
0
  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4609
4610
0
  if (Parser.getTok().isNot(AsmToken::Dollar))
4611
0
    return MatchOperand_ParseFail;
4612
4613
0
  SMLoc S = Parser.getTok().getLoc();
4614
0
  while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4615
0
    SMLoc E = getLexer().getLoc();
4616
0
    MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4617
0
    RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4618
0
    if (RegRange) {
4619
      // Remove last register operand because registers from register range
4620
      // should be inserted first.
4621
0
      if ((isGP64bit() && RegNo == Mips::RA_64) ||
4622
0
          (!isGP64bit() && RegNo == Mips::RA)) {
4623
0
        Regs.push_back(RegNo);
4624
0
      } else {
4625
0
        unsigned TmpReg = PrevReg + 1;
4626
0
        while (TmpReg <= RegNo) {
4627
0
          if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4628
0
              (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4629
0
               isGP64bit())) {
4630
0
            Error(E, "invalid register operand");
4631
0
            return MatchOperand_ParseFail;
4632
0
          }
4633
4634
0
          PrevReg = TmpReg;
4635
0
          Regs.push_back(TmpReg++);
4636
0
        }
4637
0
      }
4638
4639
0
      RegRange = false;
4640
0
    } else {
4641
0
      if ((PrevReg == Mips::NoRegister) &&
4642
0
          ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4643
0
          (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4644
0
        Error(E, "$16 or $31 expected");
4645
0
        return MatchOperand_ParseFail;
4646
0
      } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4647
0
                    (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4648
0
                    !isGP64bit()) ||
4649
0
                   ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4650
0
                    (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4651
0
                    isGP64bit()))) {
4652
0
        Error(E, "invalid register operand");
4653
0
        return MatchOperand_ParseFail;
4654
0
      } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4655
0
                 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4656
0
                  (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4657
0
                   isGP64bit()))) {
4658
0
        Error(E, "consecutive register numbers expected");
4659
0
        return MatchOperand_ParseFail;
4660
0
      }
4661
4662
0
      Regs.push_back(RegNo);
4663
0
    }
4664
4665
0
    if (Parser.getTok().is(AsmToken::Minus))
4666
0
      RegRange = true;
4667
4668
0
    if (!Parser.getTok().isNot(AsmToken::Minus) &&
4669
0
        !Parser.getTok().isNot(AsmToken::Comma)) {
4670
0
      Error(E, "',' or '-' expected");
4671
0
      return MatchOperand_ParseFail;
4672
0
    }
4673
4674
0
    Lex(); // Consume comma or minus
4675
0
    if (Parser.getTok().isNot(AsmToken::Dollar))
4676
0
      break;
4677
4678
0
    PrevReg = RegNo;
4679
0
  }
4680
4681
0
  SMLoc E = Parser.getTok().getLoc();
4682
0
  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4683
0
  parseMemOperand(Operands);
4684
0
  return MatchOperand_Success;
4685
0
}
4686
4687
MipsAsmParser::OperandMatchResultTy
4688
0
MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4689
0
  MCAsmParser &Parser = getParser();
4690
4691
0
  SMLoc S = Parser.getTok().getLoc();
4692
0
  if (parseAnyRegister(Operands) != MatchOperand_Success)
4693
0
    return MatchOperand_ParseFail;
4694
4695
0
  SMLoc E = Parser.getTok().getLoc();
4696
0
  MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4697
0
  unsigned Reg = Op.getGPR32Reg();
4698
0
  Operands.pop_back();
4699
0
  Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4700
0
  return MatchOperand_Success;
4701
0
}
4702
4703
MipsAsmParser::OperandMatchResultTy
4704
0
MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4705
0
  MCAsmParser &Parser = getParser();
4706
0
  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4707
0
  SmallVector<unsigned, 10> Regs;
4708
4709
0
  if (Parser.getTok().isNot(AsmToken::Dollar))
4710
0
    return MatchOperand_ParseFail;
4711
4712
0
  SMLoc S = Parser.getTok().getLoc();
4713
4714
0
  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4715
0
    return MatchOperand_ParseFail;
4716
4717
0
  MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4718
0
  unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4719
0
  Regs.push_back(RegNo);
4720
4721
0
  SMLoc E = Parser.getTok().getLoc();
4722
0
  if (Parser.getTok().isNot(AsmToken::Comma)) {
4723
0
    Error(E, "',' expected");
4724
0
    return MatchOperand_ParseFail;
4725
0
  }
4726
4727
  // Remove comma.
4728
0
  Parser.Lex();
4729
4730
0
  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4731
0
    return MatchOperand_ParseFail;
4732
4733
0
  Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4734
0
  RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4735
0
  Regs.push_back(RegNo);
4736
4737
0
  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4738
4739
0
  return MatchOperand_Success;
4740
0
}
4741
4742
11.3k
MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4743
4744
11.3k
  MCSymbolRefExpr::VariantKind VK =
4745
11.3k
      StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4746
11.3k
          .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4747
11.3k
          .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4748
11.3k
          .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4749
11.3k
          .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4750
11.3k
          .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4751
11.3k
          .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4752
11.3k
          .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4753
11.3k
          .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4754
11.3k
          .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4755
11.3k
          .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4756
11.3k
          .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4757
11.3k
          .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4758
11.3k
          .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4759
11.3k
          .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4760
11.3k
          .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4761
11.3k
          .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4762
11.3k
          .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4763
11.3k
          .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4764
11.3k
          .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4765
11.3k
          .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4766
11.3k
          .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4767
11.3k
          .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4768
11.3k
          .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4769
11.3k
          .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4770
11.3k
          .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4771
11.3k
          .Default(MCSymbolRefExpr::VK_None);
4772
4773
11.3k
  assert(VK != MCSymbolRefExpr::VK_None);
4774
4775
11.3k
  return VK;
4776
11.3k
}
4777
4778
/// Sometimes (i.e. load/stores) the operand may be followed immediately by
4779
/// either this.
4780
/// ::= '(', register, ')'
4781
/// handle it before we iterate so we don't get tripped up by the lack of
4782
/// a comma.
4783
31
bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands, unsigned int &ErrorCode) {
4784
31
  MCAsmParser &Parser = getParser();
4785
31
  if (getLexer().is(AsmToken::LParen)) {
4786
31
    Operands.push_back(
4787
31
        MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4788
31
    Parser.Lex();
4789
31
    if (parseOperand(Operands, Name, ErrorCode)) {
4790
      // SMLoc Loc = getLexer().getLoc();
4791
10
      Parser.eatToEndOfStatement();
4792
      //return Error(Loc, "unexpected token in argument list");
4793
10
      return true;
4794
10
    }
4795
21
    if (Parser.getTok().isNot(AsmToken::RParen)) {
4796
      // SMLoc Loc = getLexer().getLoc();
4797
4
      Parser.eatToEndOfStatement();
4798
      // return Error(Loc, "unexpected token, expected ')'");
4799
4
      ErrorCode = KS_ERR_ASM_MIPS_INVALIDOPERAND;
4800
4
      return true;
4801
4
    }
4802
17
    Operands.push_back(
4803
17
        MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4804
17
    Parser.Lex();
4805
17
  }
4806
17
  return false;
4807
31
}
4808
4809
/// Sometimes (i.e. in MSA) the operand may be followed immediately by
4810
/// either one of these.
4811
/// ::= '[', register, ']'
4812
/// ::= '[', integer, ']'
4813
/// handle it before we iterate so we don't get tripped up by the lack of
4814
/// a comma.
4815
bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4816
116
                                       OperandVector &Operands, unsigned int &ErrorCode) {
4817
116
  MCAsmParser &Parser = getParser();
4818
116
  if (getLexer().is(AsmToken::LBrac)) {
4819
116
    Operands.push_back(
4820
116
        MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4821
116
    Parser.Lex();
4822
116
    if (parseOperand(Operands, Name, ErrorCode)) {
4823
      // SMLoc Loc = getLexer().getLoc();
4824
38
      Parser.eatToEndOfStatement();
4825
      //return Error(Loc, "unexpected token in argument list");
4826
38
      return true;
4827
38
    }
4828
78
    if (Parser.getTok().isNot(AsmToken::RBrac)) {
4829
      // SMLoc Loc = getLexer().getLoc();
4830
2
      Parser.eatToEndOfStatement();
4831
      //return Error(Loc, "unexpected token, expected ']'");
4832
2
      ErrorCode = KS_ERR_ASM_MIPS_INVALIDOPERAND;
4833
2
      return true;
4834
2
    }
4835
76
    Operands.push_back(
4836
76
        MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4837
76
    Parser.Lex();
4838
76
  }
4839
76
  return false;
4840
116
}
4841
4842
bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4843
                                     SMLoc NameLoc, OperandVector &Operands, unsigned int &ErrorCode)
4844
34.1k
{
4845
34.1k
  MCAsmParser &Parser = getParser();
4846
34.1k
  DEBUG(dbgs() << "ParseInstruction\n");
4847
4848
  // We have reached first instruction, module directive are now forbidden.
4849
  //getTargetStreamer().forbidModuleDirective();
4850
4851
  // Check if we have valid mnemonic
4852
34.1k
  if (!mnemonicIsValid(Name, 0)) {
4853
891
    Parser.eatToEndOfStatement();
4854
    // return Error(NameLoc, "unknown instruction");
4855
891
    ErrorCode = KS_ERR_ASM_MIPS_MNEMONICFAIL;
4856
891
    return true;
4857
891
  }
4858
  // First operand in MCInst is instruction mnemonic.
4859
33.2k
  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4860
4861
  // Read the remaining operands.
4862
33.2k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4863
    // Read the first operand.
4864
33.1k
    if (parseOperand(Operands, Name, ErrorCode)) {
4865
      // SMLoc Loc = getLexer().getLoc();
4866
16.7k
      Parser.eatToEndOfStatement();
4867
      // return Error(Loc, "unexpected token in argument list");
4868
      // ErrorCode = KS_ERR_ASM_MIPS_INVALIDOPERAND;
4869
16.7k
      return true;
4870
16.7k
    }
4871
16.3k
    if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands, ErrorCode))
4872
39
      return true;
4873
    // AFAIK, parenthesis suffixes are never on the first operand
4874
4875
30.0k
    while (getLexer().is(AsmToken::Comma)) {
4876
14.6k
      Parser.Lex(); // Eat the comma.
4877
      // Parse and remember the operand.
4878
14.6k
      if (parseOperand(Operands, Name, ErrorCode)) {
4879
        // SMLoc Loc = getLexer().getLoc();
4880
937
        Parser.eatToEndOfStatement();
4881
        // return Error(Loc, "unexpected token in argument list");
4882
937
        return true;
4883
937
      }
4884
      // Parse bracket and parenthesis suffixes before we iterate
4885
13.7k
      if (getLexer().is(AsmToken::LBrac)) {
4886
62
        if (parseBracketSuffix(Name, Operands, ErrorCode))
4887
1
          return true;
4888
13.6k
      } else if (getLexer().is(AsmToken::LParen) &&
4889
31
                 parseParenSuffix(Name, Operands, ErrorCode))
4890
14
        return true;
4891
13.7k
    }
4892
16.3k
  }
4893
15.5k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4894
    // SMLoc Loc = getLexer().getLoc();
4895
523
    Parser.eatToEndOfStatement();
4896
    // return Error(Loc, "unexpected token in argument list");
4897
523
    ErrorCode = KS_ERR_ASM_MIPS_INVALIDOPERAND;
4898
523
    return true;
4899
523
  }
4900
14.9k
  Parser.Lex(); // Consume the EndOfStatement.
4901
14.9k
  return false;
4902
15.5k
}
4903
4904
37.4k
bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4905
37.4k
  MCAsmParser &Parser = getParser();
4906
37.4k
  SMLoc Loc = getLexer().getLoc();
4907
37.4k
  Parser.eatToEndOfStatement();
4908
37.4k
  return Error(Loc, ErrorMsg);
4909
37.4k
}
4910
4911
2.00k
bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4912
2.00k
  return Error(Loc, ErrorMsg);
4913
2.00k
}
4914
4915
91
bool MipsAsmParser::parseSetNoAtDirective() {
4916
91
  MCAsmParser &Parser = getParser();
4917
  // Line should look like: ".set noat".
4918
4919
  // Set the $at register to $0.
4920
91
  AssemblerOptions.back()->setATRegIndex(0);
4921
4922
91
  Parser.Lex(); // Eat "noat".
4923
4924
  // If this is not the end of the statement, report an error.
4925
91
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4926
52
    reportParseError("unexpected token, expected end of statement");
4927
52
    return false;
4928
52
  }
4929
4930
  //getTargetStreamer().emitDirectiveSetNoAt();
4931
39
  Parser.Lex(); // Consume the EndOfStatement.
4932
39
  return false;
4933
91
}
4934
4935
bool MipsAsmParser::parseSetAtDirective()
4936
891
{
4937
  // Line can be: ".set at", which sets $at to $1
4938
  //          or  ".set at=$reg", which sets $at to $reg.
4939
891
  MCAsmParser &Parser = getParser();
4940
891
  Parser.Lex(); // Eat "at".
4941
4942
891
  if (getLexer().is(AsmToken::EndOfStatement)) {
4943
    // No register was specified, so we set $at to $1.
4944
58
    AssemblerOptions.back()->setATRegIndex(1);
4945
4946
    //getTargetStreamer().emitDirectiveSetAt();
4947
58
    Parser.Lex(); // Consume the EndOfStatement.
4948
58
    return false;
4949
58
  }
4950
4951
833
  if (getLexer().isNot(AsmToken::Equal)) {
4952
109
    reportParseError("unexpected token, expected equals sign");
4953
109
    return false;
4954
109
  }
4955
724
  Parser.Lex(); // Eat "=".
4956
4957
724
  if (getLexer().isNot(AsmToken::Dollar)) {
4958
418
    if (getLexer().is(AsmToken::EndOfStatement)) {
4959
137
      reportParseError("no register specified");
4960
137
      return false;
4961
281
    } else {
4962
281
      reportParseError("unexpected token, expected dollar sign '$'");
4963
281
      return false;
4964
281
    }
4965
418
  }
4966
306
  Parser.Lex(); // Eat "$".
4967
4968
  // Find out what "reg" is.
4969
306
  unsigned AtRegNo;
4970
306
  const AsmToken &Reg = Parser.getTok();
4971
306
  if (Reg.is(AsmToken::Identifier)) {
4972
49
    AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4973
257
  } else if (Reg.is(AsmToken::Integer)) {
4974
215
    bool valid;
4975
215
    AtRegNo = Reg.getIntVal(valid);
4976
215
    if (!valid)
4977
0
        return true;
4978
215
  } else {
4979
42
    reportParseError("unexpected token, expected identifier or integer");
4980
42
    return false;
4981
42
  }
4982
4983
  // Check if $reg is a valid register. If it is, set $at to $reg.
4984
264
  if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4985
132
    reportParseError("invalid register");
4986
132
    return false;
4987
132
  }
4988
132
  Parser.Lex(); // Eat "reg".
4989
4990
  // If this is not the end of the statement, report an error.
4991
132
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4992
101
    reportParseError("unexpected token, expected end of statement");
4993
101
    return false;
4994
101
  }
4995
4996
  //getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4997
4998
31
  Parser.Lex(); // Consume the EndOfStatement.
4999
31
  return false;
5000
132
}
5001
5002
75
bool MipsAsmParser::parseSetReorderDirective() {
5003
75
  MCAsmParser &Parser = getParser();
5004
75
  Parser.Lex();
5005
  // If this is not the end of the statement, report an error.
5006
75
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5007
6
    reportParseError("unexpected token, expected end of statement");
5008
6
    return false;
5009
6
  }
5010
69
  AssemblerOptions.back()->setReorder();
5011
  //getTargetStreamer().emitDirectiveSetReorder();
5012
69
  Parser.Lex(); // Consume the EndOfStatement.
5013
69
  return false;
5014
75
}
5015
5016
147
bool MipsAsmParser::parseSetNoReorderDirective() {
5017
147
  MCAsmParser &Parser = getParser();
5018
147
  Parser.Lex();
5019
  // If this is not the end of the statement, report an error.
5020
147
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5021
41
    reportParseError("unexpected token, expected end of statement");
5022
41
    return false;
5023
41
  }
5024
106
  AssemblerOptions.back()->setNoReorder();
5025
  //getTargetStreamer().emitDirectiveSetNoReorder();
5026
106
  Parser.Lex(); // Consume the EndOfStatement.
5027
106
  return false;
5028
147
}
5029
5030
101
bool MipsAsmParser::parseSetMacroDirective() {
5031
101
  MCAsmParser &Parser = getParser();
5032
101
  Parser.Lex();
5033
  // If this is not the end of the statement, report an error.
5034
101
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5035
70
    reportParseError("unexpected token, expected end of statement");
5036
70
    return false;
5037
70
  }
5038
31
  AssemblerOptions.back()->setMacro();
5039
  //getTargetStreamer().emitDirectiveSetMacro();
5040
31
  Parser.Lex(); // Consume the EndOfStatement.
5041
31
  return false;
5042
101
}
5043
5044
18
bool MipsAsmParser::parseSetNoMacroDirective() {
5045
18
  MCAsmParser &Parser = getParser();
5046
18
  Parser.Lex();
5047
  // If this is not the end of the statement, report an error.
5048
18
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5049
10
    reportParseError("unexpected token, expected end of statement");
5050
10
    return false;
5051
10
  }
5052
8
  if (AssemblerOptions.back()->isReorder()) {
5053
8
    reportParseError("`noreorder' must be set before `nomacro'");
5054
8
    return false;
5055
8
  }
5056
0
  AssemblerOptions.back()->setNoMacro();
5057
  //getTargetStreamer().emitDirectiveSetNoMacro();
5058
0
  Parser.Lex(); // Consume the EndOfStatement.
5059
0
  return false;
5060
8
}
5061
5062
4.01k
bool MipsAsmParser::parseSetMsaDirective() {
5063
4.01k
  MCAsmParser &Parser = getParser();
5064
4.01k
  Parser.Lex();
5065
5066
  // If this is not the end of the statement, report an error.
5067
4.01k
  if (getLexer().isNot(AsmToken::EndOfStatement))
5068
97
    return reportParseError("unexpected token, expected end of statement");
5069
5070
3.91k
  setFeatureBits(Mips::FeatureMSA, "msa");
5071
  //getTargetStreamer().emitDirectiveSetMsa();
5072
3.91k
  return false;
5073
4.01k
}
5074
5075
7.58k
bool MipsAsmParser::parseSetNoMsaDirective() {
5076
7.58k
  MCAsmParser &Parser = getParser();
5077
7.58k
  Parser.Lex();
5078
5079
  // If this is not the end of the statement, report an error.
5080
7.58k
  if (getLexer().isNot(AsmToken::EndOfStatement))
5081
1.36k
    return reportParseError("unexpected token, expected end of statement");
5082
5083
6.22k
  clearFeatureBits(Mips::FeatureMSA, "msa");
5084
  //getTargetStreamer().emitDirectiveSetNoMsa();
5085
6.22k
  return false;
5086
7.58k
}
5087
5088
26
bool MipsAsmParser::parseSetNoDspDirective() {
5089
26
  MCAsmParser &Parser = getParser();
5090
26
  Parser.Lex(); // Eat "nodsp".
5091
5092
  // If this is not the end of the statement, report an error.
5093
26
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5094
10
    reportParseError("unexpected token, expected end of statement");
5095
10
    return false;
5096
10
  }
5097
5098
16
  clearFeatureBits(Mips::FeatureDSP, "dsp");
5099
  //getTargetStreamer().emitDirectiveSetNoDsp();
5100
16
  return false;
5101
26
}
5102
5103
239
bool MipsAsmParser::parseSetMips16Directive() {
5104
239
  MCAsmParser &Parser = getParser();
5105
239
  Parser.Lex(); // Eat "mips16".
5106
5107
  // If this is not the end of the statement, report an error.
5108
239
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5109
191
    reportParseError("unexpected token, expected end of statement");
5110
191
    return false;
5111
191
  }
5112
5113
48
  setFeatureBits(Mips::FeatureMips16, "mips16");
5114
  //getTargetStreamer().emitDirectiveSetMips16();
5115
48
  Parser.Lex(); // Consume the EndOfStatement.
5116
48
  return false;
5117
239
}
5118
5119
28
bool MipsAsmParser::parseSetNoMips16Directive() {
5120
28
  MCAsmParser &Parser = getParser();
5121
28
  Parser.Lex(); // Eat "nomips16".
5122
5123
  // If this is not the end of the statement, report an error.
5124
28
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5125
19
    reportParseError("unexpected token, expected end of statement");
5126
19
    return false;
5127
19
  }
5128
5129
9
  clearFeatureBits(Mips::FeatureMips16, "mips16");
5130
  //getTargetStreamer().emitDirectiveSetNoMips16();
5131
9
  Parser.Lex(); // Consume the EndOfStatement.
5132
9
  return false;
5133
28
}
5134
5135
813
bool MipsAsmParser::parseSetFpDirective() {
5136
813
  MCAsmParser &Parser = getParser();
5137
813
  MipsABIFlagsSection::FpABIKind FpAbiVal;
5138
  // Line can be: .set fp=32
5139
  //              .set fp=xx
5140
  //              .set fp=64
5141
813
  Parser.Lex(); // Eat fp token
5142
813
  AsmToken Tok = Parser.getTok();
5143
813
  if (Tok.isNot(AsmToken::Equal)) {
5144
32
    reportParseError("unexpected token, expected equals sign '='");
5145
32
    return false;
5146
32
  }
5147
781
  Parser.Lex(); // Eat '=' token.
5148
781
  Tok = Parser.getTok();
5149
5150
781
  if (!parseFpABIValue(FpAbiVal, ".set"))
5151
622
    return false;
5152
5153
159
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5154
31
    reportParseError("unexpected token, expected end of statement");
5155
31
    return false;
5156
31
  }
5157
  //getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5158
128
  Parser.Lex(); // Consume the EndOfStatement.
5159
128
  return false;
5160
159
}
5161
5162
377
bool MipsAsmParser::parseSetOddSPRegDirective() {
5163
377
  MCAsmParser &Parser = getParser();
5164
5165
377
  Parser.Lex(); // Eat "oddspreg".
5166
377
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5167
34
    reportParseError("unexpected token, expected end of statement");
5168
34
    return false;
5169
34
  }
5170
5171
343
  clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5172
  //getTargetStreamer().emitDirectiveSetOddSPReg();
5173
343
  return false;
5174
377
}
5175
5176
0
bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5177
0
  MCAsmParser &Parser = getParser();
5178
5179
0
  Parser.Lex(); // Eat "nooddspreg".
5180
0
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5181
0
    reportParseError("unexpected token, expected end of statement");
5182
0
    return false;
5183
0
  }
5184
5185
0
  setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5186
  //getTargetStreamer().emitDirectiveSetNoOddSPReg();
5187
0
  return false;
5188
0
}
5189
5190
40
bool MipsAsmParser::parseSetPopDirective() {
5191
40
  MCAsmParser &Parser = getParser();
5192
40
  SMLoc Loc = getLexer().getLoc();
5193
5194
40
  Parser.Lex();
5195
40
  if (getLexer().isNot(AsmToken::EndOfStatement))
5196
39
    return reportParseError("unexpected token, expected end of statement");
5197
5198
  // Always keep an element on the options "stack" to prevent the user
5199
  // from changing the initial options. This is how we remember them.
5200
1
  if (AssemblerOptions.size() == 2)
5201
1
    return reportParseError(Loc, ".set pop with no .set push");
5202
5203
0
  MCSubtargetInfo &STI = copySTI();
5204
0
  AssemblerOptions.pop_back();
5205
0
  setAvailableFeatures(
5206
0
      ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5207
0
  STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5208
5209
  //getTargetStreamer().emitDirectiveSetPop();
5210
0
  return false;
5211
1
}
5212
5213
88
bool MipsAsmParser::parseSetPushDirective() {
5214
88
  MCAsmParser &Parser = getParser();
5215
88
  Parser.Lex();
5216
88
  if (getLexer().isNot(AsmToken::EndOfStatement))
5217
77
    return reportParseError("unexpected token, expected end of statement");
5218
5219
  // Create a copy of the current assembler options environment and push it.
5220
11
  AssemblerOptions.push_back(
5221
11
              make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5222
5223
  //getTargetStreamer().emitDirectiveSetPush();
5224
11
  return false;
5225
88
}
5226
5227
16
bool MipsAsmParser::parseSetSoftFloatDirective() {
5228
16
  MCAsmParser &Parser = getParser();
5229
16
  Parser.Lex();
5230
16
  if (getLexer().isNot(AsmToken::EndOfStatement))
5231
2
    return reportParseError("unexpected token, expected end of statement");
5232
5233
14
  setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5234
  //getTargetStreamer().emitDirectiveSetSoftFloat();
5235
14
  return false;
5236
16
}
5237
5238
225
bool MipsAsmParser::parseSetHardFloatDirective() {
5239
225
  MCAsmParser &Parser = getParser();
5240
225
  Parser.Lex();
5241
225
  if (getLexer().isNot(AsmToken::EndOfStatement))
5242
8
    return reportParseError("unexpected token, expected end of statement");
5243
5244
217
  clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5245
  //getTargetStreamer().emitDirectiveSetHardFloat();
5246
217
  return false;
5247
225
}
5248
5249
14.9k
bool MipsAsmParser::parseSetAssignment() {
5250
14.9k
  StringRef Name;
5251
14.9k
  const MCExpr *Value;
5252
14.9k
  MCAsmParser &Parser = getParser();
5253
5254
14.9k
  if (Parser.parseIdentifier(Name))
5255
2.72k
    reportParseError("expected identifier after .set");
5256
5257
14.9k
  if (getLexer().isNot(AsmToken::Comma))
5258
14.0k
    return reportParseError("unexpected token, expected comma");
5259
837
  Lex(); // Eat comma
5260
5261
837
  if (Parser.parseExpression(Value))
5262
477
    return reportParseError("expected valid expression after comma");
5263
5264
360
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5265
360
  bool valid;
5266
360
  Sym->setVariableValue(Value, valid);
5267
360
  if (!valid)
5268
0
      return true;
5269
5270
360
  return false;
5271
360
}
5272
5273
453
bool MipsAsmParser::parseSetMips0Directive() {
5274
453
  MCAsmParser &Parser = getParser();
5275
453
  Parser.Lex();
5276
453
  if (getLexer().isNot(AsmToken::EndOfStatement))
5277
106
    return reportParseError("unexpected token, expected end of statement");
5278
5279
  // Reset assembler options to their initial values.
5280
347
  MCSubtargetInfo &STI = copySTI();
5281
347
  setAvailableFeatures(
5282
347
      ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5283
347
  STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5284
347
  AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5285
5286
  //getTargetStreamer().emitDirectiveSetMips0();
5287
347
  return false;
5288
453
}
5289
5290
138
bool MipsAsmParser::parseSetArchDirective() {
5291
138
  MCAsmParser &Parser = getParser();
5292
138
  Parser.Lex();
5293
138
  if (getLexer().isNot(AsmToken::Equal))
5294
5
    return reportParseError("unexpected token, expected equals sign");
5295
5296
133
  Parser.Lex();
5297
133
  StringRef Arch;
5298
133
  if (Parser.parseIdentifier(Arch))
5299
1
    return reportParseError("expected arch identifier");
5300
5301
132
  StringRef ArchFeatureName =
5302
132
      StringSwitch<StringRef>(Arch)
5303
132
          .Case("mips1", "mips1")
5304
132
          .Case("mips2", "mips2")
5305
132
          .Case("mips3", "mips3")
5306
132
          .Case("mips4", "mips4")
5307
132
          .Case("mips5", "mips5")
5308
132
          .Case("mips32", "mips32")
5309
132
          .Case("mips32r2", "mips32r2")
5310
132
          .Case("mips32r3", "mips32r3")
5311
132
          .Case("mips32r5", "mips32r5")
5312
132
          .Case("mips32r6", "mips32r6")
5313
132
          .Case("mips64", "mips64")
5314
132
          .Case("mips64r2", "mips64r2")
5315
132
          .Case("mips64r3", "mips64r3")
5316
132
          .Case("mips64r5", "mips64r5")
5317
132
          .Case("mips64r6", "mips64r6")
5318
132
          .Case("cnmips", "cnmips")
5319
132
          .Case("r4000", "mips3") // This is an implementation of Mips3.
5320
132
          .Default("");
5321
5322
132
  if (ArchFeatureName.empty())
5323
80
    return reportParseError("unsupported architecture");
5324
5325
52
  selectArch(ArchFeatureName);
5326
  //getTargetStreamer().emitDirectiveSetArch(Arch);
5327
52
  return false;
5328
132
}
5329
5330
5.80k
bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5331
5.80k
  MCAsmParser &Parser = getParser();
5332
5.80k
  Parser.Lex();
5333
5.80k
  if (getLexer().isNot(AsmToken::EndOfStatement))
5334
3.07k
    return reportParseError("unexpected token, expected end of statement");
5335
5336
2.72k
  switch (Feature) {
5337
0
  default:
5338
0
    llvm_unreachable("Unimplemented feature");
5339
15
  case Mips::FeatureDSP:
5340
15
    setFeatureBits(Mips::FeatureDSP, "dsp");
5341
    //getTargetStreamer().emitDirectiveSetDsp();
5342
15
    break;
5343
0
  case Mips::FeatureMicroMips:
5344
    //getTargetStreamer().emitDirectiveSetMicroMips();
5345
0
    break;
5346
384
  case Mips::FeatureMips1:
5347
384
    selectArch("mips1");
5348
    //getTargetStreamer().emitDirectiveSetMips1();
5349
384
    break;
5350
98
  case Mips::FeatureMips2:
5351
98
    selectArch("mips2");
5352
    //getTargetStreamer().emitDirectiveSetMips2();
5353
98
    break;
5354
43
  case Mips::FeatureMips3:
5355
43
    selectArch("mips3");
5356
    //getTargetStreamer().emitDirectiveSetMips3();
5357
43
    break;
5358
177
  case Mips::FeatureMips4:
5359
177
    selectArch("mips4");
5360
    //getTargetStreamer().emitDirectiveSetMips4();
5361
177
    break;
5362
87
  case Mips::FeatureMips5:
5363
87
    selectArch("mips5");
5364
    //getTargetStreamer().emitDirectiveSetMips5();
5365
87
    break;
5366
695
  case Mips::FeatureMips32:
5367
695
    selectArch("mips32");
5368
    //getTargetStreamer().emitDirectiveSetMips32();
5369
695
    break;
5370
9
  case Mips::FeatureMips32r2:
5371
9
    selectArch("mips32r2");
5372
    //getTargetStreamer().emitDirectiveSetMips32R2();
5373
9
    break;
5374
5
  case Mips::FeatureMips32r3:
5375
5
    selectArch("mips32r3");
5376
    //getTargetStreamer().emitDirectiveSetMips32R3();
5377
5
    break;
5378
3
  case Mips::FeatureMips32r5:
5379
3
    selectArch("mips32r5");
5380
    //getTargetStreamer().emitDirectiveSetMips32R5();
5381
3
    break;
5382
21
  case Mips::FeatureMips32r6:
5383
21
    selectArch("mips32r6");
5384
    //getTargetStreamer().emitDirectiveSetMips32R6();
5385
21
    break;
5386
841
  case Mips::FeatureMips64:
5387
841
    selectArch("mips64");
5388
    //getTargetStreamer().emitDirectiveSetMips64();
5389
841
    break;
5390
143
  case Mips::FeatureMips64r2:
5391
143
    selectArch("mips64r2");
5392
    //getTargetStreamer().emitDirectiveSetMips64R2();
5393
143
    break;
5394
35
  case Mips::FeatureMips64r3:
5395
35
    selectArch("mips64r3");
5396
    //getTargetStreamer().emitDirectiveSetMips64R3();
5397
35
    break;
5398
53
  case Mips::FeatureMips64r5:
5399
53
    selectArch("mips64r5");
5400
    //getTargetStreamer().emitDirectiveSetMips64R5();
5401
53
    break;
5402
119
  case Mips::FeatureMips64r6:
5403
119
    selectArch("mips64r6");
5404
    //getTargetStreamer().emitDirectiveSetMips64R6();
5405
119
    break;
5406
2.72k
  }
5407
2.72k
  return false;
5408
2.72k
}
5409
5410
3.70k
bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5411
3.70k
  MCAsmParser &Parser = getParser();
5412
3.70k
  if (getLexer().isNot(AsmToken::Comma)) {
5413
1.30k
    SMLoc Loc = getLexer().getLoc();
5414
1.30k
    Parser.eatToEndOfStatement();
5415
1.30k
    return Error(Loc, ErrorStr);
5416
1.30k
  }
5417
5418
2.40k
  Parser.Lex(); // Eat the comma.
5419
2.40k
  return true;
5420
3.70k
}
5421
5422
// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5423
// In this class, it is only used for .cprestore.
5424
// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5425
// MipsTargetELFStreamer and MipsAsmParser.
5426
21
bool MipsAsmParser::isPicAndNotNxxAbi() {
5427
21
  return inPicMode() && !(isABI_N32() || isABI_N64());
5428
21
}
5429
5430
230
bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5431
230
  if (AssemblerOptions.back()->isReorder()) {
5432
    // Warning(Loc, ".cpload should be inside a noreorder section");
5433
230
  }
5434
5435
230
  if (inMips16Mode()) {
5436
10
    reportParseError(".cpload is not supported in Mips16 mode");
5437
10
    return false;
5438
10
  }
5439
5440
220
  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5441
220
  OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5442
220
  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5443
86
    reportParseError("expected register containing function address");
5444
86
    return false;
5445
86
  }
5446
5447
134
  MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5448
134
  if (!RegOpnd.isGPRAsmReg()) {
5449
30
    reportParseError(RegOpnd.getStartLoc(), "invalid register");
5450
30
    return false;
5451
30
  }
5452
5453
  // If this is not the end of the statement, report an error.
5454
104
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5455
25
    reportParseError("unexpected token, expected end of statement");
5456
25
    return false;
5457
25
  }
5458
5459
  //getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5460
79
  return false;
5461
104
}
5462
5463
386
bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5464
386
  MCAsmParser &Parser = getParser();
5465
5466
  // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5467
  // is used in non-PIC mode.
5468
5469
386
  if (inMips16Mode()) {
5470
45
    reportParseError(".cprestore is not supported in Mips16 mode");
5471
45
    return false;
5472
45
  }
5473
5474
  // Get the stack offset value.
5475
341
  const MCExpr *StackOffset;
5476
341
  int64_t StackOffsetVal;
5477
341
  if (Parser.parseExpression(StackOffset)) {
5478
28
    reportParseError("expected stack offset value");
5479
28
    return false;
5480
28
  }
5481
5482
313
  if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5483
56
    reportParseError("stack offset is not an absolute expression");
5484
56
    return false;
5485
56
  }
5486
5487
257
  if (StackOffsetVal < 0) {
5488
    // Warning(Loc, ".cprestore with negative stack offset has no effect");
5489
57
    IsCpRestoreSet = false;
5490
200
  } else {
5491
200
    IsCpRestoreSet = true;
5492
200
    CpRestoreOffset = StackOffsetVal;
5493
200
  }
5494
5495
  // If this is not the end of the statement, report an error.
5496
257
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5497
237
    reportParseError("unexpected token, expected end of statement");
5498
237
    return false;
5499
237
  }
5500
5501
  // Store the $gp on the stack.
5502
20
  SmallVector<MCInst, 3> StoreInsts;
5503
20
  createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5504
20
                       StoreInsts);
5505
5506
  //getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5507
20
  Parser.Lex(); // Consume the EndOfStatement.
5508
20
  return false;
5509
257
}
5510
5511
3.10k
bool MipsAsmParser::parseDirectiveCPSetup() {
5512
3.10k
  MCAsmParser &Parser = getParser();
5513
  //unsigned FuncReg;
5514
3.10k
  unsigned Save;
5515
3.10k
  bool SaveIsReg = true;
5516
5517
3.10k
  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5518
3.10k
  OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5519
3.10k
  if (ResTy == MatchOperand_NoMatch) {
5520
112
    reportParseError("expected register containing function address");
5521
112
    Parser.eatToEndOfStatement();
5522
112
    return false;
5523
112
  }
5524
5525
2.99k
  MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5526
2.99k
  if (!FuncRegOpnd.isGPRAsmReg()) {
5527
440
    reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5528
440
    Parser.eatToEndOfStatement();
5529
440
    return false;
5530
440
  }
5531
5532
  //FuncReg = FuncRegOpnd.getGPR32Reg();
5533
2.55k
  TmpReg.clear();
5534
5535
2.55k
  if (!eatComma("unexpected token, expected comma"))
5536
0
    return true;
5537
5538
2.55k
  ResTy = parseAnyRegister(TmpReg);
5539
2.55k
  if (ResTy == MatchOperand_NoMatch) {
5540
2.31k
    const MCExpr *OffsetExpr;
5541
2.31k
    int64_t OffsetVal;
5542
2.31k
    SMLoc ExprLoc = getLexer().getLoc();
5543
5544
2.31k
    if (Parser.parseExpression(OffsetExpr) ||
5545
2.09k
        !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5546
1.32k
      reportParseError(ExprLoc, "expected save register or stack offset");
5547
1.32k
      Parser.eatToEndOfStatement();
5548
1.32k
      return false;
5549
1.32k
    }
5550
5551
989
    Save = OffsetVal;
5552
989
    SaveIsReg = false;
5553
989
  } else {
5554
242
    MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5555
242
    if (!SaveOpnd.isGPRAsmReg()) {
5556
83
      reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5557
83
      Parser.eatToEndOfStatement();
5558
83
      return false;
5559
83
    }
5560
159
    Save = SaveOpnd.getGPR32Reg();
5561
159
  }
5562
5563
1.14k
  if (!eatComma("unexpected token, expected comma"))
5564
0
    return true;
5565
5566
1.14k
  const MCExpr *Expr;
5567
1.14k
  if (Parser.parseExpression(Expr)) {
5568
805
    reportParseError("expected expression");
5569
805
    return false;
5570
805
  }
5571
5572
343
  if (Expr->getKind() != MCExpr::SymbolRef) {
5573
269
    reportParseError("expected symbol");
5574
269
    return false;
5575
269
  }
5576
  //const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5577
5578
74
  CpSaveLocation = Save;
5579
74
  CpSaveLocationIsRegister = SaveIsReg;
5580
5581
  //getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5582
  //                                         SaveIsReg);
5583
74
  return false;
5584
343
}
5585
5586
4
bool MipsAsmParser::parseDirectiveCPReturn() {
5587
  //getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5588
  //                                          CpSaveLocationIsRegister);
5589
4
  return false;
5590
4
}
5591
5592
1.14k
bool MipsAsmParser::parseDirectiveNaN() {
5593
1.14k
  MCAsmParser &Parser = getParser();
5594
1.14k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5595
615
    const AsmToken &Tok = Parser.getTok();
5596
5597
615
    if (Tok.getString() == "2008") {
5598
0
      Parser.Lex();
5599
      //getTargetStreamer().emitDirectiveNaN2008();
5600
0
      return false;
5601
615
    } else if (Tok.getString() == "legacy") {
5602
0
      Parser.Lex();
5603
      //getTargetStreamer().emitDirectiveNaNLegacy();
5604
0
      return false;
5605
0
    }
5606
615
  }
5607
  // If we don't recognize the option passed to the .nan
5608
  // directive (e.g. no option or unknown option), emit an error.
5609
1.14k
  reportParseError("invalid option in .nan directive");
5610
1.14k
  return false;
5611
1.14k
}
5612
5613
36.0k
bool MipsAsmParser::parseDirectiveSet() {
5614
36.0k
  MCAsmParser &Parser = getParser();
5615
  // Get the next token.
5616
36.0k
  const AsmToken &Tok = Parser.getTok();
5617
5618
36.0k
  if (Tok.getString() == "noat") {
5619
91
    return parseSetNoAtDirective();
5620
35.9k
  } else if (Tok.getString() == "at") {
5621
891
    return parseSetAtDirective();
5622
35.1k
  } else if (Tok.getString() == "arch") {
5623
138
    return parseSetArchDirective();
5624
34.9k
  } else if (Tok.getString() == "fp") {
5625
813
    return parseSetFpDirective();
5626
34.1k
  } else if (Tok.getString() == "oddspreg") {
5627
377
    return parseSetOddSPRegDirective();
5628
33.7k
  } else if (Tok.getString() == "nooddspreg") {
5629
0
    return parseSetNoOddSPRegDirective();
5630
33.7k
  } else if (Tok.getString() == "pop") {
5631
40
    return parseSetPopDirective();
5632
33.7k
  } else if (Tok.getString() == "push") {
5633
88
    return parseSetPushDirective();
5634
33.6k
  } else if (Tok.getString() == "reorder") {
5635
75
    return parseSetReorderDirective();
5636
33.5k
  } else if (Tok.getString() == "noreorder") {
5637
147
    return parseSetNoReorderDirective();
5638
33.4k
  } else if (Tok.getString() == "macro") {
5639
101
    return parseSetMacroDirective();
5640
33.3k
  } else if (Tok.getString() == "nomacro") {
5641
18
    return parseSetNoMacroDirective();
5642
33.3k
  } else if (Tok.getString() == "mips16") {
5643
239
    return parseSetMips16Directive();
5644
33.0k
  } else if (Tok.getString() == "nomips16") {
5645
28
    return parseSetNoMips16Directive();
5646
33.0k
  } else if (Tok.getString() == "nomicromips") {
5647
    //getTargetStreamer().emitDirectiveSetNoMicroMips();
5648
0
    Parser.eatToEndOfStatement();
5649
0
    return false;
5650
33.0k
  } else if (Tok.getString() == "micromips") {
5651
0
    return parseSetFeature(Mips::FeatureMicroMips);
5652
33.0k
  } else if (Tok.getString() == "mips0") {
5653
453
    return parseSetMips0Directive();
5654
32.5k
  } else if (Tok.getString() == "mips1") {
5655
385
    return parseSetFeature(Mips::FeatureMips1);
5656
32.1k
  } else if (Tok.getString() == "mips2") {
5657
124
    return parseSetFeature(Mips::FeatureMips2);
5658
32.0k
  } else if (Tok.getString() == "mips3") {
5659
94
    return parseSetFeature(Mips::FeatureMips3);
5660
31.9k
  } else if (Tok.getString() == "mips4") {
5661
2.98k
    return parseSetFeature(Mips::FeatureMips4);
5662
28.9k
  } else if (Tok.getString() == "mips5") {
5663
87
    return parseSetFeature(Mips::FeatureMips5);
5664
28.9k
  } else if (Tok.getString() == "mips32") {
5665
752
    return parseSetFeature(Mips::FeatureMips32);
5666
28.1k
  } else if (Tok.getString() == "mips32r2") {
5667
9
    return parseSetFeature(Mips::FeatureMips32r2);
5668
28.1k
  } else if (Tok.getString() == "mips32r3") {
5669
5
    return parseSetFeature(Mips::FeatureMips32r3);
5670
28.1k
  } else if (Tok.getString() == "mips32r5") {
5671
3
    return parseSetFeature(Mips::FeatureMips32r5);
5672
28.1k
  } else if (Tok.getString() == "mips32r6") {
5673
21
    return parseSetFeature(Mips::FeatureMips32r6);
5674
28.1k
  } else if (Tok.getString() == "mips64") {
5675
979
    return parseSetFeature(Mips::FeatureMips64);
5676
27.1k
  } else if (Tok.getString() == "mips64r2") {
5677
143
    return parseSetFeature(Mips::FeatureMips64r2);
5678
27.0k
  } else if (Tok.getString() == "mips64r3") {
5679
35
    return parseSetFeature(Mips::FeatureMips64r3);
5680
26.9k
  } else if (Tok.getString() == "mips64r5") {
5681
53
    return parseSetFeature(Mips::FeatureMips64r5);
5682
26.9k
  } else if (Tok.getString() == "mips64r6") {
5683
119
    return parseSetFeature(Mips::FeatureMips64r6);
5684
26.7k
  } else if (Tok.getString() == "dsp") {
5685
15
    return parseSetFeature(Mips::FeatureDSP);
5686
26.7k
  } else if (Tok.getString() == "nodsp") {
5687
26
    return parseSetNoDspDirective();
5688
26.7k
  } else if (Tok.getString() == "msa") {
5689
4.01k
    return parseSetMsaDirective();
5690
22.7k
  } else if (Tok.getString() == "nomsa") {
5691
7.58k
    return parseSetNoMsaDirective();
5692
15.1k
  } else if (Tok.getString() == "softfloat") {
5693
16
    return parseSetSoftFloatDirective();
5694
15.1k
  } else if (Tok.getString() == "hardfloat") {
5695
225
    return parseSetHardFloatDirective();
5696
14.9k
  } else {
5697
    // It is just an identifier, look for an assignment.
5698
14.9k
    parseSetAssignment();
5699
14.9k
    return false;
5700
14.9k
  }
5701
5702
0
  return true;
5703
36.0k
}
5704
5705
/// parseDataDirective
5706
///  ::= .word [ expression (, expression)* ]
5707
19.1k
bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5708
19.1k
  MCAsmParser &Parser = getParser();
5709
19.1k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5710
108k
    for (;;) {
5711
108k
      const MCExpr *Value;
5712
108k
      if (getParser().parseExpression(Value))
5713
693
        return true;
5714
5715
107k
      getParser().getStreamer().EmitValue(Value, Size);
5716
5717
107k
      if (getLexer().is(AsmToken::EndOfStatement))
5718
17.3k
        break;
5719
5720
90.5k
      if (getLexer().isNot(AsmToken::Comma))
5721
756
        return Error(L, "unexpected token, expected comma");
5722
89.7k
      Parser.Lex();
5723
89.7k
    }
5724
18.7k
  }
5725
5726
17.7k
  Parser.Lex();
5727
17.7k
  return false;
5728
19.1k
}
5729
5730
/// parseDirectiveGpWord
5731
///  ::= .gpword local_sym
5732
493
bool MipsAsmParser::parseDirectiveGpWord() {
5733
493
  MCAsmParser &Parser = getParser();
5734
493
  const MCExpr *Value;
5735
  // EmitGPRel32Value requires an expression, so we are using base class
5736
  // method to evaluate the expression.
5737
493
  if (getParser().parseExpression(Value))
5738
12
    return true;
5739
481
  getParser().getStreamer().EmitGPRel32Value(Value);
5740
5741
481
  if (getLexer().isNot(AsmToken::EndOfStatement))
5742
55
    return Error(getLexer().getLoc(), 
5743
55
                "unexpected token, expected end of statement");
5744
426
  Parser.Lex(); // Eat EndOfStatement token.
5745
426
  return false;
5746
481
}
5747
5748
/// parseDirectiveGpDWord
5749
///  ::= .gpdword local_sym
5750
136
bool MipsAsmParser::parseDirectiveGpDWord() {
5751
136
  MCAsmParser &Parser = getParser();
5752
136
  const MCExpr *Value;
5753
  // EmitGPRel64Value requires an expression, so we are using base class
5754
  // method to evaluate the expression.
5755
136
  if (getParser().parseExpression(Value))
5756
11
    return true;
5757
125
  getParser().getStreamer().EmitGPRel64Value(Value);
5758
5759
125
  if (getLexer().isNot(AsmToken::EndOfStatement))
5760
43
    return Error(getLexer().getLoc(), 
5761
43
                "unexpected token, expected end of statement");
5762
82
  Parser.Lex(); // Eat EndOfStatement token.
5763
82
  return false;
5764
125
}
5765
5766
661
bool MipsAsmParser::parseDirectiveOption() {
5767
661
  MCAsmParser &Parser = getParser();
5768
  // Get the option token.
5769
661
  AsmToken Tok = Parser.getTok();
5770
  // At the moment only identifiers are supported.
5771
661
  if (Tok.isNot(AsmToken::Identifier)) {
5772
258
    Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5773
258
    Parser.eatToEndOfStatement();
5774
258
    return false;
5775
258
  }
5776
5777
403
  StringRef Option = Tok.getIdentifier();
5778
5779
403
  if (Option == "pic0") {
5780
    // MipsAsmParser needs to know if the current PIC mode changes.
5781
151
    IsPicEnabled = false;
5782
5783
    //getTargetStreamer().emitDirectiveOptionPic0();
5784
151
    Parser.Lex();
5785
151
    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5786
87
      Error(Parser.getTok().getLoc(),
5787
87
            "unexpected token, expected end of statement");
5788
87
      Parser.eatToEndOfStatement();
5789
87
    }
5790
151
    return false;
5791
151
  }
5792
5793
252
  if (Option == "pic2") {
5794
    // MipsAsmParser needs to know if the current PIC mode changes.
5795
56
    IsPicEnabled = true;
5796
5797
    //getTargetStreamer().emitDirectiveOptionPic2();
5798
56
    Parser.Lex();
5799
56
    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5800
45
      Error(Parser.getTok().getLoc(),
5801
45
            "unexpected token, expected end of statement");
5802
45
      Parser.eatToEndOfStatement();
5803
45
    }
5804
56
    return false;
5805
56
  }
5806
5807
  // Unknown option.
5808
  // Warning(Parser.getTok().getLoc(), 
5809
  //         "unknown option, expected 'pic0' or 'pic2'");
5810
196
  Parser.eatToEndOfStatement();
5811
196
  return false;
5812
252
}
5813
5814
/// parseInsnDirective
5815
///  ::= .insn
5816
122
bool MipsAsmParser::parseInsnDirective() {
5817
  // If this is not the end of the statement, report an error.
5818
122
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5819
31
    reportParseError("unexpected token, expected end of statement");
5820
31
    return false;
5821
31
  }
5822
5823
  // The actual label marking happens in
5824
  // MipsELFStreamer::createPendingLabelRelocs().
5825
  //getTargetStreamer().emitDirectiveInsn();
5826
5827
91
  getParser().Lex(); // Eat EndOfStatement token.
5828
91
  return false;
5829
122
}
5830
5831
/// parseDirectiveModule
5832
///  ::= .module oddspreg
5833
///  ::= .module nooddspreg
5834
///  ::= .module fp=value
5835
///  ::= .module softfloat
5836
///  ::= .module hardfloat
5837
103
bool MipsAsmParser::parseDirectiveModule() {
5838
103
  MCAsmParser &Parser = getParser();
5839
103
  MCAsmLexer &Lexer = getLexer();
5840
103
  SMLoc L = Lexer.getLoc();
5841
5842
#if 0
5843
  if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5844
    // TODO : get a better message.
5845
    reportParseError(".module directive must appear before any code");
5846
    return false;
5847
  }
5848
#endif
5849
5850
103
  StringRef Option;
5851
103
  if (Parser.parseIdentifier(Option)) {
5852
9
    reportParseError("expected .module option identifier");
5853
9
    return false;
5854
9
  }
5855
5856
94
  if (Option == "oddspreg") {
5857
4
    clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5858
5859
    // Synchronize the abiflags information with the FeatureBits information we
5860
    // changed above.
5861
    //getTargetStreamer().updateABIInfo(*this);
5862
5863
    // If printing assembly, use the recently updated abiflags information.
5864
    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5865
    // emitted at the end).
5866
    //getTargetStreamer().emitDirectiveModuleOddSPReg();
5867
5868
    // If this is not the end of the statement, report an error.
5869
4
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5870
2
      reportParseError("unexpected token, expected end of statement");
5871
2
      return false;
5872
2
    }
5873
5874
2
    return false; // parseDirectiveModule has finished successfully.
5875
90
  } else if (Option == "nooddspreg") {
5876
0
    if (!isABI_O32()) {
5877
0
      Error(L, "'.module nooddspreg' requires the O32 ABI");
5878
0
      return false;
5879
0
    }
5880
5881
0
    setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5882
5883
    // Synchronize the abiflags information with the FeatureBits information we
5884
    // changed above.
5885
    //getTargetStreamer().updateABIInfo(*this);
5886
5887
    // If printing assembly, use the recently updated abiflags information.
5888
    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5889
    // emitted at the end).
5890
    //getTargetStreamer().emitDirectiveModuleOddSPReg();
5891
5892
    // If this is not the end of the statement, report an error.
5893
0
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5894
0
      reportParseError("unexpected token, expected end of statement");
5895
0
      return false;
5896
0
    }
5897
5898
0
    return false; // parseDirectiveModule has finished successfully.
5899
90
  } else if (Option == "fp") {
5900
5
    return parseDirectiveModuleFP();
5901
85
  } else if (Option == "softfloat") {
5902
0
    setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5903
5904
    // Synchronize the ABI Flags information with the FeatureBits information we
5905
    // updated above.
5906
    //getTargetStreamer().updateABIInfo(*this);
5907
5908
    // If printing assembly, use the recently updated ABI Flags information.
5909
    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5910
    // emitted later).
5911
    //getTargetStreamer().emitDirectiveModuleSoftFloat();
5912
5913
    // If this is not the end of the statement, report an error.
5914
0
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5915
0
      reportParseError("unexpected token, expected end of statement");
5916
0
      return false;
5917
0
    }
5918
5919
0
    return false; // parseDirectiveModule has finished successfully.
5920
85
  } else if (Option == "hardfloat") {
5921
0
    clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5922
5923
    // Synchronize the ABI Flags information with the FeatureBits information we
5924
    // updated above.
5925
    //getTargetStreamer().updateABIInfo(*this);
5926
5927
    // If printing assembly, use the recently updated ABI Flags information.
5928
    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5929
    // emitted later).
5930
    //getTargetStreamer().emitDirectiveModuleHardFloat();
5931
5932
    // If this is not the end of the statement, report an error.
5933
0
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5934
0
      reportParseError("unexpected token, expected end of statement");
5935
0
      return false;
5936
0
    }
5937
5938
0
    return false; // parseDirectiveModule has finished successfully.
5939
85
  } else {
5940
85
    return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5941
85
  }
5942
94
}
5943
5944
/// parseDirectiveModuleFP
5945
///  ::= =32
5946
///  ::= =xx
5947
///  ::= =64
5948
5
bool MipsAsmParser::parseDirectiveModuleFP() {
5949
5
  MCAsmParser &Parser = getParser();
5950
5
  MCAsmLexer &Lexer = getLexer();
5951
5952
5
  if (Lexer.isNot(AsmToken::Equal)) {
5953
5
    reportParseError("unexpected token, expected equals sign '='");
5954
5
    return false;
5955
5
  }
5956
0
  Parser.Lex(); // Eat '=' token.
5957
5958
0
  MipsABIFlagsSection::FpABIKind FpABI;
5959
0
  if (!parseFpABIValue(FpABI, ".module"))
5960
0
    return false;
5961
5962
0
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5963
0
    reportParseError("unexpected token, expected end of statement");
5964
0
    return false;
5965
0
  }
5966
5967
  // Synchronize the abiflags information with the FeatureBits information we
5968
  // changed above.
5969
  //getTargetStreamer().updateABIInfo(*this);
5970
5971
  // If printing assembly, use the recently updated abiflags information.
5972
  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5973
  // emitted at the end).
5974
  //getTargetStreamer().emitDirectiveModuleFP();
5975
5976
0
  Parser.Lex(); // Consume the EndOfStatement.
5977
0
  return false;
5978
0
}
5979
5980
bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5981
                                    StringRef Directive)
5982
781
{
5983
781
  MCAsmParser &Parser = getParser();
5984
781
  MCAsmLexer &Lexer = getLexer();
5985
781
  bool ModuleLevelOptions = Directive == ".module";
5986
5987
781
  if (Lexer.is(AsmToken::Identifier)) {
5988
366
    StringRef Value = Parser.getTok().getString();
5989
366
    Parser.Lex();
5990
5991
366
    if (Value != "xx") {
5992
250
      reportParseError("unsupported value, expected 'xx', '32' or '64'");
5993
250
      return false;
5994
250
    }
5995
5996
116
    if (!isABI_O32()) {
5997
0
      reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5998
0
      return false;
5999
0
    }
6000
6001
116
    FpABI = MipsABIFlagsSection::FpABIKind::XX;
6002
116
    if (ModuleLevelOptions) {
6003
0
      setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6004
0
      clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6005
116
    } else {
6006
116
      setFeatureBits(Mips::FeatureFPXX, "fpxx");
6007
116
      clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6008
116
    }
6009
116
    return true;
6010
116
  }
6011
6012
415
  if (Lexer.is(AsmToken::Integer)) {
6013
364
    bool valid;
6014
364
    unsigned Value = Parser.getTok().getIntVal(valid);
6015
364
    if (!valid)
6016
0
        return true;
6017
364
    Parser.Lex();
6018
6019
364
    if (Value != 32 && Value != 64) {
6020
318
      reportParseError("unsupported value, expected 'xx', '32' or '64'");
6021
318
      return false;
6022
318
    }
6023
6024
46
    if (Value == 32) {
6025
9
      if (!isABI_O32()) {
6026
3
        reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6027
3
        return false;
6028
3
      }
6029
6030
6
      FpABI = MipsABIFlagsSection::FpABIKind::S32;
6031
6
      if (ModuleLevelOptions) {
6032
0
        clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6033
0
        clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6034
6
      } else {
6035
6
        clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6036
6
        clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6037
6
      }
6038
37
    } else {
6039
37
      FpABI = MipsABIFlagsSection::FpABIKind::S64;
6040
37
      if (ModuleLevelOptions) {
6041
0
        clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6042
0
        setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6043
37
      } else {
6044
37
        clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6045
37
        setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6046
37
      }
6047
37
    }
6048
6049
43
    return true;
6050
46
  }
6051
6052
51
  return false;
6053
415
}
6054
6055
306k
bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6056
306k
  MCAsmParser &Parser = getParser();
6057
306k
  StringRef IDVal = DirectiveID.getString();
6058
6059
306k
  if (IDVal == ".cpload")
6060
230
    return parseDirectiveCpLoad(DirectiveID.getLoc());
6061
306k
  if (IDVal == ".cprestore")
6062
386
    return parseDirectiveCpRestore(DirectiveID.getLoc());
6063
306k
  if (IDVal == ".dword") {
6064
64
    parseDataDirective(8, DirectiveID.getLoc());
6065
64
    return false;
6066
64
  }
6067
306k
  if (IDVal == ".ent") {
6068
903
    StringRef SymbolName;
6069
6070
903
    if (Parser.parseIdentifier(SymbolName)) {
6071
727
      reportParseError("expected identifier after .ent");
6072
727
      return false;
6073
727
    }
6074
6075
    // There's an undocumented extension that allows an integer to
6076
    // follow the name of the procedure which AFAICS is ignored by GAS.
6077
    // Example: .ent foo,2
6078
176
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
6079
148
      if (getLexer().isNot(AsmToken::Comma)) {
6080
        // Even though we accept this undocumented extension for compatibility
6081
        // reasons, the additional integer argument does not actually change
6082
        // the behaviour of the '.ent' directive, so we would like to discourage
6083
        // its use. We do this by not referring to the extended version in
6084
        // error messages which are not directly related to its use.
6085
28
        reportParseError("unexpected token, expected end of statement");
6086
28
        return false;
6087
28
      }
6088
120
      Parser.Lex(); // Eat the comma.
6089
120
      const MCExpr *DummyNumber;
6090
120
      int64_t DummyNumberVal;
6091
      // If the user was explicitly trying to use the extended version,
6092
      // we still give helpful extension-related error messages.
6093
120
      if (Parser.parseExpression(DummyNumber)) {
6094
17
        reportParseError("expected number after comma");
6095
17
        return false;
6096
17
      }
6097
103
      if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6098
50
        reportParseError("expected an absolute expression after comma");
6099
50
        return false;
6100
50
      }
6101
103
    }
6102
6103
    // If this is not the end of the statement, report an error.
6104
81
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
6105
53
      reportParseError("unexpected token, expected end of statement");
6106
53
      return false;
6107
53
    }
6108
6109
28
    MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6110
6111
    //getTargetStreamer().emitDirectiveEnt(*Sym);
6112
28
    CurrentFn = Sym;
6113
28
    IsCpRestoreSet = false;
6114
28
    return false;
6115
81
  }
6116
6117
305k
  if (IDVal == ".end") {
6118
568
    StringRef SymbolName;
6119
6120
568
    if (Parser.parseIdentifier(SymbolName)) {
6121
466
      reportParseError("expected identifier after .end");
6122
466
      return false;
6123
466
    }
6124
6125
102
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
6126
47
      reportParseError("unexpected token, expected end of statement");
6127
47
      return false;
6128
47
    }
6129
6130
55
    if (CurrentFn == nullptr) {
6131
25
      reportParseError(".end used without .ent");
6132
25
      return false;
6133
25
    }
6134
6135
30
    if ((SymbolName != CurrentFn->getName())) {
6136
24
      reportParseError(".end symbol does not match .ent symbol");
6137
24
      return false;
6138
24
    }
6139
6140
    //getTargetStreamer().emitDirectiveEnd(SymbolName);
6141
6
    CurrentFn = nullptr;
6142
6
    IsCpRestoreSet = false;
6143
6
    return false;
6144
30
  }
6145
6146
304k
  if (IDVal == ".frame") {
6147
    // .frame $stack_reg, frame_size_in_bytes, $return_reg
6148
7.78k
    SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6149
7.78k
    OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6150
7.78k
    if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6151
3.91k
      reportParseError("expected stack register");
6152
3.91k
      return false;
6153
3.91k
    }
6154
6155
3.87k
    MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6156
3.87k
    if (!StackRegOpnd.isGPRAsmReg()) {
6157
99
      reportParseError(StackRegOpnd.getStartLoc(),
6158
99
                       "expected general purpose register");
6159
99
      return false;
6160
99
    }
6161
    //unsigned StackReg = StackRegOpnd.getGPR32Reg();
6162
6163
3.77k
    if (Parser.getTok().is(AsmToken::Comma))
6164
3.62k
      Parser.Lex();
6165
143
    else {
6166
143
      reportParseError("unexpected token, expected comma");
6167
143
      return false;
6168
143
    }
6169
6170
    // Parse the frame size.
6171
3.62k
    const MCExpr *FrameSize;
6172
3.62k
    int64_t FrameSizeVal;
6173
6174
3.62k
    if (Parser.parseExpression(FrameSize)) {
6175
228
      reportParseError("expected frame size value");
6176
228
      return false;
6177
228
    }
6178
6179
3.40k
    if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6180
105
      reportParseError("frame size not an absolute expression");
6181
105
      return false;
6182
105
    }
6183
6184
3.29k
    if (Parser.getTok().is(AsmToken::Comma))
6185
3.05k
      Parser.Lex();
6186
245
    else {
6187
245
      reportParseError("unexpected token, expected comma");
6188
245
      return false;
6189
245
    }
6190
6191
    // Parse the return register.
6192
3.05k
    TmpReg.clear();
6193
3.05k
    ResTy = parseAnyRegister(TmpReg);
6194
3.05k
    if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6195
3.02k
      reportParseError("expected return register");
6196
3.02k
      return false;
6197
3.02k
    }
6198
6199
29
    MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6200
29
    if (!ReturnRegOpnd.isGPRAsmReg()) {
6201
18
      reportParseError(ReturnRegOpnd.getStartLoc(),
6202
18
                       "expected general purpose register");
6203
18
      return false;
6204
18
    }
6205
6206
    // If this is not the end of the statement, report an error.
6207
11
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
6208
11
      reportParseError("unexpected token, expected end of statement");
6209
11
      return false;
6210
11
    }
6211
6212
    //getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6213
    //                              ReturnRegOpnd.getGPR32Reg());
6214
0
    IsCpRestoreSet = false;
6215
0
    return false;
6216
11
  }
6217
6218
296k
  if (IDVal == ".set") {
6219
36.0k
    return parseDirectiveSet();
6220
36.0k
  }
6221
6222
260k
  if (IDVal == ".mask" || IDVal == ".fmask") {
6223
    // .mask bitmask, frame_offset
6224
    // bitmask: One bit for each register used.
6225
    // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6226
    //               first register is expected to be saved.
6227
    // Examples:
6228
    //   .mask 0x80000000, -4
6229
    //   .fmask 0x80000000, -4
6230
    //
6231
6232
    // Parse the bitmask
6233
1.48k
    const MCExpr *BitMask;
6234
1.48k
    int64_t BitMaskVal;
6235
6236
1.48k
    if (Parser.parseExpression(BitMask)) {
6237
451
      reportParseError("expected bitmask value");
6238
451
      return false;
6239
451
    }
6240
6241
1.03k
    if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6242
246
      reportParseError("bitmask not an absolute expression");
6243
246
      return false;
6244
246
    }
6245
6246
787
    if (Parser.getTok().is(AsmToken::Comma))
6247
553
      Parser.Lex();
6248
234
    else {
6249
234
      reportParseError("unexpected token, expected comma");
6250
234
      return false;
6251
234
    }
6252
6253
    // Parse the frame_offset
6254
553
    const MCExpr *FrameOffset;
6255
553
    int64_t FrameOffsetVal;
6256
6257
553
    if (Parser.parseExpression(FrameOffset)) {
6258
354
      reportParseError("expected frame offset value");
6259
354
      return false;
6260
354
    }
6261
6262
199
    if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6263
98
      reportParseError("frame offset not an absolute expression");
6264
98
      return false;
6265
98
    }
6266
6267
    // If this is not the end of the statement, report an error.
6268
101
    if (getLexer().isNot(AsmToken::EndOfStatement)) {
6269
96
      reportParseError("unexpected token, expected end of statement");
6270
96
      return false;
6271
96
    }
6272
6273
#if 0
6274
    if (IDVal == ".mask")
6275
      getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6276
    else
6277
      getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6278
#endif
6279
5
    return false;
6280
101
  }
6281
6282
259k
  if (IDVal == ".nan")
6283
1.14k
    return parseDirectiveNaN();
6284
6285
258k
  if (IDVal == ".gpword") {
6286
493
    parseDirectiveGpWord();
6287
493
    return false;
6288
493
  }
6289
6290
257k
  if (IDVal == ".gpdword") {
6291
136
    parseDirectiveGpDWord();
6292
136
    return false;
6293
136
  }
6294
6295
257k
  if (IDVal == ".word") {
6296
19.1k
    parseDataDirective(4, DirectiveID.getLoc());
6297
19.1k
    return false;
6298
19.1k
  }
6299
6300
238k
  if (IDVal == ".option")
6301
661
    return parseDirectiveOption();
6302
6303
237k
  if (IDVal == ".abicalls") {
6304
    //getTargetStreamer().emitDirectiveAbiCalls();
6305
48
    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6306
12
      Error(Parser.getTok().getLoc(), 
6307
12
            "unexpected token, expected end of statement");
6308
      // Clear line
6309
12
      Parser.eatToEndOfStatement();
6310
12
    }
6311
48
    return false;
6312
48
  }
6313
6314
237k
  if (IDVal == ".cpsetup")
6315
3.10k
    return parseDirectiveCPSetup();
6316
6317
234k
  if (IDVal == ".cpreturn")
6318
4
    return parseDirectiveCPReturn();
6319
6320
234k
  if (IDVal == ".module")
6321
103
    return parseDirectiveModule();
6322
6323
234k
  if (IDVal == ".llvm_internal_mips_reallow_module_directive")
6324
0
    return parseInternalDirectiveReallowModule();
6325
6326
234k
  if (IDVal == ".insn")
6327
122
    return parseInsnDirective();
6328
6329
234k
  return true;
6330
234k
}
6331
6332
0
bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6333
  // If this is not the end of the statement, report an error.
6334
0
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6335
0
    reportParseError("unexpected token, expected end of statement");
6336
0
    return false;
6337
0
  }
6338
6339
  //getTargetStreamer().reallowModuleDirective();
6340
6341
0
  getParser().Lex(); // Eat EndOfStatement token.
6342
0
  return false;
6343
0
}
6344
6345
25
extern "C" void LLVMInitializeMipsAsmParser() {
6346
25
  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
6347
25
  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
6348
25
  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
6349
25
  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
6350
25
}
6351
6352
#define GET_REGISTER_MATCHER
6353
#define GET_MATCHER_IMPLEMENTATION
6354
#include "MipsGenAsmMatcher.inc"