Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "MCTargetDesc/MipsABIFlagsSection.h"
10
#include "MCTargetDesc/MipsABIInfo.h"
11
#include "MCTargetDesc/MipsBaseInfo.h"
12
#include "MCTargetDesc/MipsMCExpr.h"
13
#include "MCTargetDesc/MipsMCTargetDesc.h"
14
#include "MipsTargetStreamer.h"
15
#include "TargetInfo/MipsTargetInfo.h"
16
#include "llvm/ADT/APFloat.h"
17
#include "llvm/ADT/STLExtras.h"
18
#include "llvm/ADT/SmallVector.h"
19
#include "llvm/ADT/StringRef.h"
20
#include "llvm/ADT/StringSwitch.h"
21
#include "llvm/ADT/Triple.h"
22
#include "llvm/ADT/Twine.h"
23
#include "llvm/BinaryFormat/ELF.h"
24
#include "llvm/MC/MCContext.h"
25
#include "llvm/MC/MCExpr.h"
26
#include "llvm/MC/MCInst.h"
27
#include "llvm/MC/MCInstrDesc.h"
28
#include "llvm/MC/MCObjectFileInfo.h"
29
#include "llvm/MC/MCParser/MCAsmLexer.h"
30
#include "llvm/MC/MCParser/MCAsmParser.h"
31
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
32
#include "llvm/MC/MCParser/MCAsmParserUtils.h"
33
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
35
#include "llvm/MC/MCSectionELF.h"
36
#include "llvm/MC/MCStreamer.h"
37
#include "llvm/MC/MCSubtargetInfo.h"
38
#include "llvm/MC/MCSymbol.h"
39
#include "llvm/MC/MCSymbolELF.h"
40
#include "llvm/MC/MCValue.h"
41
#include "llvm/MC/SubtargetFeature.h"
42
#include "llvm/Support/Casting.h"
43
#include "llvm/Support/CommandLine.h"
44
#include "llvm/Support/Compiler.h"
45
#include "llvm/Support/Debug.h"
46
#include "llvm/Support/ErrorHandling.h"
47
#include "llvm/Support/MathExtras.h"
48
#include "llvm/Support/SMLoc.h"
49
#include "llvm/Support/SourceMgr.h"
50
#include "llvm/Support/TargetRegistry.h"
51
#include "llvm/Support/raw_ostream.h"
52
#include <algorithm>
53
#include <cassert>
54
#include <cstdint>
55
#include <memory>
56
#include <string>
57
#include <utility>
58
59
using namespace llvm;
60
61
#define DEBUG_TYPE "mips-asm-parser"
62
63
namespace llvm {
64
65
class MCInstrInfo;
66
67
} // end namespace llvm
68
69
extern cl::opt<bool> EmitJalrReloc;
70
71
namespace {
72
73
class MipsAssemblerOptions {
74
public:
75
2.93k
  MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
76
77
12
  MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
78
12
    ATReg = Opts->getATRegIndex();
79
12
    Reorder = Opts->isReorder();
80
12
    Macro = Opts->isMacro();
81
12
    Features = Opts->getFeatures();
82
12
  }
83
84
27.9k
  unsigned getATRegIndex() const { return ATReg; }
85
295
  bool setATRegIndex(unsigned Reg) {
86
295
    if (Reg > 31)
87
2
      return false;
88
293
89
293
    ATReg = Reg;
90
293
    return true;
91
293
  }
92
93
1.58k
  bool isReorder() const { return Reorder; }
94
82
  void setReorder() { Reorder = true; }
95
109
  void setNoReorder() { Reorder = false; }
96
97
2.99k
  bool isMacro() const { return Macro; }
98
31
  void setMacro() { Macro = true; }
99
37
  void setNoMacro() { Macro = false; }
100
101
72
  const FeatureBitset &getFeatures() const { return Features; }
102
419
  void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
103
104
  // Set of features that are either architecture features or referenced
105
  // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
106
  // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
107
  // The reason we need this mask is explained in the selectArch function.
108
  // FIXME: Ideally we would like TableGen to generate this information.
109
  static const FeatureBitset AllArchRelatedMask;
110
111
private:
112
  unsigned ATReg = 1;
113
  bool Reorder = true;
114
  bool Macro = true;
115
  FeatureBitset Features;
116
};
117
118
} // end anonymous namespace
119
120
const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
121
    Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
122
    Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
123
    Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
124
    Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
125
    Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
126
    Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
127
    Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
128
    Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
129
};
130
131
namespace {
132
133
class MipsAsmParser : public MCTargetAsmParser {
134
86.5k
  MipsTargetStreamer &getTargetStreamer() {
135
86.5k
    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
136
86.5k
    return static_cast<MipsTargetStreamer &>(TS);
137
86.5k
  }
138
139
  MipsABIInfo ABI;
140
  SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
141
  MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
142
                       // nullptr, which indicates that no function is currently
143
                       // selected. This usually happens after an '.end func'
144
                       // directive.
145
  bool IsLittleEndian;
146
  bool IsPicEnabled;
147
  bool IsCpRestoreSet;
148
  int CpRestoreOffset;
149
  unsigned GPReg;
150
  unsigned CpSaveLocation;
151
  /// If true, then CpSaveLocation is a register, otherwise it's an offset.
152
  bool     CpSaveLocationIsRegister;
153
154
  // Map of register aliases created via the .set directive.
155
  StringMap<AsmToken> RegisterSets;
156
157
  // Print a warning along with its fix-it message at the given range.
158
  void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
159
                             SMRange Range, bool ShowColors = true);
160
161
  void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
162
163
#define GET_ASSEMBLER_HEADER
164
#include "MipsGenAsmMatcher.inc"
165
166
  unsigned
167
  checkEarlyTargetMatchPredicate(MCInst &Inst,
168
                                 const OperandVector &Operands) override;
169
  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
170
171
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
172
                               OperandVector &Operands, MCStreamer &Out,
173
                               uint64_t &ErrorInfo,
174
                               bool MatchingInlineAsm) override;
175
176
  /// Parse a register as used in CFI directives
177
  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
178
179
  bool parseParenSuffix(StringRef Name, OperandVector &Operands);
180
181
  bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
182
183
  bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
184
185
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
186
                        SMLoc NameLoc, OperandVector &Operands) override;
187
188
  bool ParseDirective(AsmToken DirectiveID) override;
189
190
  OperandMatchResultTy parseMemOperand(OperandVector &Operands);
191
  OperandMatchResultTy
192
  matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
193
                                    StringRef Identifier, SMLoc S);
194
  OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
195
                                                     const AsmToken &Token,
196
                                                     SMLoc S);
197
  OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
198
                                                     SMLoc S);
199
  OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
200
  OperandMatchResultTy parseImm(OperandVector &Operands);
201
  OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
202
  OperandMatchResultTy parseInvNum(OperandVector &Operands);
203
  OperandMatchResultTy parseRegisterList(OperandVector &Operands);
204
205
  bool searchSymbolAlias(OperandVector &Operands);
206
207
  bool parseOperand(OperandVector &, StringRef Mnemonic);
208
209
  enum MacroExpanderResultTy {
210
    MER_NotAMacro,
211
    MER_Success,
212
    MER_Fail,
213
  };
214
215
  // Expands assembly pseudo instructions.
216
  MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
217
                                             MCStreamer &Out,
218
                                             const MCSubtargetInfo *STI);
219
220
  bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
221
                         const MCSubtargetInfo *STI);
222
223
  bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
224
                     bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
225
                     MCStreamer &Out, const MCSubtargetInfo *STI);
226
227
  bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
228
                               unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
229
                               MCStreamer &Out, const MCSubtargetInfo *STI);
230
231
  bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
232
233
  bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
234
                     MCStreamer &Out, const MCSubtargetInfo *STI);
235
236
  bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
237
                         SMLoc IDLoc, MCStreamer &Out,
238
                         const MCSubtargetInfo *STI);
239
240
  bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
241
                         const MCOperand &Offset, bool Is32BitAddress,
242
                         SMLoc IDLoc, MCStreamer &Out,
243
                         const MCSubtargetInfo *STI);
244
245
  bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246
                                  const MCSubtargetInfo *STI);
247
248
  void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
249
                     const MCSubtargetInfo *STI, bool IsLoad);
250
251
  bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
252
                               const MCSubtargetInfo *STI);
253
254
  bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
255
                            const MCSubtargetInfo *STI);
256
257
  bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258
                       const MCSubtargetInfo *STI);
259
260
  bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261
                          const MCSubtargetInfo *STI);
262
263
  bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264
                    const MCSubtargetInfo *STI, const bool IsMips64,
265
                    const bool Signed);
266
267
  bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
268
                   MCStreamer &Out, const MCSubtargetInfo *STI);
269
270
  bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
271
                 const MCSubtargetInfo *STI);
272
273
  bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
274
                 const MCSubtargetInfo *STI);
275
276
  bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277
                 const MCSubtargetInfo *STI);
278
279
  bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280
                 const MCSubtargetInfo *STI);
281
282
  bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
283
                    const MCSubtargetInfo *STI);
284
285
  bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286
                    const MCSubtargetInfo *STI);
287
288
  bool expandRotation(MCInst &Inst, SMLoc IDLoc,
289
                      MCStreamer &Out, const MCSubtargetInfo *STI);
290
  bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291
                         const MCSubtargetInfo *STI);
292
  bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293
                       const MCSubtargetInfo *STI);
294
  bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295
                          const MCSubtargetInfo *STI);
296
297
  bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298
                 const MCSubtargetInfo *STI);
299
300
  bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301
                    const MCSubtargetInfo *STI);
302
303
  bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304
                  const MCSubtargetInfo *STI);
305
306
  bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
307
                   const MCSubtargetInfo *STI);
308
309
  bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310
                       const MCSubtargetInfo *STI);
311
312
  bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313
                             const MCSubtargetInfo *STI, bool IsLoad);
314
315
  bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316
                           const MCSubtargetInfo *STI);
317
318
  bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319
                 const MCSubtargetInfo *STI);
320
321
  bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322
                  const MCSubtargetInfo *STI);
323
324
  bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325
                       const MCSubtargetInfo *STI);
326
327
  bool reportParseError(Twine ErrorMsg);
328
  bool reportParseError(SMLoc Loc, Twine ErrorMsg);
329
330
  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
331
332
  bool isEvaluated(const MCExpr *Expr);
333
  bool parseSetMips0Directive();
334
  bool parseSetArchDirective();
335
  bool parseSetFeature(uint64_t Feature);
336
  bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
337
  bool parseDirectiveCpLoad(SMLoc Loc);
338
  bool parseDirectiveCpLocal(SMLoc Loc);
339
  bool parseDirectiveCpRestore(SMLoc Loc);
340
  bool parseDirectiveCPSetup();
341
  bool parseDirectiveCPReturn();
342
  bool parseDirectiveNaN();
343
  bool parseDirectiveSet();
344
  bool parseDirectiveOption();
345
  bool parseInsnDirective();
346
  bool parseRSectionDirective(StringRef Section);
347
  bool parseSSectionDirective(StringRef Section, unsigned Type);
348
349
  bool parseSetAtDirective();
350
  bool parseSetNoAtDirective();
351
  bool parseSetMacroDirective();
352
  bool parseSetNoMacroDirective();
353
  bool parseSetMsaDirective();
354
  bool parseSetNoMsaDirective();
355
  bool parseSetNoDspDirective();
356
  bool parseSetReorderDirective();
357
  bool parseSetNoReorderDirective();
358
  bool parseSetMips16Directive();
359
  bool parseSetNoMips16Directive();
360
  bool parseSetFpDirective();
361
  bool parseSetOddSPRegDirective();
362
  bool parseSetNoOddSPRegDirective();
363
  bool parseSetPopDirective();
364
  bool parseSetPushDirective();
365
  bool parseSetSoftFloatDirective();
366
  bool parseSetHardFloatDirective();
367
  bool parseSetMtDirective();
368
  bool parseSetNoMtDirective();
369
  bool parseSetNoCRCDirective();
370
  bool parseSetNoVirtDirective();
371
  bool parseSetNoGINVDirective();
372
373
  bool parseSetAssignment();
374
375
  bool parseDirectiveGpWord();
376
  bool parseDirectiveGpDWord();
377
  bool parseDirectiveDtpRelWord();
378
  bool parseDirectiveDtpRelDWord();
379
  bool parseDirectiveTpRelWord();
380
  bool parseDirectiveTpRelDWord();
381
  bool parseDirectiveModule();
382
  bool parseDirectiveModuleFP();
383
  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
384
                       StringRef Directive);
385
386
  bool parseInternalDirectiveReallowModule();
387
388
  bool eatComma(StringRef ErrorStr);
389
390
  int matchCPURegisterName(StringRef Symbol);
391
392
  int matchHWRegsRegisterName(StringRef Symbol);
393
394
  int matchFPURegisterName(StringRef Name);
395
396
  int matchFCCRegisterName(StringRef Name);
397
398
  int matchACRegisterName(StringRef Name);
399
400
  int matchMSA128RegisterName(StringRef Name);
401
402
  int matchMSA128CtrlRegisterName(StringRef Name);
403
404
  unsigned getReg(int RC, int RegNo);
405
406
  /// Returns the internal register number for the current AT. Also checks if
407
  /// the current AT is unavailable (set to $0) and gives an error if it is.
408
  /// This should be used in pseudo-instruction expansions which need AT.
409
  unsigned getATReg(SMLoc Loc);
410
411
  bool canUseATReg();
412
413
  bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
414
                          const MCSubtargetInfo *STI);
415
416
  // Helper function that checks if the value of a vector index is within the
417
  // boundaries of accepted values for each RegisterKind
418
  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
419
  bool validateMSAIndex(int Val, int RegKind);
420
421
  // Selects a new architecture by updating the FeatureBits with the necessary
422
  // info including implied dependencies.
423
  // Internally, it clears all the feature bits related to *any* architecture
424
  // and selects the new one using the ToggleFeature functionality of the
425
  // MCSubtargetInfo object that handles implied dependencies. The reason we
426
  // clear all the arch related bits manually is because ToggleFeature only
427
  // clears the features that imply the feature being cleared and not the
428
  // features implied by the feature being cleared. This is easier to see
429
  // with an example:
430
  //  --------------------------------------------------
431
  // | Feature         | Implies                        |
432
  // | -------------------------------------------------|
433
  // | FeatureMips1    | None                           |
434
  // | FeatureMips2    | FeatureMips1                   |
435
  // | FeatureMips3    | FeatureMips2 | FeatureMipsGP64 |
436
  // | FeatureMips4    | FeatureMips3                   |
437
  // | ...             |                                |
438
  //  --------------------------------------------------
439
  //
440
  // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
441
  // FeatureMipsGP64 | FeatureMips1)
442
  // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
443
114
  void selectArch(StringRef ArchFeature) {
444
114
    MCSubtargetInfo &STI = copySTI();
445
114
    FeatureBitset FeatureBits = STI.getFeatureBits();
446
114
    FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
447
114
    STI.setFeatureBits(FeatureBits);
448
114
    setAvailableFeatures(
449
114
        ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
450
114
    AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
451
114
  }
452
453
130
  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
454
130
    if (!(getSTI().getFeatureBits()[Feature])) {
455
88
      MCSubtargetInfo &STI = copySTI();
456
88
      setAvailableFeatures(
457
88
          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
458
88
      AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
459
88
    }
460
130
  }
461
462
225
  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
463
225
    if (getSTI().getFeatureBits()[Feature]) {
464
62
      MCSubtargetInfo &STI = copySTI();
465
62
      setAvailableFeatures(
466
62
          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
467
62
      AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
468
62
    }
469
225
  }
470
471
30
  void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
472
30
    setFeatureBits(Feature, FeatureString);
473
30
    AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
474
30
  }
475
476
113
  void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
477
113
    clearFeatureBits(Feature, FeatureString);
478
113
    AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
479
113
  }
480
481
public:
482
  enum MipsMatchResultTy {
483
    Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
484
    Match_RequiresDifferentOperands,
485
    Match_RequiresNoZeroRegister,
486
    Match_RequiresSameSrcAndDst,
487
    Match_NoFCCRegisterForCurrentISA,
488
    Match_NonZeroOperandForSync,
489
    Match_NonZeroOperandForMTCX,
490
    Match_RequiresPosSizeRange0_32,
491
    Match_RequiresPosSizeRange33_64,
492
    Match_RequiresPosSizeUImm6,
493
#define GET_OPERAND_DIAGNOSTIC_TYPES
494
#include "MipsGenAsmMatcher.inc"
495
#undef GET_OPERAND_DIAGNOSTIC_TYPES
496
  };
497
498
  MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
499
                const MCInstrInfo &MII, const MCTargetOptions &Options)
500
    : MCTargetAsmParser(Options, sti, MII),
501
        ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
502
1.46k
                                          sti.getCPU(), Options)) {
503
1.46k
    MCAsmParserExtension::Initialize(parser);
504
1.46k
505
1.46k
    parser.addAliasForDirective(".asciiz", ".asciz");
506
1.46k
    parser.addAliasForDirective(".hword", ".2byte");
507
1.46k
    parser.addAliasForDirective(".word", ".4byte");
508
1.46k
    parser.addAliasForDirective(".dword", ".8byte");
509
1.46k
510
1.46k
    // Initialize the set of available features.
511
1.46k
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
512
1.46k
513
1.46k
    // Remember the initial assembler options. The user can not modify these.
514
1.46k
    AssemblerOptions.push_back(
515
1.46k
        llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
516
1.46k
517
1.46k
    // Create an assembler options environment for the user to modify.
518
1.46k
    AssemblerOptions.push_back(
519
1.46k
        llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
520
1.46k
521
1.46k
    getTargetStreamer().updateABIInfo(*this);
522
1.46k
523
1.46k
    if (!isABI_O32() && 
!useOddSPReg() != 0501
)
524
2
      report_fatal_error("-mno-odd-spreg requires the O32 ABI");
525
1.46k
526
1.46k
    CurrentFn = nullptr;
527
1.46k
528
1.46k
    IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
529
1.46k
530
1.46k
    IsCpRestoreSet = false;
531
1.46k
    CpRestoreOffset = -1;
532
1.46k
    GPReg = ABI.GetGlobalPtr();
533
1.46k
534
1.46k
    const Triple &TheTriple = sti.getTargetTriple();
535
1.46k
    IsLittleEndian = TheTriple.isLittleEndian();
536
1.46k
537
1.46k
    if (getSTI().getCPU() == "mips64r6" && 
inMicroMipsMode()60
)
538
3
      report_fatal_error("microMIPS64R6 is not supported", false);
539
1.46k
540
1.46k
    if (!isABI_O32() && 
inMicroMipsMode()496
)
541
2
      report_fatal_error("microMIPS64 is not supported", false);
542
1.46k
  }
543
544
  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
545
562
  bool hasEightFccRegisters() const { return hasMips4() || 
hasMips32()370
; }
546
547
7.37k
  bool isGP64bit() const {
548
7.37k
    return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
549
7.37k
  }
550
551
6.57k
  bool isFP64bit() const {
552
6.57k
    return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
553
6.57k
  }
554
555
16.7k
  const MipsABIInfo &getABI() const { return ABI; }
556
20.9k
  bool isABI_N32() const { return ABI.IsN32(); }
557
20.3k
  bool isABI_N64() const { return ABI.IsN64(); }
558
9.87k
  bool isABI_O32() const { return ABI.IsO32(); }
559
3.06k
  bool isABI_FPXX() const {
560
3.06k
    return getSTI().getFeatureBits()[Mips::FeatureFPXX];
561
3.06k
  }
562
563
6.76k
  bool useOddSPReg() const {
564
6.76k
    return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
565
6.76k
  }
566
567
76.3k
  bool inMicroMipsMode() const {
568
76.3k
    return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
569
76.3k
  }
570
571
51
  bool hasMips1() const {
572
51
    return getSTI().getFeatureBits()[Mips::FeatureMips1];
573
51
  }
574
575
68
  bool hasMips2() const {
576
68
    return getSTI().getFeatureBits()[Mips::FeatureMips2];
577
68
  }
578
579
613
  bool hasMips3() const {
580
613
    return getSTI().getFeatureBits()[Mips::FeatureMips3];
581
613
  }
582
583
643
  bool hasMips4() const {
584
643
    return getSTI().getFeatureBits()[Mips::FeatureMips4];
585
643
  }
586
587
95
  bool hasMips5() const {
588
95
    return getSTI().getFeatureBits()[Mips::FeatureMips5];
589
95
  }
590
591
3.62k
  bool hasMips32() const {
592
3.62k
    return getSTI().getFeatureBits()[Mips::FeatureMips32];
593
3.62k
  }
594
595
3.67k
  bool hasMips64() const {
596
3.67k
    return getSTI().getFeatureBits()[Mips::FeatureMips64];
597
3.67k
  }
598
599
2.30k
  bool hasMips32r2() const {
600
2.30k
    return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
601
2.30k
  }
602
603
540
  bool hasMips64r2() const {
604
540
    return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
605
540
  }
606
607
2.16k
  bool hasMips32r3() const {
608
2.16k
    return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
609
2.16k
  }
610
611
415
  bool hasMips64r3() const {
612
415
    return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
613
415
  }
614
615
2.21k
  bool hasMips32r5() const {
616
2.21k
    return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
617
2.21k
  }
618
619
445
  bool hasMips64r5() const {
620
445
    return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
621
445
  }
622
623
38.9k
  bool hasMips32r6() const {
624
38.9k
    return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
625
38.9k
  }
626
627
816
  bool hasMips64r6() const {
628
816
    return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
629
816
  }
630
631
3.64k
  bool hasDSP() const {
632
3.64k
    return getSTI().getFeatureBits()[Mips::FeatureDSP];
633
3.64k
  }
634
635
3.64k
  bool hasDSPR2() const {
636
3.64k
    return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
637
3.64k
  }
638
639
0
  bool hasDSPR3() const {
640
0
    return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
641
0
  }
642
643
7.23k
  bool hasMSA() const {
644
7.23k
    return getSTI().getFeatureBits()[Mips::FeatureMSA];
645
7.23k
  }
646
647
39.3k
  bool hasCnMips() const {
648
39.3k
    return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
649
39.3k
  }
650
651
674
  bool inPicMode() {
652
674
    return IsPicEnabled;
653
674
  }
654
655
3.71k
  bool inMips16Mode() const {
656
3.71k
    return getSTI().getFeatureBits()[Mips::FeatureMips16];
657
3.71k
  }
658
659
510
  bool useTraps() const {
660
510
    return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
661
510
  }
662
663
7.28k
  bool useSoftFloat() const {
664
7.28k
    return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
665
7.28k
  }
666
3.64k
  bool hasMT() const {
667
3.64k
    return getSTI().getFeatureBits()[Mips::FeatureMT];
668
3.64k
  }
669
670
3.64k
  bool hasCRC() const {
671
3.64k
    return getSTI().getFeatureBits()[Mips::FeatureCRC];
672
3.64k
  }
673
674
3.64k
  bool hasVirt() const {
675
3.64k
    return getSTI().getFeatureBits()[Mips::FeatureVirt];
676
3.64k
  }
677
678
3.64k
  bool hasGINV() const {
679
3.64k
    return getSTI().getFeatureBits()[Mips::FeatureGINV];
680
3.64k
  }
681
682
  /// Warn if RegIndex is the same as the current AT.
683
  void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
684
685
  void warnIfNoMacro(SMLoc Loc);
686
687
247
  bool isLittle() const { return IsLittleEndian; }
688
689
  const MCExpr *createTargetUnaryExpr(const MCExpr *E,
690
                                      AsmToken::TokenKind OperatorToken,
691
11.1k
                                      MCContext &Ctx) override {
692
11.1k
    switch(OperatorToken) {
693
11.1k
    default:
694
0
      llvm_unreachable("Unknown token");
695
11.1k
      
return nullptr0
;
696
11.1k
    case AsmToken::PercentCall16:
697
10.0k
      return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
698
11.1k
    case AsmToken::PercentCall_Hi:
699
8
      return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
700
11.1k
    case AsmToken::PercentCall_Lo:
701
8
      return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
702
11.1k
    case AsmToken::PercentDtprel_Hi:
703
10
      return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
704
11.1k
    case AsmToken::PercentDtprel_Lo:
705
11
      return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
706
11.1k
    case AsmToken::PercentGot:
707
101
      return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
708
11.1k
    case AsmToken::PercentGot_Disp:
709
21
      return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
710
11.1k
    case AsmToken::PercentGot_Hi:
711
10
      return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
712
11.1k
    case AsmToken::PercentGot_Lo:
713
10
      return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
714
11.1k
    case AsmToken::PercentGot_Ofst:
715
26
      return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
716
11.1k
    case AsmToken::PercentGot_Page:
717
36
      return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
718
11.1k
    case AsmToken::PercentGottprel:
719
19
      return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
720
11.1k
    case AsmToken::PercentGp_Rel:
721
76
      return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
722
11.1k
    case AsmToken::PercentHi:
723
141
      return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
724
11.1k
    case AsmToken::PercentHigher:
725
18
      return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
726
11.1k
    case AsmToken::PercentHighest:
727
18
      return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
728
11.1k
    case AsmToken::PercentLo:
729
473
      return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
730
11.1k
    case AsmToken::PercentNeg:
731
64
      return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
732
11.1k
    case AsmToken::PercentPcrel_Hi:
733
13
      return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
734
11.1k
    case AsmToken::PercentPcrel_Lo:
735
13
      return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
736
11.1k
    case AsmToken::PercentTlsgd:
737
18
      return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
738
11.1k
    case AsmToken::PercentTlsldm:
739
11
      return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
740
11.1k
    case AsmToken::PercentTprel_Hi:
741
9
      return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
742
11.1k
    case AsmToken::PercentTprel_Lo:
743
9
      return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
744
11.1k
    }
745
11.1k
  }
746
};
747
748
/// MipsOperand - Instances of this class represent a parsed Mips machine
749
/// instruction.
750
class MipsOperand : public MCParsedAsmOperand {
751
public:
752
  /// Broad categories of register classes
753
  /// The exact class is finalized by the render method.
754
  enum RegKind {
755
    RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
756
    RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context and
757
                          /// isFP64bit())
758
    RegKind_FCC = 4,      /// FCC
759
    RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
760
    RegKind_MSACtrl = 16, /// MSA control registers
761
    RegKind_COP2 = 32,    /// COP2
762
    RegKind_ACC = 64,     /// HI32DSP, LO32DSP, and ACC64DSP (depending on
763
                          /// context).
764
    RegKind_CCR = 128,    /// CCR
765
    RegKind_HWRegs = 256, /// HWRegs
766
    RegKind_COP3 = 512,   /// COP3
767
    RegKind_COP0 = 1024,  /// COP0
768
    /// Potentially any (e.g. $1)
769
    RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
770
                      RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
771
                      RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
772
  };
773
774
private:
775
  enum KindTy {
776
    k_Immediate,     /// An immediate (possibly involving symbol references)
777
    k_Memory,        /// Base + Offset Memory Address
778
    k_RegisterIndex, /// A register index in one or more RegKind.
779
    k_Token,         /// A simple token
780
    k_RegList,       /// A physical register list
781
  } Kind;
782
783
public:
784
  MipsOperand(KindTy K, MipsAsmParser &Parser)
785
123k
      : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
786
787
123k
  ~MipsOperand() override {
788
123k
    switch (Kind) {
789
123k
    case k_Memory:
790
13.2k
      delete Mem.Base;
791
13.2k
      break;
792
123k
    case k_RegList:
793
76
      delete RegList.List;
794
76
      break;
795
123k
    case k_Immediate:
796
110k
    case k_RegisterIndex:
797
110k
    case k_Token:
798
110k
      break;
799
123k
    }
800
123k
  }
801
802
private:
803
  /// For diagnostics, and checking the assembler temporary
804
  MipsAsmParser &AsmParser;
805
806
  struct Token {
807
    const char *Data;
808
    unsigned Length;
809
  };
810
811
  struct RegIdxOp {
812
    unsigned Index; /// Index into the register class
813
    RegKind Kind;   /// Bitfield of the kinds it could possibly be
814
    struct Token Tok; /// The input token this operand originated from.
815
    const MCRegisterInfo *RegInfo;
816
  };
817
818
  struct ImmOp {
819
    const MCExpr *Val;
820
  };
821
822
  struct MemOp {
823
    MipsOperand *Base;
824
    const MCExpr *Off;
825
  };
826
827
  struct RegListOp {
828
    SmallVector<unsigned, 10> *List;
829
  };
830
831
  union {
832
    struct Token Tok;
833
    struct RegIdxOp RegIdx;
834
    struct ImmOp Imm;
835
    struct MemOp Mem;
836
    struct RegListOp RegList;
837
  };
838
839
  SMLoc StartLoc, EndLoc;
840
841
  /// Internal constructor for register kinds
842
  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
843
                                                RegKind RegKind,
844
                                                const MCRegisterInfo *RegInfo,
845
                                                SMLoc S, SMLoc E,
846
57.7k
                                                MipsAsmParser &Parser) {
847
57.7k
    auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
848
57.7k
    Op->RegIdx.Index = Index;
849
57.7k
    Op->RegIdx.RegInfo = RegInfo;
850
57.7k
    Op->RegIdx.Kind = RegKind;
851
57.7k
    Op->RegIdx.Tok.Data = Str.data();
852
57.7k
    Op->RegIdx.Tok.Length = Str.size();
853
57.7k
    Op->StartLoc = S;
854
57.7k
    Op->EndLoc = E;
855
57.7k
    return Op;
856
57.7k
  }
857
858
public:
859
  /// Coerce the register to GPR32 and return the real register for the current
860
  /// target.
861
27.3k
  unsigned getGPR32Reg() const {
862
27.3k
    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
863
27.3k
    AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
864
27.3k
    unsigned ClassID = Mips::GPR32RegClassID;
865
27.3k
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
866
27.3k
  }
867
868
  /// Coerce the register to GPR32 and return the real register for the current
869
  /// target.
870
274
  unsigned getGPRMM16Reg() const {
871
274
    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
872
274
    unsigned ClassID = Mips::GPR32RegClassID;
873
274
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
874
274
  }
875
876
  /// Coerce the register to GPR64 and return the real register for the current
877
  /// target.
878
14.6k
  unsigned getGPR64Reg() const {
879
14.6k
    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
880
14.6k
    unsigned ClassID = Mips::GPR64RegClassID;
881
14.6k
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
882
14.6k
  }
883
884
private:
885
  /// Coerce the register to AFGR64 and return the real register for the current
886
  /// target.
887
965
  unsigned getAFGR64Reg() const {
888
965
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
889
965
    if (RegIdx.Index % 2 != 0)
890
69
      AsmParser.Warning(StartLoc, "Float register should be even.");
891
965
    return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
892
965
        .getRegister(RegIdx.Index / 2);
893
965
  }
894
895
  /// Coerce the register to FGR64 and return the real register for the current
896
  /// target.
897
1.36k
  unsigned getFGR64Reg() const {
898
1.36k
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
899
1.36k
    return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
900
1.36k
        .getRegister(RegIdx.Index);
901
1.36k
  }
902
903
  /// Coerce the register to FGR32 and return the real register for the current
904
  /// target.
905
2.62k
  unsigned getFGR32Reg() const {
906
2.62k
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
907
2.62k
    return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
908
2.62k
        .getRegister(RegIdx.Index);
909
2.62k
  }
910
911
  /// Coerce the register to FCC and return the real register for the current
912
  /// target.
913
734
  unsigned getFCCReg() const {
914
734
    assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
915
734
    return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
916
734
        .getRegister(RegIdx.Index);
917
734
  }
918
919
  /// Coerce the register to MSA128 and return the real register for the current
920
  /// target.
921
1.40k
  unsigned getMSA128Reg() const {
922
1.40k
    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
923
1.40k
    // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
924
1.40k
    // identical
925
1.40k
    unsigned ClassID = Mips::MSA128BRegClassID;
926
1.40k
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
927
1.40k
  }
928
929
  /// Coerce the register to MSACtrl and return the real register for the
930
  /// current target.
931
32
  unsigned getMSACtrlReg() const {
932
32
    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
933
32
    unsigned ClassID = Mips::MSACtrlRegClassID;
934
32
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
935
32
  }
936
937
  /// Coerce the register to COP0 and return the real register for the
938
  /// current target.
939
116
  unsigned getCOP0Reg() const {
940
116
    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
941
116
    unsigned ClassID = Mips::COP0RegClassID;
942
116
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
943
116
  }
944
945
  /// Coerce the register to COP2 and return the real register for the
946
  /// current target.
947
122
  unsigned getCOP2Reg() const {
948
122
    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
949
122
    unsigned ClassID = Mips::COP2RegClassID;
950
122
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
951
122
  }
952
953
  /// Coerce the register to COP3 and return the real register for the
954
  /// current target.
955
6
  unsigned getCOP3Reg() const {
956
6
    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
957
6
    unsigned ClassID = Mips::COP3RegClassID;
958
6
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
959
6
  }
960
961
  /// Coerce the register to ACC64DSP and return the real register for the
962
  /// current target.
963
180
  unsigned getACC64DSPReg() const {
964
180
    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
965
180
    unsigned ClassID = Mips::ACC64DSPRegClassID;
966
180
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
967
180
  }
968
969
  /// Coerce the register to HI32DSP and return the real register for the
970
  /// current target.
971
3
  unsigned getHI32DSPReg() const {
972
3
    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
973
3
    unsigned ClassID = Mips::HI32DSPRegClassID;
974
3
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
975
3
  }
976
977
  /// Coerce the register to LO32DSP and return the real register for the
978
  /// current target.
979
3
  unsigned getLO32DSPReg() const {
980
3
    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
981
3
    unsigned ClassID = Mips::LO32DSPRegClassID;
982
3
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
983
3
  }
984
985
  /// Coerce the register to CCR and return the real register for the
986
  /// current target.
987
38
  unsigned getCCRReg() const {
988
38
    assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
989
38
    unsigned ClassID = Mips::CCRRegClassID;
990
38
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
991
38
  }
992
993
  /// Coerce the register to HWRegs and return the real register for the
994
  /// current target.
995
60
  unsigned getHWRegsReg() const {
996
60
    assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
997
60
    unsigned ClassID = Mips::HWRegsRegClassID;
998
60
    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
999
60
  }
1000
1001
public:
1002
16.9k
  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1003
16.9k
    // Add as immediate when possible.  Null MCExpr = 0.
1004
16.9k
    if (!Expr)
1005
0
      Inst.addOperand(MCOperand::createImm(0));
1006
16.9k
    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1007
4.97k
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
1008
11.9k
    else
1009
11.9k
      Inst.addOperand(MCOperand::createExpr(Expr));
1010
16.9k
  }
1011
1012
0
  void addRegOperands(MCInst &Inst, unsigned N) const {
1013
0
    llvm_unreachable("Use a custom parser instead");
1014
0
  }
1015
1016
  /// Render the operand to an MCInst as a GPR32
1017
  /// Asserts if the wrong number of operands are requested, or the operand
1018
  /// is not a k_RegisterIndex compatible with RegKind_GPR
1019
30
  void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1020
30
    assert(N == 1 && "Invalid number of operands!");
1021
30
    Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1022
30
  }
1023
1024
50
  void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1025
50
    assert(N == 1 && "Invalid number of operands!");
1026
50
    Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1027
50
  }
1028
1029
24.2k
  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1030
24.2k
    assert(N == 1 && "Invalid number of operands!");
1031
24.2k
    Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1032
24.2k
  }
1033
1034
178
  void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1035
178
    assert(N == 1 && "Invalid number of operands!");
1036
178
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1037
178
  }
1038
1039
22
  void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1040
22
    assert(N == 1 && "Invalid number of operands!");
1041
22
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1042
22
  }
1043
1044
12
  void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1045
12
    assert(N == 1 && "Invalid number of operands!");
1046
12
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1047
12
  }
1048
1049
6
  void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1050
6
    assert(N == 1 && "Invalid number of operands!");
1051
6
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1052
6
  }
1053
1054
  void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1055
6
                                               unsigned N) const {
1056
6
    assert(N == 1 && "Invalid number of operands!");
1057
6
    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1058
6
  }
1059
1060
  /// Render the operand to an MCInst as a GPR64
1061
  /// Asserts if the wrong number of operands are requested, or the operand
1062
  /// is not a k_RegisterIndex compatible with RegKind_GPR
1063
3.99k
  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1064
3.99k
    assert(N == 1 && "Invalid number of operands!");
1065
3.99k
    Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1066
3.99k
  }
1067
1068
926
  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1069
926
    assert(N == 1 && "Invalid number of operands!");
1070
926
    Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1071
926
  }
1072
1073
39
  void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1074
39
    assert(N == 1 && "Invalid number of operands!");
1075
39
    Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1076
39
  }
1077
1078
52
  void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1079
52
    assert(N == 1 && "Invalid number of operands!");
1080
52
    Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1081
52
  }
1082
1083
1.31k
  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1084
1.31k
    assert(N == 1 && "Invalid number of operands!");
1085
1.31k
    Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1086
1.31k
  }
1087
1088
2.55k
  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1089
2.55k
    assert(N == 1 && "Invalid number of operands!");
1090
2.55k
    Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1091
2.55k
    // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1092
2.55k
    // FIXME: This should propagate failure up to parseStatement.
1093
2.55k
    if (!AsmParser.useOddSPReg() && 
RegIdx.Index & 112
)
1094
5
      AsmParser.getParser().printError(
1095
5
          StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1096
5
                    "registers");
1097
2.55k
  }
1098
1099
66
  void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1100
66
    assert(N == 1 && "Invalid number of operands!");
1101
66
    Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1102
66
    // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1103
66
    if (!AsmParser.useOddSPReg() && 
RegIdx.Index & 10
)
1104
0
      AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1105
0
                                "registers");
1106
66
  }
1107
1108
734
  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1109
734
    assert(N == 1 && "Invalid number of operands!");
1110
734
    Inst.addOperand(MCOperand::createReg(getFCCReg()));
1111
734
  }
1112
1113
1.40k
  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1114
1.40k
    assert(N == 1 && "Invalid number of operands!");
1115
1.40k
    Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1116
1.40k
  }
1117
1118
32
  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1119
32
    assert(N == 1 && "Invalid number of operands!");
1120
32
    Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1121
32
  }
1122
1123
116
  void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1124
116
    assert(N == 1 && "Invalid number of operands!");
1125
116
    Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1126
116
  }
1127
1128
122
  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1129
122
    assert(N == 1 && "Invalid number of operands!");
1130
122
    Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1131
122
  }
1132
1133
6
  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1134
6
    assert(N == 1 && "Invalid number of operands!");
1135
6
    Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1136
6
  }
1137
1138
180
  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1139
180
    assert(N == 1 && "Invalid number of operands!");
1140
180
    Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1141
180
  }
1142
1143
3
  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1144
3
    assert(N == 1 && "Invalid number of operands!");
1145
3
    Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1146
3
  }
1147
1148
3
  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1149
3
    assert(N == 1 && "Invalid number of operands!");
1150
3
    Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1151
3
  }
1152
1153
38
  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1154
38
    assert(N == 1 && "Invalid number of operands!");
1155
38
    Inst.addOperand(MCOperand::createReg(getCCRReg()));
1156
38
  }
1157
1158
60
  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1159
60
    assert(N == 1 && "Invalid number of operands!");
1160
60
    Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1161
60
  }
1162
1163
  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1164
1.37k
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
1.37k
    assert(N == 1 && "Invalid number of operands!");
1166
1.37k
    uint64_t Imm = getConstantImm() - Offset;
1167
1.37k
    Imm &= (1ULL << Bits) - 1;
1168
1.37k
    Imm += Offset;
1169
1.37k
    Imm += AdjustOffset;
1170
1.37k
    Inst.addOperand(MCOperand::createImm(Imm));
1171
1.37k
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
475
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
475
    assert(N == 1 && "Invalid number of operands!");
1166
475
    uint64_t Imm = getConstantImm() - Offset;
1167
475
    Imm &= (1ULL << Bits) - 1;
1168
475
    Imm += Offset;
1169
475
    Imm += AdjustOffset;
1170
475
    Inst.addOperand(MCOperand::createImm(Imm));
1171
475
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<2u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
14
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
14
    assert(N == 1 && "Invalid number of operands!");
1166
14
    uint64_t Imm = getConstantImm() - Offset;
1167
14
    Imm &= (1ULL << Bits) - 1;
1168
14
    Imm += Offset;
1169
14
    Imm += AdjustOffset;
1170
14
    Inst.addOperand(MCOperand::createImm(Imm));
1171
14
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<16u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
48
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
48
    assert(N == 1 && "Invalid number of operands!");
1166
48
    uint64_t Imm = getConstantImm() - Offset;
1167
48
    Imm &= (1ULL << Bits) - 1;
1168
48
    Imm += Offset;
1169
48
    Imm += AdjustOffset;
1170
48
    Inst.addOperand(MCOperand::createImm(Imm));
1171
48
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<8u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
15
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
15
    assert(N == 1 && "Invalid number of operands!");
1166
15
    uint64_t Imm = getConstantImm() - Offset;
1167
15
    Imm &= (1ULL << Bits) - 1;
1168
15
    Imm += Offset;
1169
15
    Imm += AdjustOffset;
1170
15
    Inst.addOperand(MCOperand::createImm(Imm));
1171
15
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 32, -32>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
6
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
6
    assert(N == 1 && "Invalid number of operands!");
1166
6
    uint64_t Imm = getConstantImm() - Offset;
1167
6
    Imm &= (1ULL << Bits) - 1;
1168
6
    Imm += Offset;
1169
6
    Imm += AdjustOffset;
1170
6
    Inst.addOperand(MCOperand::createImm(Imm));
1171
6
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<3u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
155
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
155
    assert(N == 1 && "Invalid number of operands!");
1166
155
    uint64_t Imm = getConstantImm() - Offset;
1167
155
    Imm &= (1ULL << Bits) - 1;
1168
155
    Imm += Offset;
1169
155
    Imm += AdjustOffset;
1170
155
    Inst.addOperand(MCOperand::createImm(Imm));
1171
155
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<6u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
76
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
76
    assert(N == 1 && "Invalid number of operands!");
1166
76
    uint64_t Imm = getConstantImm() - Offset;
1167
76
    Imm &= (1ULL << Bits) - 1;
1168
76
    Imm += Offset;
1169
76
    Imm += AdjustOffset;
1170
76
    Inst.addOperand(MCOperand::createImm(Imm));
1171
76
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<4u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
62
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
62
    assert(N == 1 && "Invalid number of operands!");
1166
62
    uint64_t Imm = getConstantImm() - Offset;
1167
62
    Imm &= (1ULL << Bits) - 1;
1168
62
    Imm += Offset;
1169
62
    Imm += AdjustOffset;
1170
62
    Inst.addOperand(MCOperand::createImm(Imm));
1171
62
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<10u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
132
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
132
    assert(N == 1 && "Invalid number of operands!");
1166
132
    uint64_t Imm = getConstantImm() - Offset;
1167
132
    Imm &= (1ULL << Bits) - 1;
1168
132
    Imm += Offset;
1169
132
    Imm += AdjustOffset;
1170
132
    Inst.addOperand(MCOperand::createImm(Imm));
1171
132
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<1u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
57
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
57
    assert(N == 1 && "Invalid number of operands!");
1166
57
    uint64_t Imm = getConstantImm() - Offset;
1167
57
    Imm &= (1ULL << Bits) - 1;
1168
57
    Imm += Offset;
1169
57
    Imm += AdjustOffset;
1170
57
    Inst.addOperand(MCOperand::createImm(Imm));
1171
57
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 33, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
10
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
10
    assert(N == 1 && "Invalid number of operands!");
1166
10
    uint64_t Imm = getConstantImm() - Offset;
1167
10
    Imm &= (1ULL << Bits) - 1;
1168
10
    Imm += Offset;
1169
10
    Imm += AdjustOffset;
1170
10
    Inst.addOperand(MCOperand::createImm(Imm));
1171
10
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 32, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
20
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
20
    assert(N == 1 && "Invalid number of operands!");
1166
20
    uint64_t Imm = getConstantImm() - Offset;
1167
20
    Imm &= (1ULL << Bits) - 1;
1168
20
    Imm += Offset;
1169
20
    Imm += AdjustOffset;
1170
20
    Inst.addOperand(MCOperand::createImm(Imm));
1171
20
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<5u, 1, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
42
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
42
    assert(N == 1 && "Invalid number of operands!");
1166
42
    uint64_t Imm = getConstantImm() - Offset;
1167
42
    Imm &= (1ULL << Bits) - 1;
1168
42
    Imm += Offset;
1169
42
    Imm += AdjustOffset;
1170
42
    Inst.addOperand(MCOperand::createImm(Imm));
1171
42
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<2u, 1, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
12
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
12
    assert(N == 1 && "Invalid number of operands!");
1166
12
    uint64_t Imm = getConstantImm() - Offset;
1167
12
    Imm &= (1ULL << Bits) - 1;
1168
12
    Imm += Offset;
1169
12
    Imm += AdjustOffset;
1170
12
    Inst.addOperand(MCOperand::createImm(Imm));
1171
12
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<32u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
212
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
212
    assert(N == 1 && "Invalid number of operands!");
1166
212
    uint64_t Imm = getConstantImm() - Offset;
1167
212
    Imm &= (1ULL << Bits) - 1;
1168
212
    Imm += Offset;
1169
212
    Imm += AdjustOffset;
1170
212
    Inst.addOperand(MCOperand::createImm(Imm));
1171
212
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<7u, -1, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
7
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
7
    assert(N == 1 && "Invalid number of operands!");
1166
7
    uint64_t Imm = getConstantImm() - Offset;
1167
7
    Imm &= (1ULL << Bits) - 1;
1168
7
    Imm += Offset;
1169
7
    Imm += AdjustOffset;
1170
7
    Inst.addOperand(MCOperand::createImm(Imm));
1171
7
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<7u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
5
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
5
    assert(N == 1 && "Invalid number of operands!");
1166
5
    uint64_t Imm = getConstantImm() - Offset;
1167
5
    Imm &= (1ULL << Bits) - 1;
1168
5
    Imm += Offset;
1169
5
    Imm += AdjustOffset;
1170
5
    Inst.addOperand(MCOperand::createImm(Imm));
1171
5
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantUImmOperands<20u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1164
25
  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1165
25
    assert(N == 1 && "Invalid number of operands!");
1166
25
    uint64_t Imm = getConstantImm() - Offset;
1167
25
    Imm &= (1ULL << Bits) - 1;
1168
25
    Imm += Offset;
1169
25
    Imm += AdjustOffset;
1170
25
    Inst.addOperand(MCOperand::createImm(Imm));
1171
25
  }
1172
1173
  template <unsigned Bits>
1174
1.98k
  void addSImmOperands(MCInst &Inst, unsigned N) const {
1175
1.98k
    if (isImm() && !isConstantImm()) {
1176
388
      addExpr(Inst, getImm());
1177
388
      return;
1178
388
    }
1179
1.60k
    addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1180
1.60k
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addSImmOperands<32u>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1174
642
  void addSImmOperands(MCInst &Inst, unsigned N) const {
1175
642
    if (isImm() && !isConstantImm()) {
1176
0
      addExpr(Inst, getImm());
1177
0
      return;
1178
0
    }
1179
642
    addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1180
642
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addSImmOperands<16u>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1174
1.34k
  void addSImmOperands(MCInst &Inst, unsigned N) const {
1175
1.34k
    if (isImm() && !isConstantImm()) {
1176
388
      addExpr(Inst, getImm());
1177
388
      return;
1178
388
    }
1179
959
    addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1180
959
  }
1181
1182
  template <unsigned Bits>
1183
236
  void addUImmOperands(MCInst &Inst, unsigned N) const {
1184
236
    if (isImm() && !isConstantImm()) {
1185
188
      addExpr(Inst, getImm());
1186
188
      return;
1187
188
    }
1188
48
    addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1189
48
  }
1190
1191
  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1192
1.64k
  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193
1.64k
    assert(N == 1 && "Invalid number of operands!");
1194
1.64k
    int64_t Imm = getConstantImm() - Offset;
1195
1.64k
    Imm = SignExtend64<Bits>(Imm);
1196
1.64k
    Imm += Offset;
1197
1.64k
    Imm += AdjustOffset;
1198
1.64k
    Inst.addOperand(MCOperand::createImm(Imm));
1199
1.64k
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantSImmOperands<32u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1192
642
  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193
642
    assert(N == 1 && "Invalid number of operands!");
1194
642
    int64_t Imm = getConstantImm() - Offset;
1195
642
    Imm = SignExtend64<Bits>(Imm);
1196
642
    Imm += Offset;
1197
642
    Imm += AdjustOffset;
1198
642
    Inst.addOperand(MCOperand::createImm(Imm));
1199
642
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantSImmOperands<16u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1192
959
  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193
959
    assert(N == 1 && "Invalid number of operands!");
1194
959
    int64_t Imm = getConstantImm() - Offset;
1195
959
    Imm = SignExtend64<Bits>(Imm);
1196
959
    Imm += Offset;
1197
959
    Imm += AdjustOffset;
1198
959
    Inst.addOperand(MCOperand::createImm(Imm));
1199
959
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantSImmOperands<4u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1192
4
  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193
4
    assert(N == 1 && "Invalid number of operands!");
1194
4
    int64_t Imm = getConstantImm() - Offset;
1195
4
    Imm = SignExtend64<Bits>(Imm);
1196
4
    Imm += Offset;
1197
4
    Imm += AdjustOffset;
1198
4
    Inst.addOperand(MCOperand::createImm(Imm));
1199
4
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantSImmOperands<5u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1192
20
  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193
20
    assert(N == 1 && "Invalid number of operands!");
1194
20
    int64_t Imm = getConstantImm() - Offset;
1195
20
    Imm = SignExtend64<Bits>(Imm);
1196
20
    Imm += Offset;
1197
20
    Imm += AdjustOffset;
1198
20
    Inst.addOperand(MCOperand::createImm(Imm));
1199
20
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantSImmOperands<10u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1192
12
  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193
12
    assert(N == 1 && "Invalid number of operands!");
1194
12
    int64_t Imm = getConstantImm() - Offset;
1195
12
    Imm = SignExtend64<Bits>(Imm);
1196
12
    Imm += Offset;
1197
12
    Imm += AdjustOffset;
1198
12
    Inst.addOperand(MCOperand::createImm(Imm));
1199
12
  }
MipsAsmParser.cpp:void (anonymous namespace)::MipsOperand::addConstantSImmOperands<6u, 0, 0>(llvm::MCInst&, unsigned int) const
Line
Count
Source
1192
6
  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1193
6
    assert(N == 1 && "Invalid number of operands!");
1194
6
    int64_t Imm = getConstantImm() - Offset;
1195
6
    Imm = SignExtend64<Bits>(Imm);
1196
6
    Imm += Offset;
1197
6
    Imm += AdjustOffset;
1198
6
    Inst.addOperand(MCOperand::createImm(Imm));
1199
6
  }
1200
1201
3.59k
  void addImmOperands(MCInst &Inst, unsigned N) const {
1202
3.59k
    assert(N == 1 && "Invalid number of operands!");
1203
3.59k
    const MCExpr *Expr = getImm();
1204
3.59k
    addExpr(Inst, Expr);
1205
3.59k
  }
1206
1207
12.6k
  void addMemOperands(MCInst &Inst, unsigned N) const {
1208
12.6k
    assert(N == 2 && "Invalid number of operands!");
1209
12.6k
1210
12.6k
    Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1211
12.6k
                                             ? 
getMemBase()->getGPR64Reg()10.6k
1212
12.6k
                                             : 
getMemBase()->getGPR32Reg()2.02k
));
1213
12.6k
1214
12.6k
    const MCExpr *Expr = getMemOff();
1215
12.6k
    addExpr(Inst, Expr);
1216
12.6k
  }
1217
1218
50
  void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1219
50
    assert(N == 2 && "Invalid number of operands!");
1220
50
1221
50
    Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1222
50
1223
50
    const MCExpr *Expr = getMemOff();
1224
50
    addExpr(Inst, Expr);
1225
50
  }
1226
1227
63
  void addRegListOperands(MCInst &Inst, unsigned N) const {
1228
63
    assert(N == 1 && "Invalid number of operands!");
1229
63
1230
63
    for (auto RegNo : getRegList())
1231
249
      Inst.addOperand(MCOperand::createReg(RegNo));
1232
63
  }
1233
1234
33.3k
  bool isReg() const override {
1235
33.3k
    // As a special case until we sort out the definition of div/divu, accept
1236
33.3k
    // $0/$zero here so that MCK_ZERO works correctly.
1237
33.3k
    return isGPRAsmReg() && 
RegIdx.Index == 015.5k
;
1238
33.3k
  }
1239
1240
134k
  bool isRegIdx() const { return Kind == k_RegisterIndex; }
1241
28.7k
  bool isImm() const override { return Kind == k_Immediate; }
1242
1243
15.5k
  bool isConstantImm() const {
1244
15.5k
    int64_t Res;
1245
15.5k
    return isImm() && 
getImm()->evaluateAsAbsolute(Res)10.6k
;
1246
15.5k
  }
1247
1248
12
  bool isConstantImmz() const {
1249
12
    return isConstantImm() && getConstantImm() == 0;
1250
12
  }
1251
1252
4.18k
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
4.18k
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)3.35k
;
1254
4.18k
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<1u, 0>() const
Line
Count
Source
1252
69
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
69
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254
69
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<2u, 0>() const
Line
Count
Source
1252
85
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
85
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)79
;
1254
85
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<2u, 1>() const
Line
Count
Source
1252
56
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
56
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254
56
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<3u, 0>() const
Line
Count
Source
1252
410
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
410
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)409
;
1254
410
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<4u, 0>() const
Line
Count
Source
1252
291
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
291
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)285
;
1254
291
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 0>() const
Line
Count
Source
1252
2.11k
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
2.11k
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)1.47k
;
1254
2.11k
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 1>() const
Line
Count
Source
1252
140
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
140
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254
140
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 32>() const
Line
Count
Source
1252
92
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
92
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)88
;
1254
92
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<5u, 33>() const
Line
Count
Source
1252
26
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
26
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254
26
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<6u, 0>() const
Line
Count
Source
1252
302
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
302
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)167
;
1254
302
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<7u, 0>() const
Line
Count
Source
1252
19
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
19
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254
19
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<7u, -1>() const
Line
Count
Source
1252
16
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
16
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254
16
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<8u, 0>() const
Line
Count
Source
1252
46
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
46
    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1254
46
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<10u, 0>() const
Line
Count
Source
1252
470
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
470
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)432
;
1254
470
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<20u, 0>() const
Line
Count
Source
1252
47
  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1253
47
    return isConstantImm() && 
isUInt<Bits>(getConstantImm() - Offset)45
;
1254
47
  }
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantUImm<26u, 0>() const
1255
1256
4.26k
  template <unsigned Bits> bool isSImm() const {
1257
4.26k
    return isConstantImm() ? 
isInt<Bits>(getConstantImm())1.68k
:
isImm()2.58k
;
1258
4.26k
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isSImm<16u>() const
Line
Count
Source
1256
3.76k
  template <unsigned Bits> bool isSImm() const {
1257
3.76k
    return isConstantImm() ? 
isInt<Bits>(getConstantImm())1.38k
:
isImm()2.38k
;
1258
3.76k
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isSImm<32u>() const
Line
Count
Source
1256
247
  template <unsigned Bits> bool isSImm() const {
1257
247
    return isConstantImm() ? 
isInt<Bits>(getConstantImm())70
:
isImm()177
;
1258
247
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isSImm<33u>() const
Line
Count
Source
1256
258
  template <unsigned Bits> bool isSImm() const {
1257
258
    return isConstantImm() ? 
isInt<Bits>(getConstantImm())229
:
isImm()29
;
1258
258
  }
1259
1260
928
  template <unsigned Bits> bool isUImm() const {
1261
928
    return isConstantImm() ? 
isUInt<Bits>(getConstantImm())443
:
isImm()485
;
1262
928
  }
1263
1264
3.61k
  template <unsigned Bits> bool isAnyImm() const {
1265
3.61k
    return isConstantImm() ? 
(1.34k
isInt<Bits>(getConstantImm())1.34k
||
1266
1.34k
                              
isUInt<Bits>(getConstantImm())49
)
1267
3.61k
                           : 
isImm()2.26k
;
1268
3.61k
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isAnyImm<16u>() const
Line
Count
Source
1264
1.36k
  template <unsigned Bits> bool isAnyImm() const {
1265
1.36k
    return isConstantImm() ? 
(276
isInt<Bits>(getConstantImm())276
||
1266
276
                              
isUInt<Bits>(getConstantImm())5
)
1267
1.36k
                           : 
isImm()1.09k
;
1268
1.36k
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isAnyImm<33u>() const
Line
Count
Source
1264
2.24k
  template <unsigned Bits> bool isAnyImm() const {
1265
2.24k
    return isConstantImm() ? 
(1.07k
isInt<Bits>(getConstantImm())1.07k
||
1266
1.07k
                              
isUInt<Bits>(getConstantImm())44
)
1267
2.24k
                           : 
isImm()1.17k
;
1268
2.24k
  }
1269
1270
134
  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1271
134
    return isConstantImm() && 
isInt<Bits>(getConstantImm() - Offset)128
;
1272
134
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantSImm<4u, 0>() const
Line
Count
Source
1270
8
  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1271
8
    return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1272
8
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantSImm<5u, 0>() const
Line
Count
Source
1270
60
  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1271
60
    return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1272
60
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantSImm<6u, 0>() const
Line
Count
Source
1270
22
  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1271
22
    return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1272
22
  }
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantSImm<9u, 0>() const
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantSImm<10u, 0>() const
Line
Count
Source
1270
44
  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1271
44
    return isConstantImm() && 
isInt<Bits>(getConstantImm() - Offset)38
;
1272
44
  }
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isConstantSImm<11u, 0>() const
1273
1274
28
  template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1275
28
    return isConstantImm() && getConstantImm() >= Bottom &&
1276
28
           
getConstantImm() <= Top21
;
1277
28
  }
1278
1279
158k
  bool isToken() const override {
1280
158k
    // Note: It's not possible to pretend that other operand kinds are tokens.
1281
158k
    // The matcher emitter checks tokens first.
1282
158k
    return Kind == k_Token;
1283
158k
  }
1284
1285
38.9k
  bool isMem() const override { return Kind == k_Memory; }
1286
1287
12.6k
  bool isConstantMemOff() const {
1288
12.6k
    return isMem() && isa<MCConstantExpr>(getMemOff());
1289
12.6k
  }
1290
1291
  // Allow relocation operators.
1292
  // FIXME: This predicate and others need to look through binary expressions
1293
  //        and determine whether a Value is a constant or not.
1294
  template <unsigned Bits, unsigned ShiftAmount = 0>
1295
3.22k
  bool isMemWithSimmOffset() const {
1296
3.22k
    if (!isMem())
1297
1.08k
      return false;
1298
2.14k
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
2.14k
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
2.14k
        
(1.94k
isConstantMemOff()1.94k
&&
1302
1.94k
         
isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())1.93k
))
1303
1.40k
      return true;
1304
731
    MCValue Res;
1305
731
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
731
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
731
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<10u, 0u>() const
Line
Count
Source
1295
7
  bool isMemWithSimmOffset() const {
1296
7
    if (!isMem())
1297
0
      return false;
1298
7
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
7
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
7
        (isConstantMemOff() &&
1302
7
         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303
3
      return true;
1304
4
    MCValue Res;
1305
4
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
4
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
4
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<10u, 1u>() const
Line
Count
Source
1295
9
  bool isMemWithSimmOffset() const {
1296
9
    if (!isMem())
1297
0
      return false;
1298
9
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
9
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
9
        (isConstantMemOff() &&
1302
9
         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303
5
      return true;
1304
4
    MCValue Res;
1305
4
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
4
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
4
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<10u, 2u>() const
Line
Count
Source
1295
10
  bool isMemWithSimmOffset() const {
1296
10
    if (!isMem())
1297
0
      return false;
1298
10
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
10
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
10
        (isConstantMemOff() &&
1302
10
         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303
6
      return true;
1304
4
    MCValue Res;
1305
4
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
4
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
4
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<10u, 3u>() const
Line
Count
Source
1295
13
  bool isMemWithSimmOffset() const {
1296
13
    if (!isMem())
1297
0
      return false;
1298
13
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
13
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
13
        (isConstantMemOff() &&
1302
13
         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303
9
      return true;
1304
4
    MCValue Res;
1305
4
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
4
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
4
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<11u, 0u>() const
Line
Count
Source
1295
304
  bool isMemWithSimmOffset() const {
1296
304
    if (!isMem())
1297
24
      return false;
1298
280
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
280
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
280
        (isConstantMemOff() &&
1302
280
         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303
58
      return true;
1304
222
    MCValue Res;
1305
222
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
222
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
222
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<12u, 0u>() const
Line
Count
Source
1295
40
  bool isMemWithSimmOffset() const {
1296
40
    if (!isMem())
1297
4
      return false;
1298
36
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
36
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
36
        
(28
isConstantMemOff()28
&&
1302
28
         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303
25
      return true;
1304
11
    MCValue Res;
1305
11
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
11
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
11
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<16u, 0u>() const
Line
Count
Source
1295
1.00k
  bool isMemWithSimmOffset() const {
1296
1.00k
    if (!isMem())
1297
68
      return false;
1298
940
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
940
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
940
        
(751
isConstantMemOff()751
&&
1302
751
         
isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())747
))
1303
717
      return true;
1304
223
    MCValue Res;
1305
223
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
223
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
223
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isMemWithSimmOffset<9u, 0u>() const
Line
Count
Source
1295
1.83k
  bool isMemWithSimmOffset() const {
1296
1.83k
    if (!isMem())
1297
991
      return false;
1298
845
    if (!getMemBase()->isGPRAsmReg())
1299
0
      return false;
1300
845
    if (isa<MCTargetExpr>(getMemOff()) ||
1301
845
        (isConstantMemOff() &&
1302
845
         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1303
586
      return true;
1304
259
    MCValue Res;
1305
259
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1306
259
    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1307
259
  }
1308
1309
382
  bool isMemWithPtrSizeOffset() const {
1310
382
    if (!isMem())
1311
6
      return false;
1312
376
    if (!getMemBase()->isGPRAsmReg())
1313
0
      return false;
1314
376
    const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 
64193
:
32183
;
1315
376
    if (isa<MCTargetExpr>(getMemOff()) ||
1316
376
        
(270
isConstantMemOff()270
&&
isIntN(PtrBits, getConstantMemOff())270
))
1317
336
      return true;
1318
40
    MCValue Res;
1319
40
    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1320
40
    return IsReloc && isIntN(PtrBits, Res.getConstant());
1321
40
  }
1322
1323
75
  bool isMemWithGRPMM16Base() const {
1324
75
    return isMem() && getMemBase()->isMM16AsmReg();
1325
75
  }
1326
1327
18
  template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1328
18
    return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1329
18
      && 
getMemBase()->isRegIdx()14
&&
(getMemBase()->getGPR32Reg() == Mips::SP)14
;
1330
18
  }
1331
1332
10.4k
  template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1333
10.4k
    return isMem() && isConstantMemOff() && 
isUInt<Bits>(getConstantMemOff())279
1334
10.4k
      && 
(getConstantMemOff() % 4 == 0)165
&&
getMemBase()->isRegIdx()142
1335
10.4k
      && 
(getMemBase()->getGPR32Reg() == Mips::SP)142
;
1336
10.4k
  }
1337
1338
0
  template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1339
0
    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1340
0
      && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1341
0
      && (getMemBase()->getGPR32Reg() == Mips::GP);
1342
0
  }
1343
1344
  template <unsigned Bits, unsigned ShiftLeftAmount>
1345
36
  bool isScaledUImm() const {
1346
36
    return isConstantImm() &&
1347
36
           isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1348
36
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isScaledUImm<5u, 2u>() const
Line
Count
Source
1345
26
  bool isScaledUImm() const {
1346
26
    return isConstantImm() &&
1347
26
           isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1348
26
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isScaledUImm<6u, 2u>() const
Line
Count
Source
1345
10
  bool isScaledUImm() const {
1346
10
    return isConstantImm() &&
1347
10
           isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1348
10
  }
1349
1350
  template <unsigned Bits, unsigned ShiftLeftAmount>
1351
92
  bool isScaledSImm() const {
1352
92
    if (isConstantImm() &&
1353
92
        
isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm())61
)
1354
19
      return true;
1355
73
    // Operand can also be a symbol or symbol plus
1356
73
    // offset in case of relocations.
1357
73
    if (Kind != k_Immediate)
1358
0
      return false;
1359
73
    MCValue Res;
1360
73
    bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1361
73
    return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1362
73
  }
MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isScaledSImm<19u, 2u>() const
Line
Count
Source
1351
92
  bool isScaledSImm() const {
1352
92
    if (isConstantImm() &&
1353
92
        
isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm())61
)
1354
19
      return true;
1355
73
    // Operand can also be a symbol or symbol plus
1356
73
    // offset in case of relocations.
1357
73
    if (Kind != k_Immediate)
1358
0
      return false;
1359
73
    MCValue Res;
1360
73
    bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1361
73
    return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1362
73
  }
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isScaledSImm<7u, 2u>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isScaledSImm<10u, 1u>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isScaledSImm<10u, 2u>() const
Unexecuted instantiation: MipsAsmParser.cpp:bool (anonymous namespace)::MipsOperand::isScaledSImm<10u, 3u>() const
1363
1364
36
  bool isRegList16() const {
1365
36
    if (!isRegList())
1366
0
      return false;
1367
36
1368
36
    int Size = RegList.List->size();
1369
36
    if (Size < 2 || 
Size > 530
)
1370
6
      return false;
1371
30
1372
30
    unsigned R0 = RegList.List->front();
1373
30
    unsigned R1 = RegList.List->back();
1374
30
    if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1375
30
          
(12
R0 == Mips::S0_6412
&&
R1 == Mips::RA_640
)))
1376
12
      return false;
1377
18
1378
18
    int PrevReg = *RegList.List->begin();
1379
36
    for (int i = 1; i < Size - 1; 
i++18
) {
1380
18
      int Reg = (*(RegList.List))[i];
1381
18
      if ( Reg != PrevReg + 1)
1382
0
        return false;
1383
18
      PrevReg = Reg;
1384
18
    }
1385
18
1386
18
    return true;
1387
18
  }
1388
1389
245
  bool isInvNum() const { return Kind == k_Immediate; }
1390
1391
0
  bool isLSAImm() const {
1392
0
    if (!isConstantImm())
1393
0
      return false;
1394
0
    int64_t Val = getConstantImm();
1395
0
    return 1 <= Val && Val <= 4;
1396
0
  }
1397
1398
91
  bool isRegList() const { return Kind == k_RegList; }
1399
1400
43.0k
  StringRef getToken() const {
1401
43.0k
    assert(Kind == k_Token && "Invalid access!");
1402
43.0k
    return StringRef(Tok.Data, Tok.Length);
1403
43.0k
  }
1404
1405
251
  unsigned getReg() const override {
1406
251
    // As a special case until we sort out the definition of div/divu, accept
1407
251
    // $0/$zero here so that MCK_ZERO works correctly.
1408
251
    if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1409
251
        RegIdx.Kind & RegKind_GPR)
1410
251
      return getGPR32Reg(); // FIXME: GPR64 too
1411
0
1412
0
    llvm_unreachable("Invalid access!");
1413
0
    return 0;
1414
0
  }
1415
1416
25.1k
  const MCExpr *getImm() const {
1417
25.1k
    assert((Kind == k_Immediate) && "Invalid access!");
1418
25.1k
    return Imm.Val;
1419
25.1k
  }
1420
1421
10.1k
  int64_t getConstantImm() const {
1422
10.1k
    const MCExpr *Val = getImm();
1423
10.1k
    int64_t Value = 0;
1424
10.1k
    (void)Val->evaluateAsAbsolute(Value);
1425
10.1k
    return Value;
1426
10.1k
  }
1427
1428
15.6k
  MipsOperand *getMemBase() const {
1429
15.6k
    assert((Kind == k_Memory) && "Invalid access!");
1430
15.6k
    return Mem.Base;
1431
15.6k
  }
1432
1433
31.3k
  const MCExpr *getMemOff() const {
1434
31.3k
    assert((Kind == k_Memory) && "Invalid access!");
1435
31.3k
    return Mem.Off;
1436
31.3k
  }
1437
1438
2.67k
  int64_t getConstantMemOff() const {
1439
2.67k
    return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1440
2.67k
  }
1441
1442
63
  const SmallVectorImpl<unsigned> &getRegList() const {
1443
63
    assert((Kind == k_RegList) && "Invalid access!");
1444
63
    return *(RegList.List);
1445
63
  }
1446
1447
  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1448
43.1k
                                                  MipsAsmParser &Parser) {
1449
43.1k
    auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1450
43.1k
    Op->Tok.Data = Str.data();
1451
43.1k
    Op->Tok.Length = Str.size();
1452
43.1k
    Op->StartLoc = S;
1453
43.1k
    Op->EndLoc = S;
1454
43.1k
    return Op;
1455
43.1k
  }
1456
1457
  /// Create a numeric register (e.g. $1). The exact register remains
1458
  /// unresolved until an instruction successfully matches
1459
  static std::unique_ptr<MipsOperand>
1460
  createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1461
40.7k
                   SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1462
40.7k
    LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1463
40.7k
    return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1464
40.7k
  }
1465
1466
  /// Create a register that is definitely a GPR.
1467
  /// This is typically only used for named registers such as $gp.
1468
  static std::unique_ptr<MipsOperand>
1469
  createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1470
6.46k
               SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1471
6.46k
    return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1472
6.46k
  }
1473
1474
  /// Create a register that is definitely a FGR.
1475
  /// This is typically only used for named registers such as $f0.
1476
  static std::unique_ptr<MipsOperand>
1477
  createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1478
7.30k
               SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1479
7.30k
    return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1480
7.30k
  }
1481
1482
  /// Create a register that is definitely a HWReg.
1483
  /// This is typically only used for named registers such as $hwr_cpunum.
1484
  static std::unique_ptr<MipsOperand>
1485
  createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1486
5
                  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1487
5
    return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1488
5
  }
1489
1490
  /// Create a register that is definitely an FCC.
1491
  /// This is typically only used for named registers such as $fcc0.
1492
  static std::unique_ptr<MipsOperand>
1493
  createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1494
866
               SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1495
866
    return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1496
866
  }
1497
1498
  /// Create a register that is definitely an ACC.
1499
  /// This is typically only used for named registers such as $ac0.
1500
  static std::unique_ptr<MipsOperand>
1501
  createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1502
275
               SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1503
275
    return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1504
275
  }
1505
1506
  /// Create a register that is definitely an MSA128.
1507
  /// This is typically only used for named registers such as $w0.
1508
  static std::unique_ptr<MipsOperand>
1509
  createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1510
2.14k
                  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1511
2.14k
    return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1512
2.14k
  }
1513
1514
  /// Create a register that is definitely an MSACtrl.
1515
  /// This is typically only used for named registers such as $msaaccess.
1516
  static std::unique_ptr<MipsOperand>
1517
  createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1518
16
                   SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1519
16
    return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1520
16
  }
1521
1522
  static std::unique_ptr<MipsOperand>
1523
9.68k
  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1524
9.68k
    auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1525
9.68k
    Op->Imm.Val = Val;
1526
9.68k
    Op->StartLoc = S;
1527
9.68k
    Op->EndLoc = E;
1528
9.68k
    return Op;
1529
9.68k
  }
1530
1531
  static std::unique_ptr<MipsOperand>
1532
  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1533
13.2k
            SMLoc E, MipsAsmParser &Parser) {
1534
13.2k
    auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1535
13.2k
    Op->Mem.Base = Base.release();
1536
13.2k
    Op->Mem.Off = Off;
1537
13.2k
    Op->StartLoc = S;
1538
13.2k
    Op->EndLoc = E;
1539
13.2k
    return Op;
1540
13.2k
  }
1541
1542
  static std::unique_ptr<MipsOperand>
1543
  CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1544
76
                MipsAsmParser &Parser) {
1545
76
    assert(Regs.size() > 0 && "Empty list not allowed");
1546
76
1547
76
    auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1548
76
    Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1549
76
    Op->StartLoc = StartLoc;
1550
76
    Op->EndLoc = EndLoc;
1551
76
    return Op;
1552
76
  }
1553
1554
100
 bool isGPRZeroAsmReg() const {
1555
100
    return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1556
100
  }
1557
1558
130
 bool isGPRNonZeroAsmReg() const {
1559
130
   return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1560
130
          
RegIdx.Index <= 3176
;
1561
130
  }
1562
1563
111k
  bool isGPRAsmReg() const {
1564
111k
    return isRegIdx() && 
RegIdx.Kind & RegKind_GPR91.7k
&&
RegIdx.Index <= 3189.1k
;
1565
111k
  }
1566
1567
344
  bool isMM16AsmReg() const {
1568
344
    if (!(isRegIdx() && RegIdx.Kind))
1569
0
      return false;
1570
344
    return ((RegIdx.Index >= 2 && 
RegIdx.Index <= 7342
)
1571
344
            || 
RegIdx.Index == 16161
||
RegIdx.Index == 17105
);
1572
344
1573
344
  }
1574
65
  bool isMM16AsmRegZero() const {
1575
65
    if (!(isRegIdx() && RegIdx.Kind))
1576
0
      return false;
1577
65
    return (RegIdx.Index == 0 ||
1578
65
            
(60
RegIdx.Index >= 260
&&
RegIdx.Index <= 760
) ||
1579
65
            
RegIdx.Index == 1724
);
1580
65
  }
1581
1582
28
  bool isMM16AsmRegMoveP() const {
1583
28
    if (!(isRegIdx() && RegIdx.Kind))
1584
0
      return false;
1585
28
    return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1586
28
      
(8
RegIdx.Index >= 168
&&
RegIdx.Index <= 200
));
1587
28
  }
1588
1589
20
  bool isMM16AsmRegMovePPairFirst() const {
1590
20
    if (!(isRegIdx() && RegIdx.Kind))
1591
0
      return false;
1592
20
    return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1593
20
  }
1594
1595
16
  bool isMM16AsmRegMovePPairSecond() const {
1596
16
    if (!(isRegIdx() && RegIdx.Kind))
1597
0
      return false;
1598
16
    return (RegIdx.Index == 21 || 
RegIdx.Index == 2213
||
1599
16
      
(13
RegIdx.Index >= 513
&&
RegIdx.Index <= 713
));
1600
16
  }
1601
1602
15.8k
  bool isFGRAsmReg() const {
1603
15.8k
    // AFGR64 is $0-$15 but we handle this in getAFGR64()
1604
15.8k
    return isRegIdx() && 
RegIdx.Kind & RegKind_FGR15.7k
&&
RegIdx.Index <= 3114.3k
;
1605
15.8k
  }
1606
1607
209
  bool isStrictlyFGRAsmReg() const {
1608
209
    // AFGR64 is $0-$15 but we handle this in getAFGR64()
1609
209
    return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1610
209
  }
1611
1612
85
  bool isHWRegsAsmReg() const {
1613
85
    return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1614
85
  }
1615
1616
46
  bool isCCRAsmReg() const {
1617
46
    return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1618
46
  }
1619
1620
2.07k
  bool isFCCAsmReg() const {
1621
2.07k
    if (!(isRegIdx() && 
RegIdx.Kind & RegKind_FCC2.07k
))
1622
418
      return false;
1623
1.65k
    return RegIdx.Index <= 7;
1624
1.65k
  }
1625
1626
589
  bool isACCAsmReg() const {
1627
589
    return isRegIdx() && 
RegIdx.Kind & RegKind_ACC586
&&
RegIdx.Index <= 3482
;
1628
589
  }
1629
1630
680
  bool isCOP0AsmReg() const {
1631
680
    return isRegIdx() && 
RegIdx.Kind & RegKind_COP0548
&&
RegIdx.Index <= 31548
;
1632
680
  }
1633
1634
566
  bool isCOP2AsmReg() const {
1635
566
    return isRegIdx() && 
RegIdx.Kind & RegKind_COP2564
&&
RegIdx.Index <= 31564
;
1636
566
  }
1637
1638
16
  bool isCOP3AsmReg() const {
1639
16
    return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1640
16
  }
1641
1642
2.13k
  bool isMSA128AsmReg() const {
1643
2.13k
    return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1644
2.13k
  }
1645
1646
38
  bool isMSACtrlAsmReg() const {
1647
38
    return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1648
38
  }
1649
1650
  /// getStartLoc - Get the location of the first token of this operand.
1651
2.42k
  SMLoc getStartLoc() const override { return StartLoc; }
1652
  /// getEndLoc - Get the location of the last token of this operand.
1653
16
  SMLoc getEndLoc() const override { return EndLoc; }
1654
1655
7
  void print(raw_ostream &OS) const override {
1656
7
    switch (Kind) {
1657
7
    case k_Immediate:
1658
3
      OS << "Imm<";
1659
3
      OS << *Imm.Val;
1660
3
      OS << ">";
1661
3
      break;
1662
7
    case k_Memory:
1663
0
      OS << "Mem<";
1664
0
      Mem.Base->print(OS);
1665
0
      OS << ", ";
1666
0
      OS << *Mem.Off;
1667
0
      OS << ">";
1668
0
      break;
1669
7
    case k_RegisterIndex:
1670
0
      OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1671
0
         << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1672
0
      break;
1673
7
    case k_Token:
1674
4
      OS << getToken();
1675
4
      break;
1676
7
    case k_RegList:
1677
0
      OS << "RegList< ";
1678
0
      for (auto Reg : (*RegList.List))
1679
0
        OS << Reg << " ";
1680
0
      OS <<  ">";
1681
0
      break;
1682
7
    }
1683
7
  }
1684
1685
6
  bool isValidForTie(const MipsOperand &Other) const {
1686
6
    if (Kind != Other.Kind)
1687
0
      return false;
1688
6
1689
6
    switch (Kind) {
1690
6
    default:
1691
0
      llvm_unreachable("Unexpected kind");
1692
6
      
return false0
;
1693
6
    case k_RegisterIndex: {
1694
6
      StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1695
6
      StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1696
6
      return Token == OtherToken;
1697
6
    }
1698
6
    }
1699
6
  }
1700
}; // class MipsOperand
1701
1702
} // end anonymous namespace
1703
1704
namespace llvm {
1705
1706
extern const MCInstrDesc MipsInsts[];
1707
1708
} // end namespace llvm
1709
1710
72.0k
static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1711
72.0k
  return MipsInsts[Opcode];
1712
72.0k
}
1713
1714
1.10k
static bool hasShortDelaySlot(MCInst &Inst) {
1715
1.10k
  switch (Inst.getOpcode()) {
1716
1.10k
    case Mips::BEQ_MM:
1717
63
    case Mips::BNE_MM:
1718
63
    case Mips::BLTZ_MM:
1719
63
    case Mips::BGEZ_MM:
1720
63
    case Mips::BLEZ_MM:
1721
63
    case Mips::BGTZ_MM:
1722
63
    case Mips::JRC16_MM:
1723
63
    case Mips::JALS_MM:
1724
63
    case Mips::JALRS_MM:
1725
63
    case Mips::JALRS16_MM:
1726
63
    case Mips::BGEZALS_MM:
1727
63
    case Mips::BLTZALS_MM:
1728
63
      return true;
1729
63
    case Mips::J_MM:
1730
6
      return !Inst.getOperand(0).isReg();
1731
1.03k
    default:
1732
1.03k
      return false;
1733
1.10k
  }
1734
1.10k
}
1735
1736
62
static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1737
62
  if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1738
62
    return &SRExpr->getSymbol();
1739
62
  }
1740
0
1741
0
  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1742
0
    const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1743
0
    const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1744
0
1745
0
    if (LHSSym)
1746
0
      return LHSSym;
1747
0
1748
0
    if (RHSSym)
1749
0
      return RHSSym;
1750
0
1751
0
    return nullptr;
1752
0
  }
1753
0
1754
0
  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1755
0
    return getSingleMCSymbol(UExpr->getSubExpr());
1756
0
1757
0
  return nullptr;
1758
0
}
1759
1760
62
static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1761
62
  if (isa<MCSymbolRefExpr>(Expr))
1762
62
    return 1;
1763
0
1764
0
  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1765
0
    return countMCSymbolRefExpr(BExpr->getLHS()) +
1766
0
           countMCSymbolRefExpr(BExpr->getRHS());
1767
0
1768
0
  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1769
0
    return countMCSymbolRefExpr(UExpr->getSubExpr());
1770
0
1771
0
  return 0;
1772
0
}
1773
1774
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1775
                                       MCStreamer &Out,
1776
35.9k
                                       const MCSubtargetInfo *STI) {
1777
35.9k
  MipsTargetStreamer &TOut = getTargetStreamer();
1778
35.9k
  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1779
35.9k
  bool ExpandedJalSym = false;
1780
35.9k
1781
35.9k
  Inst.setLoc(IDLoc);
1782
35.9k
1783
35.9k
  if (MCID.isBranch() || 
MCID.isCall()34.8k
) {
1784
1.57k
    const unsigned Opcode = Inst.getOpcode();
1785
1.57k
    MCOperand Offset;
1786
1.57k
1787
1.57k
    switch (Opcode) {
1788
1.57k
    default:
1789
825
      break;
1790
1.57k
    case Mips::BBIT0:
1791
6
    case Mips::BBIT032:
1792
6
    case Mips::BBIT1:
1793
6
    case Mips::BBIT132:
1794
6
      assert(hasCnMips() && "instruction only valid for octeon cpus");
1795
6
      LLVM_FALLTHROUGH;
1796
6
1797
106
    case Mips::BEQ:
1798
106
    case Mips::BNE:
1799
106
    case Mips::BEQ_MM:
1800
106
    case Mips::BNE_MM:
1801
106
      assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1802
106
      Offset = Inst.getOperand(2);
1803
106
      if (!Offset.isImm())
1804
35
        break; // We'll deal with this situation later on when applying fixups.
1805
71
      if (!isIntN(inMicroMipsMode() ? 
1718
:
1853
, Offset.getImm()))
1806
10
        return Error(IDLoc, "branch target out of range");
1807
61
      if (OffsetToAlignment(Offset.getImm(),
1808
61
                            1LL << (inMicroMipsMode() ? 
114
:
247
)))
1809
22
        return Error(IDLoc, "branch to misaligned address");
1810
39
      break;
1811
407
    case Mips::BGEZ:
1812
407
    case Mips::BGTZ:
1813
407
    case Mips::BLEZ:
1814
407
    case Mips::BLTZ:
1815
407
    case Mips::BGEZAL:
1816
407
    case Mips::BLTZAL:
1817
407
    case Mips::BC1F:
1818
407
    case Mips::BC1T:
1819
407
    case Mips::BGEZ_MM:
1820
407
    case Mips::BGTZ_MM:
1821
407
    case Mips::BLEZ_MM:
1822
407
    case Mips::BLTZ_MM:
1823
407
    case Mips::BGEZAL_MM:
1824
407
    case Mips::BLTZAL_MM:
1825
407
    case Mips::BC1F_MM:
1826
407
    case Mips::BC1T_MM:
1827
407
    case Mips::BC1EQZC_MMR6:
1828
407
    case Mips::BC1NEZC_MMR6:
1829
407
    case Mips::BC2EQZC_MMR6:
1830
407
    case Mips::BC2NEZC_MMR6:
1831
407
      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1832
407
      Offset = Inst.getOperand(1);
1833
407
      if (!Offset.isImm())
1834
25
        break; // We'll deal with this situation later on when applying fixups.
1835
382
      if (!isIntN(inMicroMipsMode() ? 
17114
:
18268
, Offset.getImm()))
1836
52
        return Error(IDLoc, "branch target out of range");
1837
330
      if (OffsetToAlignment(Offset.getImm(),
1838
330
                            1LL << (inMicroMipsMode() ? 
184
:
2246
)))
1839
96
        return Error(IDLoc, "branch to misaligned address");
1840
234
      break;
1841
234
    
case Mips::BGEC: 104
case Mips::BGEC_MMR6:
1842
104
    case Mips::BLTC:    case Mips::BLTC_MMR6:
1843
104
    case Mips::BGEUC:   case Mips::BGEUC_MMR6:
1844
104
    case Mips::BLTUC:   case Mips::BLTUC_MMR6:
1845
104
    case Mips::BEQC:    case Mips::BEQC_MMR6:
1846
104
    case Mips::BNEC:    case Mips::BNEC_MMR6:
1847
104
      assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1848
104
      Offset = Inst.getOperand(2);
1849
104
      if (!Offset.isImm())
1850
10
        break; // We'll deal with this situation later on when applying fixups.
1851
94
      if (!isIntN(18, Offset.getImm()))
1852
36
        return Error(IDLoc, "branch target out of range");
1853
58
      if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1854
36
        return Error(IDLoc, "branch to misaligned address");
1855
22
      break;
1856
60
    case Mips::BLEZC:   case Mips::BLEZC_MMR6:
1857
60
    case Mips::BGEZC:   case Mips::BGEZC_MMR6:
1858
60
    case Mips::BGTZC:   case Mips::BGTZC_MMR6:
1859
60
    case Mips::BLTZC:   case Mips::BLTZC_MMR6:
1860
60
      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1861
60
      Offset = Inst.getOperand(1);
1862
60
      if (!Offset.isImm())
1863
0
        break; // We'll deal with this situation later on when applying fixups.
1864
60
      if (!isIntN(18, Offset.getImm()))
1865
24
        return Error(IDLoc, "branch target out of range");
1866
36
      if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1867
24
        return Error(IDLoc, "branch to misaligned address");
1868
12
      break;
1869
53
    case Mips::BEQZC:   case Mips::BEQZC_MMR6:
1870
53
    case Mips::BNEZC:   case Mips::BNEZC_MMR6:
1871
53
      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1872
53
      Offset = Inst.getOperand(1);
1873
53
      if (!Offset.isImm())
1874
23
        break; // We'll deal with this situation later on when applying fixups.
1875
30
      if (!isIntN(23, Offset.getImm()))
1876
12
        return Error(IDLoc, "branch target out of range");
1877
18
      if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1878
12
        return Error(IDLoc, "branch to misaligned address");
1879
6
      break;
1880
21
    case Mips::BEQZ16_MM:
1881
21
    case Mips::BEQZC16_MMR6:
1882
21
    case Mips::BNEZ16_MM:
1883
21
    case Mips::BNEZC16_MMR6:
1884
21
      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1885
21
      Offset = Inst.getOperand(1);
1886
21
      if (!Offset.isImm())
1887
6
        break; // We'll deal with this situation later on when applying fixups.
1888
15
      if (!isInt<8>(Offset.getImm()))
1889
3
        return Error(IDLoc, "branch target out of range");
1890
12
      if (OffsetToAlignment(Offset.getImm(), 2LL))
1891
3
        return Error(IDLoc, "branch to misaligned address");
1892
9
      break;
1893
1.57k
    }
1894
1.57k
  }
1895
35.6k
1896
35.6k
  // SSNOP is deprecated on MIPS32r6/MIPS64r6
1897
35.6k
  // We still accept it but it is a normal nop.
1898
35.6k
  if (hasMips32r6() && 
Inst.getOpcode() == Mips::SSNOP2.22k
) {
1899
4
    std::string ISA = hasMips64r6() ? 
"MIPS64r6"2
:
"MIPS32r6"2
;
1900
4
    Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1901
4
                                                      "nop instruction");
1902
4
  }
1903
35.6k
1904
35.6k
  if (hasCnMips()) {
1905
61
    const unsigned Opcode = Inst.getOpcode();
1906
61
    MCOperand Opnd;
1907
61
    int Imm;
1908
61
1909
61
    switch (Opcode) {
1910
61
      default:
1911
51
        break;
1912
61
1913
61
      case Mips::BBIT0:
1914
6
      case Mips::BBIT032:
1915
6
      case Mips::BBIT1:
1916
6
      case Mips::BBIT132:
1917
6
        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1918
6
        // The offset is handled above
1919
6
        Opnd = Inst.getOperand(1);
1920
6
        if (!Opnd.isImm())
1921
0
          return Error(IDLoc, "expected immediate operand kind");
1922
6
        Imm = Opnd.getImm();
1923
6
        if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1924
6
                              
Opcode == Mips::BBIT15
?
632
:
314
))
1925
0
          return Error(IDLoc, "immediate operand value out of range");
1926
6
        if (Imm > 31) {
1927
0
          Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1928
0
                                               : Mips::BBIT132);
1929
0
          Inst.getOperand(1).setImm(Imm - 32);
1930
0
        }
1931
6
        break;
1932
6
1933
6
      case Mips::SEQi:
1934
4
      case Mips::SNEi:
1935
4
        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1936
4
        Opnd = Inst.getOperand(2);
1937
4
        if (!Opnd.isImm())
1938
0
          return Error(IDLoc, "expected immediate operand kind");
1939
4
        Imm = Opnd.getImm();
1940
4
        if (!isInt<10>(Imm))
1941
0
          return Error(IDLoc, "immediate operand value out of range");
1942
4
        break;
1943
61
    }
1944
61
  }
1945
35.6k
1946
35.6k
  // Warn on division by zero. We're checking here as all instructions get
1947
35.6k
  // processed here, not just the macros that need expansion.
1948
35.6k
  //
1949
35.6k
  // The MIPS backend models most of the divison instructions and macros as
1950
35.6k
  // three operand instructions. The pre-R6 divide instructions however have
1951
35.6k
  // two operands and explicitly define HI/LO as part of the instruction,
1952
35.6k
  // not in the operands.
1953
35.6k
  unsigned FirstOp = 1;
1954
35.6k
  unsigned SecondOp = 2;
1955
35.6k
  switch (Inst.getOpcode()) {
1956
35.6k
  default:
1957
35.3k
    break;
1958
35.6k
  case Mips::SDivIMacro:
1959
152
  case Mips::UDivIMacro:
1960
152
  case Mips::DSDivIMacro:
1961
152
  case Mips::DUDivIMacro:
1962
152
    if (Inst.getOperand(2).getImm() == 0) {
1963
26
      if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1964
26
          
Inst.getOperand(1).getReg() == Mips::ZERO_6422
)
1965
14
        Warning(IDLoc, "dividing zero by zero");
1966
12
      else
1967
12
        Warning(IDLoc, "division by zero");
1968
26
    }
1969
152
    break;
1970
152
  case Mips::DSDIV:
1971
72
  case Mips::SDIV:
1972
72
  case Mips::UDIV:
1973
72
  case Mips::DUDIV:
1974
72
  case Mips::UDIV_MM:
1975
72
  case Mips::SDIV_MM:
1976
72
    FirstOp = 0;
1977
72
    SecondOp = 1;
1978
72
    LLVM_FALLTHROUGH;
1979
166
  case Mips::SDivMacro:
1980
166
  case Mips::DSDivMacro:
1981
166
  case Mips::UDivMacro:
1982
166
  case Mips::DUDivMacro:
1983
166
  case Mips::DIV:
1984
166
  case Mips::DIVU:
1985
166
  case Mips::DDIV:
1986
166
  case Mips::DDIVU:
1987
166
  case Mips::DIVU_MMR6:
1988
166
  case Mips::DIV_MMR6:
1989
166
    if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1990
166
        
Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64126
) {
1991
60
      if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1992
60
          
Inst.getOperand(FirstOp).getReg() == Mips::ZERO_6440
)
1993
30
        Warning(IDLoc, "dividing zero by zero");
1994
30
      else
1995
30
        Warning(IDLoc, "division by zero");
1996
60
    }
1997
166
    break;
1998
35.6k
  }
1999
35.6k
2000
35.6k
  // For PIC code convert unconditional jump to unconditional branch.
2001
35.6k
  if ((Inst.getOpcode() == Mips::J || 
Inst.getOpcode() == Mips::J_MM35.5k
) &&
2002
35.6k
      
inPicMode()112
) {
2003
51
    MCInst BInst;
2004
51
    BInst.setOpcode(inMicroMipsMode() ? 
Mips::BEQ_MM8
:
Mips::BEQ43
);
2005
51
    BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2006
51
    BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2007
51
    BInst.addOperand(Inst.getOperand(0));
2008
51
    Inst = BInst;
2009
51
  }
2010
35.6k
2011
35.6k
  // This expansion is not in a function called by tryExpandInstruction()
2012
35.6k
  // because the pseudo-instruction doesn't have a distinct opcode.
2013
35.6k
  if ((Inst.getOpcode() == Mips::JAL || 
Inst.getOpcode() == Mips::JAL_MM35.4k
) &&
2014
35.6k
      
inPicMode()194
) {
2015
62
    warnIfNoMacro(IDLoc);
2016
62
2017
62
    const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2018
62
2019
62
    // We can do this expansion if there's only 1 symbol in the argument
2020
62
    // expression.
2021
62
    if (countMCSymbolRefExpr(JalExpr) > 1)
2022
0
      return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2023
62
2024
62
    // FIXME: This is checking the expression can be handled by the later stages
2025
62
    //        of the assembler. We ought to leave it to those later stages.
2026
62
    const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2027
62
2028
62
    // FIXME: Add support for label+offset operands (currently causes an error).
2029
62
    // FIXME: Add support for forward-declared local symbols.
2030
62
    // FIXME: Add expansion for when the LargeGOT option is enabled.
2031
62
    if (JalSym->isInSection() || 
JalSym->isTemporary()36
||
2032
62
        
(29
JalSym->isELF()29
&&
2033
36
         
cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL29
)) {
2034
36
      if (isABI_O32()) {
2035
18
        // If it's a local symbol and the O32 ABI is being used, we expand to:
2036
18
        //  lw $25, 0($gp)
2037
18
        //    R_(MICRO)MIPS_GOT16  label
2038
18
        //  addiu $25, $25, 0
2039
18
        //    R_(MICRO)MIPS_LO16   label
2040
18
        //  jalr  $25
2041
18
        const MCExpr *Got16RelocExpr =
2042
18
            MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2043
18
        const MCExpr *Lo16RelocExpr =
2044
18
            MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2045
18
2046
18
        TOut.emitRRX(Mips::LW, Mips::T9, GPReg,
2047
18
                     MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2048
18
        TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2049
18
                     MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2050
18
      } else if (isABI_N32() || 
isABI_N64()9
) {
2051
18
        // If it's a local symbol and the N32/N64 ABIs are being used,
2052
18
        // we expand to:
2053
18
        //  lw/ld $25, 0($gp)
2054
18
        //    R_(MICRO)MIPS_GOT_DISP  label
2055
18
        //  jalr  $25
2056
18
        const MCExpr *GotDispRelocExpr =
2057
18
            MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2058
18
2059
18
        TOut.emitRRX(ABI.ArePtrs64bit() ? 
Mips::LD9
:
Mips::LW9
, Mips::T9,
2060
18
                     GPReg, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2061
18
                     STI);
2062
18
      }
2063
36
    } else {
2064
26
      // If it's an external/weak symbol, we expand to:
2065
26
      //  lw/ld    $25, 0($gp)
2066
26
      //    R_(MICRO)MIPS_CALL16  label
2067
26
      //  jalr  $25
2068
26
      const MCExpr *Call16RelocExpr =
2069
26
          MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2070
26
2071
26
      TOut.emitRRX(ABI.ArePtrs64bit() ? 
Mips::LD7
:
Mips::LW19
, Mips::T9, GPReg,
2072
26
                   MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2073
26
    }
2074
62
2075
62
    MCInst JalrInst;
2076
62
    if (IsCpRestoreSet && 
inMicroMipsMode()14
)
2077
2
      JalrInst.setOpcode(Mips::JALRS_MM);
2078
60
    else
2079
60
      JalrInst.setOpcode(inMicroMipsMode() ? 
Mips::JALR_MM6
:
Mips::JALR54
);
2080
62
    JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2081
62
    JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2082
62
2083
62
    if (EmitJalrReloc) {
2084
62
      // As an optimization hint for the linker, before the JALR we add:
2085
62
      // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2086
62
      // tmplabel:
2087
62
      MCSymbol *TmpLabel = getContext().createTempSymbol();
2088
62
      const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2089
62
      const MCExpr *RelocJalrExpr =
2090
62
          MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2091
62
                                  getContext(), IDLoc);
2092
62
2093
62
      TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2094
62
          inMicroMipsMode() ? 
"R_MICROMIPS_JALR"8
:
"R_MIPS_JALR"54
,
2095
62
          RelocJalrExpr, IDLoc, *STI);
2096
62
      TOut.getStreamer().EmitLabel(TmpLabel);
2097
62
    }
2098
62
2099
62
    Inst = JalrInst;
2100
62
    ExpandedJalSym = true;
2101
62
  }
2102
35.6k
2103
35.6k
  bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2104
35.6k
  if ((MCID.mayLoad() || 
MCID.mayStore()24.3k
) &&
!IsPCRelativeLoad12.0k
) {
2105
12.0k
    // Check the offset of memory operand, if it is a symbol
2106
12.0k
    // reference or immediate we may have to expand instructions.
2107
48.2k
    for (unsigned i = 0; i < MCID.getNumOperands(); 
i++36.1k
) {
2108
36.2k
      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2109
36.2k
      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2110
36.2k
          
(OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)12.6k
) {
2111
23.8k
        MCOperand &Op = Inst.getOperand(i);
2112
23.8k
        if (Op.isImm()) {
2113
1.35k
          int64_t MemOffset = Op.getImm();
2114
1.35k
          if (MemOffset < -32768 || 
MemOffset > 327671.34k
) {
2115
97
            // Offset can't exceed 16bit value.
2116
97
            expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2117
97
            return getParser().hasPendingError();
2118
97
          }
2119
22.4k
        } else if (Op.isExpr()) {
2120
10.4k
          const MCExpr *Expr = Op.getExpr();
2121
10.4k
          if (Expr->getKind() == MCExpr::SymbolRef) {
2122
18
            const MCSymbolRefExpr *SR =
2123
18
                static_cast<const MCSymbolRefExpr *>(Expr);
2124
18
            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2125
18
              // Expand symbol.
2126
18
              expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2127
18
              return getParser().hasPendingError();
2128
18
            }
2129
10.4k
          } else if (!isEvaluated(Expr)) {
2130
3
            expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2131
3
            return getParser().hasPendingError();
2132
3
          }
2133
10.4k
        }
2134
23.8k
      }
2135
36.2k
    } // for
2136
12.0k
  }   // if load/store
2137
35.6k
2138
35.6k
  
if (35.5k
inMicroMipsMode()35.5k
) {
2139
2.13k
    if (MCID.mayLoad() && 
Inst.getOpcode() != Mips::LWP_MM276
) {
2140
270
      // Try to create 16-bit GP relative load instruction.
2141
1.06k
      for (unsigned i = 0; i < MCID.getNumOperands(); 
i++792
) {
2142
798
        const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2143
798
        if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2144
798
            
(OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)420
) {
2145
422
          MCOperand &Op = Inst.getOperand(i);
2146
422
          if (Op.isImm()) {
2147
151
            int MemOffset = Op.getImm();
2148
151
            MCOperand &DstReg = Inst.getOperand(0);
2149
151
            MCOperand &BaseReg = Inst.getOperand(1);
2150
151
            if (isInt<9>(MemOffset) && 
(MemOffset % 4 == 0)143
&&
2151
151
                getContext().getRegisterInfo()->getRegClass(
2152
110
                  Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2153
151
                
(96
BaseReg.getReg() == Mips::GP96
||
2154
96
                
BaseReg.getReg() == Mips::GP_6490
)) {
2155
6
2156
6
              TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2157
6
                           IDLoc, STI);
2158
6
              return false;
2159
6
            }
2160
151
          }
2161
422
        }
2162
798
      } // for
2163
270
    }   // if load
2164
2.13k
2165
2.13k
    // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2166
2.13k
2167
2.13k
    MCOperand Opnd;
2168
2.13k
    int Imm;
2169
2.13k
2170
2.13k
    switch (Inst.getOpcode()) {
2171
2.13k
      default:
2172
2.00k
        break;
2173
2.13k
      case Mips::ADDIUSP_MM:
2174
22
        Opnd = Inst.getOperand(0);
2175
22
        if (!Opnd.isImm())
2176
0
          return Error(IDLoc, "expected immediate operand kind");
2177
22
        Imm = Opnd.getImm();
2178
22
        if (Imm < -1032 || Imm > 1028 || 
(20
Imm < 820
&&
Imm > -1212
) ||
2179
22
            
Imm % 4 != 020
)
2180
2
          return Error(IDLoc, "immediate operand value out of range");
2181
20
        break;
2182
20
      case Mips::SLL16_MM:
2183
8
      case Mips::SRL16_MM:
2184
8
        Opnd = Inst.getOperand(2);
2185
8
        if (!Opnd.isImm())
2186
0
          return Error(IDLoc, "expected immediate operand kind");
2187
8
        Imm = Opnd.getImm();
2188
8
        if (Imm < 1 || Imm > 8)
2189
2
          return Error(IDLoc, "immediate operand value out of range");
2190
6
        break;
2191
6
      case Mips::LI16_MM:
2192
6
        Opnd = Inst.getOperand(1);
2193
6
        if (!Opnd.isImm())
2194
0
          return Error(IDLoc, "expected immediate operand kind");
2195
6
        Imm = Opnd.getImm();
2196
6
        if (Imm < -1 || Imm > 126)
2197
0
          return Error(IDLoc, "immediate operand value out of range");
2198
6
        break;
2199
10
      case Mips::ADDIUR2_MM:
2200
10
        Opnd = Inst.getOperand(2);
2201
10
        if (!Opnd.isImm())
2202
0
          return Error(IDLoc, "expected immediate operand kind");
2203
10
        Imm = Opnd.getImm();
2204
10
        if (!(Imm == 1 || Imm == -1 ||
2205
10
              
(6
(Imm % 4 == 0)6
&&
Imm < 284
&&
Imm > 04
)))
2206
2
          return Error(IDLoc, "immediate operand value out of range");
2207
8
        break;
2208
8
      case Mips::ANDI16_MM:
2209
4
        Opnd = Inst.getOperand(2);
2210
4
        if (!Opnd.isImm())
2211
0
          return Error(IDLoc, "expected immediate operand kind");
2212
4
        Imm = Opnd.getImm();
2213
4
        if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2214
4
              Imm == 15 || Imm == 16 || Imm == 31 || 
Imm == 321
||
Imm == 631
||
2215
4
              
Imm == 641
||
Imm == 2551
||
Imm == 327681
||
Imm == 655351
))
2216
1
          return Error(IDLoc, "immediate operand value out of range");
2217
3
        break;
2218
12
      case Mips::LBU16_MM:
2219
12
        Opnd = Inst.getOperand(2);
2220
12
        if (!Opnd.isImm())
2221
0
          return Error(IDLoc, "expected immediate operand kind");
2222
12
        Imm = Opnd.getImm();
2223
12
        if (Imm < -1 || 
Imm > 148
)
2224
4
          return Error(IDLoc, "immediate operand value out of range");
2225
8
        break;
2226
8
      case Mips::SB16_MM:
2227
6
      case Mips::SB16_MMR6:
2228
6
        Opnd = Inst.getOperand(2);
2229
6
        if (!Opnd.isImm())
2230
0
          return Error(IDLoc, "expected immediate operand kind");
2231
6
        Imm = Opnd.getImm();
2232
6
        if (Imm < 0 || Imm > 15)
2233
2
          return Error(IDLoc, "immediate operand value out of range");
2234
4
        break;
2235
14
      case Mips::LHU16_MM:
2236
14
      case Mips::SH16_MM:
2237
14
      case Mips::SH16_MMR6:
2238
14
        Opnd = Inst.getOperand(2);
2239
14
        if (!Opnd.isImm())
2240
0
          return Error(IDLoc, "expected immediate operand kind");
2241
14
        Imm = Opnd.getImm();
2242
14
        if (Imm < 0 || Imm > 30 || 
(Imm % 2 != 0)8
)
2243
6
          return Error(IDLoc, "immediate operand value out of range");
2244
8
        break;
2245
18
      case Mips::LW16_MM:
2246
18
      case Mips::SW16_MM:
2247
18
      case Mips::SW16_MMR6:
2248
18
        Opnd = Inst.getOperand(2);
2249
18
        if (!Opnd.isImm())
2250
0
          return Error(IDLoc, "expected immediate operand kind");
2251
18
        Imm = Opnd.getImm();
2252
18
        if (Imm < 0 || Imm > 60 || 
(Imm % 4 != 0)12
)
2253
6
          return Error(IDLoc, "immediate operand value out of range");
2254
12
        break;
2255
12
      case Mips::ADDIUPC_MM:
2256
12
        Opnd = Inst.getOperand(1);
2257
12
        if (!Opnd.isImm())
2258
0
          return Error(IDLoc, "expected immediate operand kind");
2259
12
        Imm = Opnd.getImm();
2260
12
        if ((Imm % 4 != 0) || 
!isInt<25>(Imm)11
)
2261
3
          return Error(IDLoc, "immediate operand value out of range");
2262
9
        break;
2263
12
      case Mips::LWP_MM:
2264
12
      case Mips::SWP_MM:
2265
12
        if (Inst.getOperand(0).getReg() == Mips::RA)
2266
4
          return Error(IDLoc, "invalid operand for instruction");
2267
8
        break;
2268
8
      case Mips::MOVEP_MM:
2269
6
      case Mips::MOVEP_MMR6: {
2270
6
        unsigned R0 = Inst.getOperand(0).getReg();
2271
6
        unsigned R1 = Inst.getOperand(1).getReg();
2272
6
        bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2273
6
                        
(2
R0 == Mips::A12
&&
R1 == Mips::A32
) ||
2274
6
                        
(2
R0 == Mips::A22
&&
R1 == Mips::A30
) ||
2275
6
                        
(2
R0 == Mips::A02
&&
R1 == Mips::S50
) ||
2276
6
                        
(2
R0 == Mips::A02
&&
R1 == Mips::S60
) ||
2277
6
                        
(2
R0 == Mips::A02
&&
R1 == Mips::A10
) ||
2278
6
                        
(2
R0 == Mips::A02
&&
R1 == Mips::A20
) ||
2279
6
                        
(2
R0 == Mips::A02
&&
R1 == Mips::A30
));
2280
6
        if (!RegPair)
2281
2
          return Error(IDLoc, "invalid operand for instruction");
2282
4
        break;
2283
4
      }
2284
2.13k
    }
2285
2.13k
  }
2286
35.5k
2287
35.5k
  bool FillDelaySlot =
2288
35.5k
      MCID.hasDelaySlot() && 
AssemblerOptions.back()->isReorder()1.37k
;
2289
35.5k
  if (FillDelaySlot)
2290
1.09k
    TOut.emitDirectiveSetNoReorder();
2291
35.5k
2292
35.5k
  MacroExpanderResultTy ExpandResult =
2293
35.5k
      tryExpandInstruction(Inst, IDLoc, Out, STI);
2294
35.5k
  switch (ExpandResult) {
2295
35.5k
  case MER_NotAMacro:
2296
31.6k
    Out.EmitInstruction(Inst, *STI);
2297
31.6k
    break;
2298
35.5k
  case MER_Success:
2299
3.84k
    break;
2300
35.5k
  case MER_Fail:
2301
59
    return true;
2302
35.4k
  }
2303
35.4k
2304
35.4k
  // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2305
35.4k
  // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2306
35.4k
  if (inMicroMipsMode()) {
2307
2.09k
    TOut.setUsesMicroMips();
2308
2.09k
    TOut.updateABIInfo(*this);
2309
2.09k
  }
2310
35.4k
2311
35.4k
  // If this instruction has a delay slot and .set reorder is active,
2312
35.4k
  // emit a NOP after it.
2313
35.4k
  if (FillDelaySlot) {
2314
1.07k
    TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2315
1.07k
    TOut.emitDirectiveSetReorder();
2316
1.07k
  }
2317
35.4k
2318
35.4k
  if ((Inst.getOpcode() == Mips::JalOneReg ||
2319
35.4k
       
Inst.getOpcode() == Mips::JalTwoReg35.4k
||
ExpandedJalSym35.3k
) &&
2320
35.4k
      
isPicAndNotNxxAbi()121
) {
2321
47
    if (IsCpRestoreSet) {
2322
26
      // We need a NOP between the JALR and the LW:
2323
26
      // If .set reorder has been used, we've already emitted a NOP.
2324
26
      // If .set noreorder has been used, we need to emit a NOP at this point.
2325
26
      if (!AssemblerOptions.back()->isReorder())
2326
15
        TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2327
15
                                STI);
2328
26
2329
26
      // Load the $gp from the stack.
2330
26
      TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2331
26
    } else
2332
21
      Warning(IDLoc, "no .cprestore used in PIC mode");
2333
47
  }
2334
35.4k
2335
35.4k
  return false;
2336
35.4k
}
2337
2338
MipsAsmParser::MacroExpanderResultTy
2339
MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2340
35.5k
                                    const MCSubtargetInfo *STI) {
2341
35.5k
  switch (Inst.getOpcode()) {
2342
35.5k
  default:
2343
30.6k
    return MER_NotAMacro;
2344
35.5k
  case Mips::LoadImm32:
2345
206
    return expandLoadImm(Inst, true, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2346
35.5k
  case Mips::LoadImm64:
2347
279
    return expandLoadImm(Inst, false, IDLoc, Out, STI) ? 
MER_Fail1
:
MER_Success278
;
2348
35.5k
  case Mips::LoadAddrImm32:
2349
572
  case Mips::LoadAddrImm64:
2350
572
    assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2351
572
    assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2352
572
           "expected immediate operand kind");
2353
572
2354
572
    return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2355
572
                             Inst.getOperand(1),
2356
572
                             Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2357
572
                             Out, STI)
2358
572
               ? 
MER_Fail8
2359
572
               : 
MER_Success564
;
2360
572
  case Mips::LoadAddrReg32:
2361
507
  case Mips::LoadAddrReg64:
2362
507
    assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2363
507
    assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2364
507
    assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2365
507
           "expected immediate operand kind");
2366
507
2367
507
    return expandLoadAddress(Inst.getOperand(0).getReg(),
2368
507
                             Inst.getOperand(1).getReg(), Inst.getOperand(2),
2369
507
                             Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2370
507
                             Out, STI)
2371
507
               ? 
MER_Fail7
2372
507
               : 
MER_Success500
;
2373
507
  case Mips::B_MM_Pseudo:
2374
26
  case Mips::B_MMR6_Pseudo:
2375
26
    return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? 
MER_Fail4
2376
26
                                                             : 
MER_Success22
;
2377
26
  case Mips::SWM_MM:
2378
22
  case Mips::LWM_MM:
2379
22
    return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? 
MER_Fail0
2380
22
                                                          : MER_Success;
2381
59
  case Mips::JalOneReg:
2382
59
  case Mips::JalTwoReg:
2383
59
    return expandJalWithRegs(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2384
65
  case Mips::BneImm:
2385
65
  case Mips::BeqImm:
2386
65
  case Mips::BEQLImmMacro:
2387
65
  case Mips::BNELImmMacro:
2388
65
    return expandBranchImm(Inst, IDLoc, Out, STI) ? 
MER_Fail4
:
MER_Success61
;
2389
258
  case Mips::BLT:
2390
258
  case Mips::BLE:
2391
258
  case Mips::BGE:
2392
258
  case Mips::BGT:
2393
258
  case Mips::BLTU:
2394
258
  case Mips::BLEU:
2395
258
  case Mips::BGEU:
2396
258
  case Mips::BGTU:
2397
258
  case Mips::BLTL:
2398
258
  case Mips::BLEL:
2399
258
  case Mips::BGEL:
2400
258
  case Mips::BGTL:
2401
258
  case Mips::BLTUL:
2402
258
  case Mips::BLEUL:
2403
258
  case Mips::BGEUL:
2404
258
  case Mips::BGTUL:
2405
258
  case Mips::BLTImmMacro:
2406
258
  case Mips::BLEImmMacro:
2407
258
  case Mips::BGEImmMacro:
2408
258
  case Mips::BGTImmMacro:
2409
258
  case Mips::BLTUImmMacro:
2410
258
  case Mips::BLEUImmMacro:
2411
258
  case Mips::BGEUImmMacro:
2412
258
  case Mips::BGTUImmMacro:
2413
258
  case Mips::BLTLImmMacro:
2414
258
  case Mips::BLELImmMacro:
2415
258
  case Mips::BGELImmMacro:
2416
258
  case Mips::BGTLImmMacro:
2417
258
  case Mips::BLTULImmMacro:
2418
258
  case Mips::BLEULImmMacro:
2419
258
  case Mips::BGEULImmMacro:
2420
258
  case Mips::BGTULImmMacro:
2421
258
    return expandCondBranches(Inst, IDLoc, Out, STI) ? 
MER_Fail17
:
MER_Success241
;
2422
258
  case Mips::SDivMacro:
2423
100
  case Mips::SDivIMacro:
2424
100
  case Mips::SRemMacro:
2425
100
  case Mips::SRemIMacro:
2426
100
    return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? 
MER_Fail0
2427
100
                                                            : MER_Success;
2428
172
  case Mips::DSDivMacro:
2429
172
  case Mips::DSDivIMacro:
2430
172
  case Mips::DSRemMacro:
2431
172
  case Mips::DSRemIMacro:
2432
172
    return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? 
MER_Fail0
2433
172
                                                           : MER_Success;
2434
172
  case Mips::UDivMacro:
2435
76
  case Mips::UDivIMacro:
2436
76
  case Mips::URemMacro:
2437
76
  case Mips::URemIMacro:
2438
76
    return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? 
MER_Fail0
2439
76
                                                             : MER_Success;
2440
120
  case Mips::DUDivMacro:
2441
120
  case Mips::DUDivIMacro:
2442
120
  case Mips::DURemMacro:
2443
120
  case Mips::DURemIMacro:
2444
120
    return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? 
MER_Fail0
2445
120
                                                            : MER_Success;
2446
120
  case Mips::PseudoTRUNC_W_S:
2447
13
    return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? 
MER_Fail0
2448
13
                                                            : MER_Success;
2449
120
  case Mips::PseudoTRUNC_W_D32:
2450
6
    return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? 
MER_Fail0
2451
6
                                                           : MER_Success;
2452
120
  case Mips::PseudoTRUNC_W_D:
2453
7
    return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? 
MER_Fail0
2454
7
                                                          : MER_Success;
2455
120
2456
120
  case Mips::LoadImmSingleGPR:
2457
66
    return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
2458
66
               ? 
MER_Fail0
2459
66
               : MER_Success;
2460
120
  case Mips::LoadImmSingleFGR:
2461
66
    return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
2462
66
               ? 
MER_Fail0
2463
66
               : MER_Success;
2464
120
  case Mips::LoadImmDoubleGPR:
2465
77
    return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
2466
77
               ? 
MER_Fail0
2467
77
               : MER_Success;
2468
120
  case Mips::LoadImmDoubleFGR:
2469
52
      return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
2470
52
               ? 
MER_Fail0
2471
52
               : MER_Success;
2472
120
  case Mips::LoadImmDoubleFGR_32:
2473
39
    return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
2474
39
               ? 
MER_Fail0
2475
39
               : MER_Success;
2476
120
  case Mips::Ulh:
2477
45
    return expandUlh(Inst, true, IDLoc, Out, STI) ? 
MER_Fail6
:
MER_Success39
;
2478
120
  case Mips::Ulhu:
2479
51
    return expandUlh(Inst, false, IDLoc, Out, STI) ? 
MER_Fail6
:
MER_Success45
;
2480
120
  case Mips::Ush:
2481
48
    return expandUsh(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2482
121
  case Mips::Ulw:
2483
121
  case Mips::Usw:
2484
121
    return expandUxw(Inst, IDLoc, Out, STI) ? 
MER_Fail6
:
MER_Success115
;
2485
121
  case Mips::NORImm:
2486
56
  case Mips::NORImm64:
2487
56
    return expandAliasImmediate(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2488
56
  case Mips::SGE:
2489
8
  case Mips::SGEU:
2490
8
    return expandSge(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2491
20
  case Mips::SGEImm:
2492
20
  case Mips::SGEUImm:
2493
20
  case Mips::SGEImm64:
2494
20
  case Mips::SGEUImm64:
2495
20
    return expandSgeImm(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2496
20
  case Mips::SGTImm:
2497
12
  case Mips::SGTUImm:
2498
12
  case Mips::SGTImm64:
2499
12
  case Mips::SGTUImm64:
2500
12
    return expandSgtImm(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2501
27
  case Mips::SLTImm64:
2502
27
    if (isInt<16>(Inst.getOperand(2).getImm())) {
2503
7
      Inst.setOpcode(Mips::SLTi64);
2504
7
      return MER_NotAMacro;
2505
7
    }
2506
20
    return expandAliasImmediate(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2507
33
  case Mips::SLTUImm64:
2508
33
    if (isInt<16>(Inst.getOperand(2).getImm())) {
2509
13
      Inst.setOpcode(Mips::SLTiu64);
2510
13
      return MER_NotAMacro;
2511
13
    }
2512
20
    return expandAliasImmediate(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2513
896
  case Mips::ADDi:   case Mips::ADDi_MM:
2514
896
  case Mips::ADDiu:  case Mips::ADDiu_MM:
2515
896
  case Mips::SLTi:   case Mips::SLTi_MM:
2516
896
  case Mips::SLTiu:  case Mips::SLTiu_MM:
2517
896
    if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2518
896
        Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2519
552
      int64_t ImmValue = Inst.getOperand(2).getImm();
2520
552
      if (isInt<16>(ImmValue))
2521
472
        return MER_NotAMacro;
2522
80
      return expandAliasImmediate(Inst, IDLoc, Out, STI) ? 
MER_Fail0
2523
80
                                                         : MER_Success;
2524
80
    }
2525
344
    return MER_NotAMacro;
2526
344
  
case Mips::ANDi: 256
case Mips::ANDi_MM: 256
case Mips::ANDi64:
2527
256
  case Mips::ORi:   case Mips::ORi_MM:   case Mips::ORi64:
2528
256
  case Mips::XORi:  case Mips::XORi_MM:  case Mips::XORi64:
2529
256
    if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2530
256
        Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2531
256
      int64_t ImmValue = Inst.getOperand(2).getImm();
2532
256
      if (isUInt<16>(ImmValue))
2533
118
        return MER_NotAMacro;
2534
138
      return expandAliasImmediate(Inst, IDLoc, Out, STI) ? 
MER_Fail0
2535
138
                                                         : MER_Success;
2536
138
    }
2537
0
    return MER_NotAMacro;
2538
40
  case Mips::ROL:
2539
40
  case Mips::ROR:
2540
40
    return expandRotation(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2541
120
  case Mips::ROLImm:
2542
120
  case Mips::RORImm:
2543
120
    return expandRotationImm(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2544
120
  case Mips::DROL:
2545
20
  case Mips::DROR:
2546
20
    return expandDRotation(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2547
130
  case Mips::DROLImm:
2548
130
  case Mips::DRORImm:
2549
130
    return expandDRotationImm(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2550
130
  case Mips::ABSMacro:
2551
2
    return expandAbs(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2552
130
  case Mips::MULImmMacro:
2553
49
  case Mips::DMULImmMacro:
2554
49
    return expandMulImm(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2555
49
  case Mips::MULOMacro:
2556
21
  case Mips::DMULOMacro:
2557
21
    return expandMulO(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2558
21
  case Mips::MULOUMacro:
2559
21
  case Mips::DMULOUMacro:
2560
21
    return expandMulOU(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2561
21
  case Mips::DMULMacro:
2562
7
    return expandDMULMacro(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2563
21
  case Mips::LDMacro:
2564
12
  case Mips::SDMacro:
2565
12
    return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2566
12
                                 Inst.getOpcode() == Mips::LDMacro)
2567
12
               ? 
MER_Fail0
2568
12
               : MER_Success;
2569
12
  case Mips::SDC1_M1:
2570
2
    return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2571
2
               ? 
MER_Fail0
2572
2
               : MER_Success;
2573
12
  case Mips::SEQMacro:
2574
10
    return expandSeq(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2575
20
  case Mips::SEQIMacro:
2576
20
    return expandSeqI(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2577
42
  case Mips::MFTC0:   case Mips::MTTC0:
2578
42
  case Mips::MFTGPR:  case Mips::MTTGPR:
2579
42
  case Mips::MFTLO:   case Mips::MTTLO:
2580
42
  case Mips::MFTHI:   case Mips::MTTHI:
2581
42
  case Mips::MFTACX:  case Mips::MTTACX:
2582
42
  case Mips::MFTDSP:  case Mips::MTTDSP:
2583
42
  case Mips::MFTC1:   case Mips::MTTC1:
2584
42
  case Mips::MFTHC1:  case Mips::MTTHC1:
2585
42
  case Mips::CFTC1:   case Mips::CTTC1:
2586
42
    return expandMXTRAlias(Inst, IDLoc, Out, STI) ? 
MER_Fail0
: MER_Success;
2587
35.5k
  }
2588
35.5k
}
2589
2590
bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2591
                                      MCStreamer &Out,
2592
59
                                      const MCSubtargetInfo *STI) {
2593
59
  MipsTargetStreamer &TOut = getTargetStreamer();
2594
59
2595
59
  // Create a JALR instruction which is going to replace the pseudo-JAL.
2596
59
  MCInst JalrInst;
2597
59
  JalrInst.setLoc(IDLoc);
2598
59
  const MCOperand FirstRegOp = Inst.getOperand(0);
2599
59
  const unsigned Opcode = Inst.getOpcode();
2600
59
2601
59
  if (Opcode == Mips::JalOneReg) {
2602
30
    // jal $rs => jalr $rs
2603
30
    if (IsCpRestoreSet && 
inMicroMipsMode()22
) {
2604
2
      JalrInst.setOpcode(Mips::JALRS16_MM);
2605
2
      JalrInst.addOperand(FirstRegOp);
2606
28
    } else if (inMicroMipsMode()) {
2607
2
      JalrInst.setOpcode(hasMips32r6() ? 
Mips::JALRC16_MMR60
: Mips::JALR16_MM);
2608
2
      JalrInst.addOperand(FirstRegOp);
2609
26
    } else {
2610
26
      JalrInst.setOpcode(Mips::JALR);
2611
26
      JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2612
26
      JalrInst.addOperand(FirstRegOp);
2613
26
    }
2614
30
  } else 
if (29
Opcode == Mips::JalTwoReg29
) {
2615
29
    // jal $rd, $rs => jalr $rd, $rs
2616
29
    if (IsCpRestoreSet && 
inMicroMipsMode()22
)
2617
2
      JalrInst.setOpcode(Mips::JALRS_MM);
2618
27
    else
2619
27
      JalrInst.setOpcode(inMicroMipsMode() ? 
Mips::JALR_MM2
:
Mips::JALR25
);
2620
29
    JalrInst.addOperand(FirstRegOp);
2621
29
    const MCOperand SecondRegOp = Inst.getOperand(1);
2622
29
    JalrInst.addOperand(SecondRegOp);
2623
29
  }
2624
59
  Out.EmitInstruction(JalrInst, *STI);
2625
59
2626
59
  // If .set reorder is active and branch instruction has a delay slot,
2627
59
  // emit a NOP after it.
2628
59
  const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2629
59
  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2630
21
    TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2631
21
                            STI);
2632
59
2633
59
  return false;
2634
59
}
2635
2636
/// Can the value be represented by a unsigned N-bit value and a shift left?
2637
518
template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2638
518
  unsigned BitNum = findFirstSet(x);
2639
518
2640
518
  return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2641
518
}
2642
2643
/// Load (or add) an immediate into a register.
2644
///
2645
/// @param ImmValue     The immediate to load.
2646
/// @param DstReg       The register that will hold the immediate.
2647
/// @param SrcReg       A register to add to the immediate or Mips::NoRegister
2648
///                     for a simple initialization.
2649
/// @param Is32BitImm   Is ImmValue 32-bit or 64-bit?
2650
/// @param IsAddress    True if the immediate represents an address. False if it
2651
///                     is an integer.
2652
/// @param IDLoc        Location of the immediate in the source file.
2653
bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2654
                                  unsigned SrcReg, bool Is32BitImm,
2655
                                  bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2656
2.98k
                                  const MCSubtargetInfo *STI) {
2657
2.98k
  MipsTargetStreamer &TOut = getTargetStreamer();
2658
2.98k
2659
2.98k
  if (!Is32BitImm && 
!isGP64bit()795
) {
2660
1
    Error(IDLoc, "instruction requires a 64-bit architecture");
2661
1
    return true;
2662
1
  }
2663
2.98k
2664
2.98k
  if (Is32BitImm) {
2665
2.19k
    if (isInt<32>(ImmValue) || 
isUInt<32>(ImmValue)388
) {
2666
2.18k
      // Sign extend up to 64-bit so that the predicates match the hardware
2667
2.18k
      // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2668
2.18k
      // true.
2669
2.18k
      ImmValue = SignExtend64<32>(ImmValue);
2670
2.18k
    } else {
2671
6
      Error(IDLoc, "instruction requires a 32-bit immediate");
2672
6
      return true;
2673
6
    }
2674
2.97k
  }
2675
2.97k
2676
2.97k
  unsigned ZeroReg = IsAddress ? 
ABI.GetNullPtr()1.42k
:
ABI.GetZeroReg()1.55k
;
2677
2.97k
  unsigned AdduOp = !Is32BitImm ? 
Mips::DADDu794
:
Mips::ADDu2.18k
;
2678
2.97k
2679
2.97k
  bool UseSrcReg = false;
2680
2.97k
  if (SrcReg != Mips::NoRegister)
2681
586
    UseSrcReg = true;
2682
2.97k
2683
2.97k
  unsigned TmpReg = DstReg;
2684
2.97k
  if (UseSrcReg &&
2685
2.97k
      
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)586
) {
2686
178
    // At this point we need AT to perform the expansions and we exit if it is
2687
178
    // not available.
2688
178
    unsigned ATReg = getATReg(IDLoc);
2689
178
    if (!ATReg)
2690
0
      return true;
2691
178
    TmpReg = ATReg;
2692
178
  }
2693
2.97k
2694
2.97k
  if (isInt<16>(ImmValue)) {
2695
825
    if (!UseSrcReg)
2696
712
      SrcReg = ZeroReg;
2697
825
2698
825
    // This doesn't quite follow the usual ABI expectations for N32 but matches
2699
825
    // traditional assembler behaviour. N32 would normally use addiu for both
2700
825
    // integers and addresses.
2701
825
    if (IsAddress && 
!Is32BitImm254
) {
2702
28
      TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2703
28
      return false;
2704
28
    }
2705
797
2706
797
    TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2707
797
    return false;
2708
797
  }
2709
2.15k
2710
2.15k
  if (isUInt<16>(ImmValue)) {
2711
221
    unsigned TmpReg = DstReg;
2712
221
    if (SrcReg == DstReg) {
2713
6
      TmpReg = getATReg(IDLoc);
2714
6
      if (!TmpReg)
2715
0
        return true;
2716
221
    }
2717
221
2718
221
    TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2719
221
    if (UseSrcReg)
2720
44
      TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2721
221
    return false;
2722
221
  }
2723
1.93k
2724
1.93k
  if (isInt<32>(ImmValue) || 
isUInt<32>(ImmValue)656
) {
2725
1.41k
    warnIfNoMacro(IDLoc);
2726
1.41k
2727
1.41k
    uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2728
1.41k
    uint16_t Bits15To0 = ImmValue & 0xffff;
2729
1.41k
    if (!Is32BitImm && 
!isInt<32>(ImmValue)232
) {
2730
138
      // Traditional behaviour seems to special case this particular value. It's
2731
138
      // not clear why other masks are handled differently.
2732
138
      if (ImmValue == 0xffffffff) {
2733
28
        TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2734
28
        TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2735
28
        if (UseSrcReg)
2736
4
          TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2737
28
        return false;
2738
28
      }
2739
110
2740
110
      // Expand to an ORi instead of a LUi to avoid sign-extending into the
2741
110
      // upper 32 bits.
2742
110
      TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2743
110
      TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2744
110
      if (Bits15To0)
2745
62
        TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2746
110
      if (UseSrcReg)
2747
32
        TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2748
110
      return false;
2749
110
    }
2750
1.27k
2751
1.27k
    TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2752
1.27k
    if (Bits15To0)
2753
757
      TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2754
1.27k
    if (UseSrcReg)
2755
377
      TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2756
1.27k
    return false;
2757
1.27k
  }
2758
518
2759
518
  if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2760
60
    if (Is32BitImm) {
2761
0
      Error(IDLoc, "instruction requires a 32-bit immediate");
2762
0
      return true;
2763
0
    }
2764
60
2765
60
    // Traditionally, these immediates are shifted as little as possible and as
2766
60
    // such we align the most significant bit to bit 15 of our temporary.
2767
60
    unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2768
60
    unsigned LastSet = findLastSet((uint64_t)ImmValue);
2769
60
    unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2770
60
    uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2771
60
    TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2772
60
    TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2773
60
2774
60
    if (UseSrcReg)
2775
0
      TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2776
60
2777
60
    return false;
2778
60
  }
2779
458
2780
458
  warnIfNoMacro(IDLoc);
2781
458
2782
458
  // The remaining case is packed with a sequence of dsll and ori with zeros
2783
458
  // being omitted and any neighbouring dsll's being coalesced.
2784
458
  // The highest 32-bit's are equivalent to a 32-bit immediate load.
2785
458
2786
458
  // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2787
458
  if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2788
458
                    IDLoc, Out, STI))
2789
0
    return false;
2790
458
2791
458
  // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2792
458
  // skip it and defer the shift to the next chunk.
2793
458
  unsigned ShiftCarriedForwards = 16;
2794
1.37k
  for (int BitNum = 16; BitNum >= 0; 
BitNum -= 16916
) {
2795
916
    uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2796
916
2797
916
    if (ImmChunk != 0) {
2798
791
      TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2799
791
      TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2800
791
      ShiftCarriedForwards = 0;
2801
791
    }
2802
916
2803
916
    ShiftCarriedForwards += 16;
2804
916
  }
2805
458
  ShiftCarriedForwards -= 16;
2806
458
2807
458
  // Finish any remaining shifts left by trailing zeros.
2808
458
  if (ShiftCarriedForwards)
2809
61
    TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2810
458
2811
458
  if (UseSrcReg)
2812
16
    TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2813
458
2814
458
  return false;
2815
458
}
2816
2817
bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2818
485
                                  MCStreamer &Out, const MCSubtargetInfo *STI) {
2819
485
  const MCOperand &ImmOp = Inst.getOperand(1);
2820
485
  assert(ImmOp.isImm() && "expected immediate operand kind");
2821
485
  const MCOperand &DstRegOp = Inst.getOperand(0);
2822
485
  assert(DstRegOp.isReg() && "expected register operand kind");
2823
485
2824
485
  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2825
485
                    Is32BitImm, false, IDLoc, Out, STI))
2826
1
    return true;
2827
484
2828
484
  return false;
2829
484
}
2830
2831
bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2832
                                      const MCOperand &Offset,
2833
                                      bool Is32BitAddress, SMLoc IDLoc,
2834
                                      MCStreamer &Out,
2835
1.07k
                                      const MCSubtargetInfo *STI) {
2836
1.07k
  // la can't produce a usable address when addresses are 64-bit.
2837
1.07k
  if (Is32BitAddress && 
ABI.ArePtrs64bit()528
) {
2838
3
    // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2839
3
    //        We currently can't do this because we depend on the equality
2840
3
    //        operator and N64 can end up with a GPR32/GPR64 mismatch.
2841
3
    Error(IDLoc, "la used to load 64-bit address");
2842
3
    // Continue as if we had 'dla' instead.
2843
3
    Is32BitAddress = false;
2844
3
    return true;
2845
3
  }
2846
1.07k
2847
1.07k
  // dla requires 64-bit addresses.
2848
1.07k
  if (!Is32BitAddress && 
!hasMips3()551
) {
2849
0
    Error(IDLoc, "instruction requires a 64-bit architecture");
2850
0
    return true;
2851
0
  }
2852
1.07k
2853
1.07k
  if (!Offset.isImm())
2854
138
    return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2855
138
                                   Is32BitAddress, IDLoc, Out, STI);
2856
938
2857
938
  if (!ABI.ArePtrs64bit()) {
2858
592
    // Continue as if we had 'la' whether we had 'la' or 'dla'.
2859
592
    Is32BitAddress = true;
2860
592
  }
2861
938
2862
938
  return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2863
938
                       IDLoc, Out, STI);
2864
938
}
2865
2866
bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2867
                                            unsigned DstReg, unsigned SrcReg,
2868
                                            bool Is32BitSym, SMLoc IDLoc,
2869
                                            MCStreamer &Out,
2870
138
                                            const MCSubtargetInfo *STI) {
2871
138
  // FIXME: These expansions do not respect -mxgot.
2872
138
  MipsTargetStreamer &TOut = getTargetStreamer();
2873
138
  bool UseSrcReg = SrcReg != Mips::NoRegister;
2874
138
  warnIfNoMacro(IDLoc);
2875
138
2876
138
  if (inPicMode() && 
ABI.IsO32()51
) {
2877
29
    MCValue Res;
2878
29
    if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2879
0
      Error(IDLoc, "expected relocatable expression");
2880
0
      return true;
2881
0
    }
2882
29
    if (Res.getSymB() != nullptr) {
2883
0
      Error(IDLoc, "expected relocatable expression with only one symbol");
2884
0
      return true;
2885
0
    }
2886
29
2887
29
    // The case where the result register is $25 is somewhat special. If the
2888
29
    // symbol in the final relocation is external and not modified with a
2889
29
    // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2890
29
    if ((DstReg == Mips::T9 || 
DstReg == Mips::T9_6414
) &&
!UseSrcReg15
&&
2891
29
        
Res.getConstant() == 07
&&
2892
29
        
!(5
Res.getSymA()->getSymbol().isInSection()5
||
2893
5
          Res.getSymA()->getSymbol().isTemporary() ||
2894
5
          
(2
Res.getSymA()->getSymbol().isELF()2
&&
2895
2
           cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2896
2
               ELF::STB_LOCAL))) {
2897
2
      const MCExpr *CallExpr =
2898
2
          MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2899
2
      TOut.emitRRX(Mips::LW, DstReg, GPReg, MCOperand::createExpr(CallExpr),
2900
2
                   IDLoc, STI);
2901
2
      return false;
2902
2
    }
2903
27
2904
27
    // The remaining cases are:
2905
27
    //   External GOT: lw $tmp, %got(symbol+offset)($gp)
2906
27
    //                >addiu $tmp, $tmp, %lo(offset)
2907
27
    //                >addiu $rd, $tmp, $rs
2908
27
    //   Local GOT:    lw $tmp, %got(symbol+offset)($gp)
2909
27
    //                 addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2910
27
    //                >addiu $rd, $tmp, $rs
2911
27
    // The addiu's marked with a '>' may be omitted if they are redundant. If
2912
27
    // this happens then the last instruction must use $rd as the result
2913
27
    // register.
2914
27
    const MipsMCExpr *GotExpr =
2915
27
        MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2916
27
    const MCExpr *LoExpr = nullptr;
2917
27
    if (Res.getSymA()->getSymbol().isInSection() ||
2918
27
        Res.getSymA()->getSymbol().isTemporary())
2919
5
      LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2920
22
    else if (Res.getConstant() != 0) {
2921
12
      // External symbols fully resolve the symbol with just the %got(symbol)
2922
12
      // but we must still account for any offset to the symbol for expressions
2923
12
      // like symbol+8.
2924
12
      LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2925
12
    }
2926
27
2927
27
    unsigned TmpReg = DstReg;
2928
27
    if (UseSrcReg &&
2929
27
        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2930
16
                                                               SrcReg)) {
2931
8
      // If $rs is the same as $rd, we need to use AT.
2932
8
      // If it is not available we exit.
2933
8
      unsigned ATReg = getATReg(IDLoc);
2934
8
      if (!ATReg)
2935
0
        return true;
2936
8
      TmpReg = ATReg;
2937
8
    }
2938
27
2939
27
    TOut.emitRRX(Mips::LW, TmpReg, GPReg, MCOperand::createExpr(GotExpr), IDLoc,
2940
27
                 STI);
2941
27
2942
27
    if (LoExpr)
2943
17
      TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2944
17
                   IDLoc, STI);
2945
27
2946
27
    if (UseSrcReg)
2947
16
      TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2948
27
2949
27
    return false;
2950
109
  }
2951
109
2952
109
  if (inPicMode() && 
ABI.ArePtrs64bit()22
) {
2953
22
    MCValue Res;
2954
22
    if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2955
0
      Error(IDLoc, "expected relocatable expression");
2956
0
      return true;
2957
0
    }
2958
22
    if (Res.getSymB() != nullptr) {
2959
0
      Error(IDLoc, "expected relocatable expression with only one symbol");
2960
0
      return true;
2961
0
    }
2962
22
2963
22
    // The case where the result register is $25 is somewhat special. If the
2964
22
    // symbol in the final relocation is external and not modified with a
2965
22
    // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT_DISP.
2966
22
    if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && 
!UseSrcReg11
&&
2967
22
        
Res.getConstant() == 05
&&
2968
22
        
!(2
Res.getSymA()->getSymbol().isInSection()2
||
2969
2
          Res.getSymA()->getSymbol().isTemporary() ||
2970
2
          
(1
Res.getSymA()->getSymbol().isELF()1
&&
2971
1
           cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2972
1
               ELF::STB_LOCAL))) {
2973
1
      const MCExpr *CallExpr =
2974
1
          MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2975
1
      TOut.emitRRX(Mips::LD, DstReg, GPReg, MCOperand::createExpr(CallExpr),
2976
1
                   IDLoc, STI);
2977
1
      return false;
2978
1
    }
2979
21
2980
21
    // The remaining cases are:
2981
21
    //   Small offset: ld $tmp, %got_disp(symbol)($gp)
2982
21
    //                >daddiu $tmp, $tmp, offset
2983
21
    //                >daddu $rd, $tmp, $rs
2984
21
    // The daddiu's marked with a '>' may be omitted if they are redundant. If
2985
21
    // this happens then the last instruction must use $rd as the result
2986
21
    // register.
2987
21
    const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP,
2988
21
                                                   Res.getSymA(),
2989
21
                                                   getContext());
2990
21
    const MCExpr *LoExpr = nullptr;
2991
21
    if (Res.getConstant() != 0) {
2992
14
      // Symbols fully resolve with just the %got_disp(symbol) but we
2993
14
      // must still account for any offset to the symbol for
2994
14
      // expressions like symbol+8.
2995
14
      LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2996
14
2997
14
      // FIXME: Offsets greater than 16 bits are not yet implemented.
2998
14
      // FIXME: The correct range is a 32-bit sign-extended number.
2999
14
      if (Res.getConstant() < -0x8000 || 
Res.getConstant() > 0x7fff10
) {
3000
8
        Error(IDLoc, "macro instruction uses large offset, which is not "
3001
8
                     "currently supported");
3002
8
        return true;
3003
8
      }
3004
13
    }
3005
13
3006
13
    unsigned TmpReg = DstReg;
3007
13
    if (UseSrcReg &&
3008
13
        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3009
8
                                                               SrcReg)) {
3010
4
      // If $rs is the same as $rd, we need to use AT.
3011
4
      // If it is not available we exit.
3012
4
      unsigned ATReg = getATReg(IDLoc);
3013
4
      if (!ATReg)
3014
0
        return true;
3015
4
      TmpReg = ATReg;
3016
4
    }
3017
13
3018
13
    TOut.emitRRX(Mips::LD, TmpReg, GPReg, MCOperand::createExpr(GotExpr), IDLoc,
3019
13
                 STI);
3020
13
3021
13
    if (LoExpr)
3022
6
      TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3023
6
                   IDLoc, STI);
3024
13
3025
13
    if (UseSrcReg)
3026
8
      TOut.emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3027
13
3028
13
    return false;
3029
87
  }
3030
87
3031
87
  const MipsMCExpr *HiExpr =
3032
87
      MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3033
87
  const MipsMCExpr *LoExpr =
3034
87
      MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3035
87
3036
87
  // This is the 64-bit symbol address expansion.
3037
87
  if (ABI.ArePtrs64bit() && 
isGP64bit()21
) {
3038
21
    // We need AT for the 64-bit expansion in the cases where the optional
3039
21
    // source register is the destination register and for the superscalar
3040
21
    // scheduled form.
3041
21
    //
3042
21
    // If it is not available we exit if the destination is the same as the
3043
21
    // source register.
3044
21
3045
21
    const MipsMCExpr *HighestExpr =
3046
21
        MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3047
21
    const MipsMCExpr *HigherExpr =
3048
21
        MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3049
21
3050
21
    bool RdRegIsRsReg =
3051
21
        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3052
21
3053
21
    if (canUseATReg() && 
UseSrcReg13
&&
RdRegIsRsReg8
) {
3054
4
      unsigned ATReg = getATReg(IDLoc);
3055
4
3056
4
      // If $rs is the same as $rd:
3057
4
      // (d)la $rd, sym($rd) => lui    $at, %highest(sym)
3058
4
      //                        daddiu $at, $at, %higher(sym)
3059
4
      //                        dsll   $at, $at, 16
3060
4
      //                        daddiu $at, $at, %hi(sym)
3061
4
      //                        dsll   $at, $at, 16
3062
4
      //                        daddiu $at, $at, %lo(sym)
3063
4
      //                        daddu  $rd, $at, $rd
3064
4
      TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3065
4
                  STI);
3066
4
      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3067
4
                   MCOperand::createExpr(HigherExpr), IDLoc, STI);
3068
4
      TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3069
4
      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3070
4
                   IDLoc, STI);
3071
4
      TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3072
4
      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3073
4
                   IDLoc, STI);
3074
4
      TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3075
4
3076
4
      return false;
3077
17
    } else if (canUseATReg() && 
!RdRegIsRsReg9
) {
3078
9
      unsigned ATReg = getATReg(IDLoc);
3079
9
3080
9
      // If the $rs is different from $rd or if $rs isn't specified and we
3081
9
      // have $at available:
3082
9
      // (d)la $rd, sym/sym($rs) => lui    $rd, %highest(sym)
3083
9
      //                            lui    $at, %hi(sym)
3084
9
      //                            daddiu $rd, $rd, %higher(sym)
3085
9
      //                            daddiu $at, $at, %lo(sym)
3086
9
      //                            dsll32 $rd, $rd, 0
3087
9
      //                            daddu  $rd, $rd, $at
3088
9
      //                            (daddu  $rd, $rd, $rs)
3089
9
      //
3090
9
      // Which is preferred for superscalar issue.
3091
9
      TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3092
9
                  STI);
3093
9
      TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3094
9
      TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3095
9
                   MCOperand::createExpr(HigherExpr), IDLoc, STI);
3096
9
      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3097
9
                   IDLoc, STI);
3098
9
      TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3099
9
      TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3100
9
      if (UseSrcReg)
3101
4
        TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3102
9
3103
9
      return false;
3104
9
    } else 
if (8
!canUseATReg()8
&&
!RdRegIsRsReg8
) {
3105
8
      // Otherwise, synthesize the address in the destination register
3106
8
      // serially:
3107
8
      // (d)la $rd, sym/sym($rs) => lui    $rd, %highest(sym)
3108
8
      //                            daddiu $rd, $rd, %higher(sym)
3109
8
      //                            dsll   $rd, $rd, 16
3110
8
      //                            daddiu $rd, $rd, %hi(sym)
3111
8
      //                            dsll   $rd, $rd, 16
3112
8
      //                            daddiu $rd, $rd, %lo(sym)
3113
8
      TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3114
8
                  STI);
3115
8
      TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3116
8
                   MCOperand::createExpr(HigherExpr), IDLoc, STI);
3117
8
      TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3118
8
      TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3119
8
                   MCOperand::createExpr(HiExpr), IDLoc, STI);
3120
8
      TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3121
8
      TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3122
8
                   MCOperand::createExpr(LoExpr), IDLoc, STI);
3123
8
      if (UseSrcReg)
3124
4
        TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3125
8
3126
8
      return false;
3127
8
    } else {
3128
0
      // We have a case where SrcReg == DstReg and we don't have $at
3129
0
      // available. We can't expand this case, so error out appropriately.
3130
0
      assert(SrcReg == DstReg && !canUseATReg() &&
3131
0
             "Could have expanded dla but didn't?");
3132
0
      reportParseError(IDLoc,
3133
0
                     "pseudo-instruction requires $at, which is not available");
3134
0
      return true;
3135
0
    }
3136
66
  }
3137
66
3138
66
  // And now, the 32-bit symbol address expansion:
3139
66
  // If $rs is the same as $rd:
3140
66
  // (d)la $rd, sym($rd)     => lui   $at, %hi(sym)
3141
66
  //                            ori   $at, $at, %lo(sym)
3142
66
  //                            addu  $rd, $at, $rd
3143
66
  // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3144
66
  // (d)la $rd, sym/sym($rs) => lui   $rd, %hi(sym)
3145
66
  //                            ori   $rd, $rd, %lo(sym)
3146
66
  //                            (addu $rd, $rd, $rs)
3147
66
  unsigned TmpReg = DstReg;
3148
66
  if (UseSrcReg &&
3149
66
      
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)28
) {
3150
14
    // If $rs is the same as $rd, we need to use AT.
3151
14
    // If it is not available we exit.
3152
14
    unsigned ATReg = getATReg(IDLoc);
3153
14
    if (!ATReg)
3154
0
      return true;
3155
14
    TmpReg = ATReg;
3156
14
  }
3157
66
3158
66
  TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3159
66
  TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3160
66
               IDLoc, STI);
3161
66
3162
66
  if (UseSrcReg)
3163
28
    TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3164
66
  else
3165
66
    assert(
3166
66
        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3167
66
3168
66
  return false;
3169
66
}
3170
3171
// Each double-precision register DO-D15 overlaps with two of the single
3172
// precision registers F0-F31. As an example, all of the following hold true:
3173
// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3174
73
static unsigned nextReg(unsigned Reg) {
3175
73
  if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3176
0
    return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3177
73
  switch (Reg) {
3178
73
  
default: 0
llvm_unreachable0
("Unknown register in assembly macro expansion!");
3179
73
  
case Mips::ZERO: return Mips::AT0
;
3180
73
  
case Mips::AT: return Mips::V00
;
3181
73
  
case Mips::V0: return Mips::V10
;
3182
73
  
case Mips::V1: return Mips::A00
;
3183
73
  
case Mips::A0: return Mips::A133
;
3184
73
  
case Mips::A1: return Mips::A20
;
3185
73
  
case Mips::A2: return Mips::A30
;
3186
73
  
case Mips::A3: return Mips::T00
;
3187
73
  
case Mips::T0: return Mips::T112
;
3188
73
  
case Mips::T1: return Mips::T20
;
3189
73
  
case Mips::T2: return Mips::T30
;
3190
73
  
case Mips::T3: return Mips::T40
;
3191
73
  
case Mips::T4: return Mips::T50
;
3192
73
  
case Mips::T5: return Mips::T60
;
3193
73
  
case Mips::T6: return Mips::T70
;
3194
73
  
case Mips::T7: return Mips::S00
;
3195
73
  
case Mips::S0: return Mips::S110
;
3196
73
  
case Mips::S1: return Mips::S20
;
3197
73
  
case Mips::S2: return Mips::S30
;
3198
73
  
case Mips::S3: return Mips::S40
;
3199
73
  
case Mips::S4: return Mips::S50
;
3200
73
  
case Mips::S5: return Mips::S60
;
3201
73
  
case Mips::S6: return Mips::S70
;
3202
73
  
case Mips::S7: return Mips::T80
;
3203
73
  
case Mips::T8: return Mips::T90
;
3204
73
  
case Mips::T9: return Mips::K00
;
3205
73
  
case Mips::K0: return Mips::K10
;
3206
73
  
case Mips::K1: return Mips::GP0
;
3207
73
  
case Mips::GP: return Mips::SP0
;
3208
73
  
case Mips::SP: return Mips::FP0
;
3209
73
  
case Mips::FP: return Mips::RA0
;
3210
73
  
case Mips::RA: return Mips::ZERO4
;
3211
73
  
case Mips::D0: return Mips::F12
;
3212
73
  
case Mips::D1: return Mips::F30
;
3213
73
  
case Mips::D2: return Mips::F512
;
3214
73
  
case Mips::D3: return Mips::F70
;
3215
73
  
case Mips::D4: return Mips::F90
;
3216
73
  
case Mips::D5: return Mips::F110
;
3217
73
  
case Mips::D6: return Mips::F130
;
3218
73
  
case Mips::D7: return Mips::F150
;
3219
73
  
case Mips::D8: return Mips::F170
;
3220
73
  
case Mips::D9: return Mips::F190
;
3221
73
  
case Mips::D10: return Mips::F210
;
3222
73
  
case Mips::D11: return Mips::F230
;
3223
73
  
case Mips::D12: return Mips::F250
;
3224
73
  
case Mips::D13: return Mips::F270
;
3225
73
  
case Mips::D14: return Mips::F290
;
3226
73
  
case Mips::D15: return Mips::F310
;
3227
73
  }
3228
73
}
3229
3230
// FIXME: This method is too general. In principle we should compute the number
3231
// of instructions required to synthesize the immediate inline compared to
3232
// synthesizing the address inline and relying on non .text sections.
3233
// For static O32 and N32 this may yield a small benefit, for static N64 this is
3234
// likely to yield a much larger benefit as we have to synthesize a 64bit
3235
// address to load a 64 bit value.
3236
bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3237
127
                                       MCSymbol *Sym) {
3238
127
  unsigned ATReg = getATReg(IDLoc);
3239
127
  if (!ATReg)
3240
0
    return true;
3241
127
3242
127
  if(IsPicEnabled) {
3243
57
    const MCExpr *GotSym =
3244
57
        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3245
57
    const MipsMCExpr *GotExpr =
3246
57
        MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3247
57
3248
57
    if(isABI_O32() || 
isABI_N32()38
) {
3249
38
      TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3250
38
                   IDLoc, STI);
3251
38
    } else { //isABI_N64()
3252
19
      TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3253
19
                   IDLoc, STI);
3254
19
    }
3255
70
  } else { //!IsPicEnabled
3256
70
    const MCExpr *HiSym =
3257
70
        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3258
70
    const MipsMCExpr *HiExpr =
3259
70
        MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3260
70
3261
70
    // FIXME: This is technically correct but gives a different result to gas,
3262
70
    // but gas is incomplete there (it has a fixme noting it doesn't work with
3263
70
    // 64-bit addresses).
3264
70
    // FIXME: With -msym32 option, the address expansion for N64 should probably
3265
70
    // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3266
70
    // symbol's value is considered sign extended.
3267
70
    if(isABI_O32() || 
isABI_N32()38
) {
3268
51
      TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3269
51
    } else { //isABI_N64()
3270
19
      const MCExpr *HighestSym =
3271
19
          MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3272
19
      const MipsMCExpr *HighestExpr =
3273
19
          MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3274
19
      const MCExpr *HigherSym =
3275
19
          MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3276
19
      const MipsMCExpr *HigherExpr =
3277
19
          MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3278
19
3279
19
      TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3280
19
                  STI);
3281
19
      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3282
19
                   MCOperand::createExpr(HigherExpr), IDLoc, STI);
3283
19
      TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3284
19
      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3285
19
                   IDLoc, STI);
3286
19
      TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3287
19
    }
3288
70
  }
3289
127
  return false;
3290
127
}
3291
3292
bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
3293
                                      bool Is64FPU, SMLoc IDLoc,
3294
                                      MCStreamer &Out,
3295
300
                                      const MCSubtargetInfo *STI) {
3296
300
  MipsTargetStreamer &TOut = getTargetStreamer();
3297
300
  assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3298
300
  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3299
300
         "Invalid instruction operand.");
3300
300
3301
300
  unsigned FirstReg = Inst.getOperand(0).getReg();
3302
300
  uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3303
300
3304
300
  uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3305
300
  // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3306
300
  // exponent field), convert it to double (e.g. 1 to 1.0)
3307
300
  if ((HiImmOp64 & 0x7ff00000) == 0) {
3308
104
    APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3309
104
    ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3310
104
  }
3311
300
3312
300
  uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3313
300
  HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3314
300
3315
300
  if (IsSingle) {
3316
132
    // Conversion of a double in an uint64_t to a float in a uint32_t,
3317
132
    // retaining the bit pattern of a float.
3318
132
    uint32_t ImmOp32;
3319
132
    double doubleImm = BitsToDouble(ImmOp64);
3320
132
    float tmp_float = static_cast<float>(doubleImm);
3321
132
    ImmOp32 = FloatToBits(tmp_float);
3322
132
3323
132
    if (IsGPR) {
3324
66
      if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
3325
66
                        Out, STI))
3326
0
        return true;
3327
66
      return false;
3328
66
    } else {
3329
66
      unsigned ATReg = getATReg(IDLoc);
3330
66
      if (!ATReg)
3331
0
        return true;
3332
66
      if (LoImmOp64 == 0) {
3333
30
        if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
3334
30
                          Out, STI))
3335
0
          return true;
3336
30
        TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3337
30
        return false;
3338
30
      }
3339
36
3340
36
      MCSection *CS = getStreamer().getCurrentSectionOnly();
3341
36
      // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3342
36
      // where appropriate.
3343
36
      MCSection *ReadOnlySection = getContext().getELFSection(
3344
36
          ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3345
36
3346
36
      MCSymbol *Sym = getContext().createTempSymbol();
3347
36
      const MCExpr *LoSym =
3348
36
          MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3349
36
      const MipsMCExpr *LoExpr =
3350
36
          MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3351
36
3352
36
      getStreamer().SwitchSection(ReadOnlySection);
3353
36
      getStreamer().EmitLabel(Sym, IDLoc);
3354
36
      getStreamer().EmitIntValue(ImmOp32, 4);
3355
36
      getStreamer().SwitchSection(CS);
3356
36
3357
36
      if(emitPartialAddress(TOut, IDLoc, Sym))
3358
0
        return true;
3359
36
      TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
3360
36
                   MCOperand::createExpr(LoExpr), IDLoc, STI);
3361
36
    }
3362
132
    
return false36
;
3363
168
  }
3364
168
3365
168
  // if(!IsSingle)
3366
168
  unsigned ATReg = getATReg(IDLoc);
3367
168
  if (!ATReg)
3368
0
    return true;
3369
168
3370
168
  if (IsGPR) {
3371
77
    if (LoImmOp64 == 0) {
3372
35
      if(isABI_N32() || 
isABI_N64()25
) {
3373
20
        if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
3374
20
                          IDLoc, Out, STI))
3375
0
          return true;
3376
20
        return false;
3377
20
      } else {
3378
15
        if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
3379
15
                        IDLoc, Out, STI))
3380
0
          return true;
3381
15
3382
15
        if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
3383
15
                        IDLoc, Out, STI))
3384
0
          return true;
3385
15
        return false;
3386
15
      }
3387
35
    }
3388
42
3389
42
    MCSection *CS = getStreamer().getCurrentSectionOnly();
3390
42
    MCSection *ReadOnlySection = getContext().getELFSection(
3391
42
        ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3392
42
3393
42
    MCSymbol *Sym = getContext().createTempSymbol();
3394
42
    const MCExpr *LoSym =
3395
42
        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3396
42
    const MipsMCExpr *LoExpr =
3397
42
        MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3398
42
3399
42
    getStreamer().SwitchSection(ReadOnlySection);
3400
42
    getStreamer().EmitLabel(Sym, IDLoc);
3401
42
    getStreamer().EmitIntValue(HiImmOp64, 4);
3402
42
    getStreamer().EmitIntValue(LoImmOp64, 4);
3403
42
    getStreamer().SwitchSection(CS);
3404
42
3405
42
    if(emitPartialAddress(TOut, IDLoc, Sym))
3406
0
      return true;
3407
42
    if(isABI_N64())
3408
12
      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3409
12
                   MCOperand::createExpr(LoExpr), IDLoc, STI);
3410
30
    else
3411
30
      TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
3412
30
                   MCOperand::createExpr(LoExpr), IDLoc, STI);
3413
42
3414
42
    if(isABI_N32() || 
isABI_N64()30
)
3415
24
      TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
3416
18
    else {
3417
18
      TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3418
18
      TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
3419
18
    }
3420
42
    return false;
3421
91
  } else { // if(!IsGPR && !IsSingle)
3422
91
    if ((LoImmOp64 == 0) &&
3423
91
        
!(49
(HiImmOp64 & 0xffff0000)49
&&
(HiImmOp64 & 0x0000ffff)35
)) {
3424
42
      // FIXME: In the case where the constant is zero, we can load the
3425
42
      // register directly from the zero register.
3426
42
      if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
3427
42
                        Out, STI))
3428
0
        return true;
3429
42
      if (isABI_N32() || 
isABI_N64()30
)
3430
24
        TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3431
18
      else if (hasMips32r2()) {
3432
6
        TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3433
6
        TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3434
12
      } else {
3435
12
        TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
3436
12
        TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3437
12
      }
3438
42
      return false;
3439
42
    }
3440
49
3441
49
    MCSection *CS = getStreamer().getCurrentSectionOnly();
3442
49
    // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3443
49
    // where appropriate.
3444
49
    MCSection *ReadOnlySection = getContext().getELFSection(
3445
49
        ".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3446
49
3447
49
    MCSymbol *Sym = getContext().createTempSymbol();
3448
49
    const MCExpr *LoSym =
3449
49
        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3450
49
    const MipsMCExpr *LoExpr =
3451
49
        MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3452
49
3453
49
    getStreamer().SwitchSection(ReadOnlySection);
3454
49
    getStreamer().EmitLabel(Sym, IDLoc);
3455
49
    getStreamer().EmitIntValue(HiImmOp64, 4);
3456
49
    getStreamer().EmitIntValue(LoImmOp64, 4);
3457
49
    getStreamer().SwitchSection(CS);
3458
49
3459
49
    if(emitPartialAddress(TOut, IDLoc, Sym))
3460
0
      return true;
3461
49
    TOut.emitRRX(Is64FPU ? 
Mips::LDC16428
:
Mips::LDC121
, FirstReg, ATReg,
3462
49
                 MCOperand::createExpr(LoExpr), IDLoc, STI);
3463
49
  }
3464
168
  
return false49
;
3465
168
}
3466
3467
bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3468
                                               MCStreamer &Out,
3469
26
                                               const MCSubtargetInfo *STI) {
3470
26
  MipsTargetStreamer &TOut = getTargetStreamer();
3471
26
3472
26
  assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3473
26
         "unexpected number of operands");
3474
26
3475
26
  MCOperand Offset = Inst.getOperand(0);
3476
26
  if (Offset.isExpr()) {
3477
11
    Inst.clear();
3478
11
    Inst.setOpcode(Mips::BEQ_MM);
3479
11
    Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3480
11
    Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3481
11
    Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3482
15
  } else {
3483
15
    assert(Offset.isImm() && "expected immediate operand kind");
3484
15
    if (isInt<11>(Offset.getImm())) {
3485
5
      // If offset fits into 11 bits then this instruction becomes microMIPS
3486
5
      // 16-bit unconditional branch instruction.
3487
5
      if (inMicroMipsMode())
3488
5
        Inst.setOpcode(hasMips32r6() ? 
Mips::BC16_MMR61
:
Mips::B16_MM4
);
3489
10
    } else {
3490
10
      if (!isInt<17>(Offset.getImm()))
3491
2
        return Error(IDLoc, "branch target out of range");
3492
8
      if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
3493
2
        return Error(IDLoc, "branch to misaligned address");
3494
6
      Inst.clear();
3495
6
      Inst.setOpcode(Mips::BEQ_MM);
3496
6
      Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3497
6
      Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3498
6
      Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3499
6
    }
3500
15
  }
3501
26
  Out.EmitInstruction(Inst, *STI);
3502
22
3503
22
  // If .set reorder is active and branch instruction has a delay slot,
3504
22
  // emit a NOP after it.
3505
22
  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3506
22
  if (MCID.hasDelaySlot() && 
AssemblerOptions.back()->isReorder()21
)
3507
18
    TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3508
22
3509
22
  return false;
3510
26
}
3511
3512
bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3513
65
                                    const MCSubtargetInfo *STI) {
3514
65
  MipsTargetStreamer &TOut = getTargetStreamer();
3515
65
  const MCOperand &DstRegOp = Inst.getOperand(0);
3516
65
  assert(DstRegOp.isReg() && "expected register operand kind");
3517
65
3518
65
  const MCOperand &ImmOp = Inst.getOperand(1);
3519
65
  assert(ImmOp.isImm() && "expected immediate operand kind");
3520
65
3521
65
  const MCOperand &MemOffsetOp = Inst.getOperand(2);
3522
65
  assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3523
65
         "expected immediate or expression operand");
3524
65
3525
65
  bool IsLikely = false;
3526
65
3527
65
  unsigned OpCode = 0;
3528
65
  switch(Inst.getOpcode()) {
3529
65
    case Mips::BneImm:
3530
24
      OpCode = Mips::BNE;
3531
24
      break;
3532
65
    case Mips::BeqImm:
3533
25
      OpCode = Mips::BEQ;
3534
25
      break;
3535
65
    case Mips::BEQLImmMacro:
3536
8
      OpCode = Mips::BEQL;
3537
8
      IsLikely = true;
3538
8
      break;
3539
65
    case Mips::BNELImmMacro:
3540
8
      OpCode = Mips::BNEL;
3541
8
      IsLikely = true;
3542
8
      break;
3543
65
    default:
3544
0
      llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3545
65
      
break0
;
3546
65
  }
3547
65
3548
65
  int64_t ImmValue = ImmOp.getImm();
3549
65
  if (ImmValue == 0) {
3550
10
    if (IsLikely) {
3551
2
      TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3552
2
                   MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3553
2
      TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3554
2
    } else
3555
8
      TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3556
8
              STI);
3557
55
  } else {
3558
55
    warnIfNoMacro(IDLoc);
3559
55
3560
55
    unsigned ATReg = getATReg(IDLoc);
3561
55
    if (!ATReg)
3562
2
      return true;
3563
53
3564
53
    if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3565
53
                      IDLoc, Out, STI))
3566
2
      return true;
3567
51
3568
51
    if (IsLikely) {
3569
12
      TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3570
12
              MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3571
12
      TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3572
12
    } else
3573
39
      TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3574
51
  }
3575
65
  
return false61
;
3576
65
}
3577
3578
void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3579
118
                                  const MCSubtargetInfo *STI, bool IsLoad) {
3580
118
  const MCOperand &DstRegOp = Inst.getOperand(0);
3581
118
  assert(DstRegOp.isReg() && "expected register operand kind");
3582
118
  const MCOperand &BaseRegOp = Inst.getOperand(1);
3583
118
  assert(BaseRegOp.isReg() && "expected register operand kind");
3584
118
  const MCOperand &OffsetOp = Inst.getOperand(2);
3585
118
3586
118
  MipsTargetStreamer &TOut = getTargetStreamer();
3587
118
  unsigned DstReg = DstRegOp.getReg();
3588
118
  unsigned BaseReg = BaseRegOp.getReg();
3589
118
  unsigned TmpReg = DstReg;
3590
118
3591
118
  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3592
118
  int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3593
118
  unsigned DstRegClassID =
3594
118
      getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3595
118
  bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3596
118
               
(DstRegClassID == Mips::GPR64RegClassID)21
;
3597
118
3598
118
  if (!IsLoad || 
!IsGPR98
||
(BaseReg == DstReg)96
) {
3599
62
    // At this point we need AT to perform the expansions
3600
62
    // and we exit if it is not available.
3601
62
    TmpReg = getATReg(IDLoc);
3602
62
    if (!TmpReg)
3603
2
      return;
3604
116
  }
3605
116
3606
116
  if (OffsetOp.isImm()) {
3607
95
    int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3608
95
    int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3609
95
3610
95
    // If msb of LoOffset is 1(negative number) we must increment
3611
95
    // HiOffset to account for the sign-extension of the low part.
3612
95
    if (LoOffset & 0x8000)
3613
36
      HiOffset += 0x10000;
3614
95
3615
95
    bool IsLargeOffset = HiOffset != 0;
3616
95
3617
95
    if (IsLargeOffset) {
3618
95
      bool Is32BitImm = (HiOffset >> 32) == 0;
3619
95
      if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3620
95
                        IDLoc, Out, STI))
3621
0
        return;
3622
95
    }
3623
95
3624
95
    if (BaseReg != Mips::ZERO && 
BaseReg != Mips::ZERO_6485
)
3625
68
      TOut.emitRRR(isGP64bit() ? 
Mips::DADDu16
:
Mips::ADDu52
, TmpReg, TmpReg,
3626
68
                   BaseReg, IDLoc, STI);
3627
95
    TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3628
95
  } else {
3629
21
    assert(OffsetOp.isExpr() && "expected expression operand kind");
3630
21
    const MCExpr *ExprOffset = OffsetOp.getExpr();
3631
21
    MCOperand LoOperand = MCOperand::createExpr(
3632
21
        MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3633
21
    MCOperand HiOperand = MCOperand::createExpr(
3634
21
        MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3635
21
3636
21
    if (IsLoad)
3637
12
      TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3638
12
                                 LoOperand, TmpReg, IDLoc, STI);
3639
9
    else
3640
9
      TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3641
9
                                  LoOperand, TmpReg, IDLoc, STI);
3642
21
  }
3643
116
}
3644
3645
bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3646
                                            MCStreamer &Out,
3647
22
                                            const MCSubtargetInfo *STI) {
3648
22
  unsigned OpNum = Inst.getNumOperands();
3649
22
  unsigned Opcode = Inst.getOpcode();
3650
22
  unsigned NewOpcode = Opcode == Mips::SWM_MM ? 
Mips::SWM32_MM11
:
Mips::LWM32_MM11
;
3651
22
3652
22
  assert(Inst.getOperand(OpNum - 1).isImm() &&
3653
22
         Inst.getOperand(OpNum - 2).isReg() &&
3654
22
         Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3655
22
3656
22
  if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3657
22
      
Inst.getOperand(OpNum - 1).getImm() >= 018
&&
3658
22
      
(18
Inst.getOperand(OpNum - 2).getReg() == Mips::SP18
||
3659
18
       
Inst.getOperand(OpNum - 2).getReg() == Mips::SP_644
) &&
3660
22
      
(14
Inst.getOperand(OpNum - 3).getReg() == Mips::RA14
||
3661
14
       
Inst.getOperand(OpNum - 3).getReg() == Mips::RA_648
)) {
3662
6
    // It can be implemented as SWM16 or LWM16 instruction.
3663
6
    if (inMicroMipsMode() && hasMips32r6())
3664
2
      NewOpcode = Opcode == Mips::SWM_MM ? 
Mips::SWM16_MMR61
:
Mips::LWM16_MMR61
;
3665
4
    else
3666
4
      NewOpcode = Opcode == Mips::SWM_MM ? 
Mips::SWM16_MM2
:
Mips::LWM16_MM2
;
3667
6
  }
3668
22
3669
22
  Inst.setOpcode(NewOpcode);
3670
22
  Out.EmitInstruction(Inst, *STI);
3671
22
  return false;
3672
22
}
3673
3674
bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3675
                                       MCStreamer &Out,
3676
258
                                       const MCSubtargetInfo *STI) {
3677
258
  MipsTargetStreamer &TOut = getTargetStreamer();
3678
258
  bool EmittedNoMacroWarning = false;
3679
258
  unsigned PseudoOpcode = Inst.getOpcode();
3680
258
  unsigned SrcReg = Inst.getOperand(0).getReg();
3681
258
  const MCOperand &TrgOp = Inst.getOperand(1);
3682
258
  const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3683
258
3684
258
  unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3685
258
  bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3686
258
3687
258
  unsigned TrgReg;
3688
258
  if (TrgOp.isReg())
3689
240
    TrgReg = TrgOp.getReg();
3690
18
  else if (TrgOp.isImm()) {
3691
18
    warnIfNoMacro(IDLoc);
3692
18
    EmittedNoMacroWarning = true;
3693
18
3694
18
    TrgReg = getATReg(IDLoc);
3695
18
    if (!TrgReg)
3696
1
      return true;
3697
17
3698
17
    switch(PseudoOpcode) {
3699
17
    default:
3700
0
      llvm_unreachable("unknown opcode for branch pseudo-instruction");
3701
17
    case Mips::BLTImmMacro:
3702
2
      PseudoOpcode = Mips::BLT;
3703
2
      break;
3704
17
    case Mips::BLEImmMacro:
3705
1
      PseudoOpcode = Mips::BLE;
3706
1
      break;
3707
17
    case Mips::BGEImmMacro:
3708
1
      PseudoOpcode = Mips::BGE;
3709
1
      break;
3710
17
    case Mips::BGTImmMacro:
3711
1
      PseudoOpcode = Mips::BGT;
3712
1
      break;
3713
17
    case Mips::BLTUImmMacro:
3714
1
      PseudoOpcode = Mips::BLTU;
3715
1
      break;
3716
17
    case Mips::BLEUImmMacro:
3717
1
      PseudoOpcode = Mips::BLEU;
3718
1
      break;
3719
17
    case Mips::BGEUImmMacro:
3720
1
      PseudoOpcode = Mips::BGEU;
3721
1
      break;
3722
17
    case Mips::BGTUImmMacro:
3723
1
      PseudoOpcode = Mips::BGTU;
3724
1
      break;
3725
17
    case Mips::BLTLImmMacro:
3726
1
      PseudoOpcode = Mips::BLTL;
3727
1
      break;
3728
17
    case Mips::BLELImmMacro:
3729
1
      PseudoOpcode = Mips::BLEL;
3730
1
      break;
3731
17
    case Mips::BGELImmMacro:
3732
1
      PseudoOpcode = Mips::BGEL;
3733
1
      break;
3734
17
    case Mips::BGTLImmMacro:
3735
1
      PseudoOpcode = Mips::BGTL;
3736
1
      break;
3737
17
    case Mips::BLTULImmMacro:
3738
1
      PseudoOpcode = Mips::BLTUL;
3739
1
      break;
3740
17
    case Mips::BLEULImmMacro:
3741
1
      PseudoOpcode = Mips::BLEUL;
3742
1
      break;
3743
17
    case Mips::BGEULImmMacro:
3744
1
      PseudoOpcode = Mips::BGEUL;
3745
1
      break;
3746
17
    case Mips::BGTULImmMacro:
3747
1
      PseudoOpcode = Mips::BGTUL;
3748
1
      break;
3749
17
    }
3750
17
3751
17
    if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3752
17
                      false, IDLoc, Out, STI))
3753
0
      return true;
3754
257
  }
3755
257
3756
257
  switch (PseudoOpcode) {
3757
257
  case Mips::BLT:
3758
65
  case Mips::BLTU:
3759
65
  case Mips::BLTL:
3760
65
  case Mips::BLTUL:
3761
65
    AcceptsEquality = false;
3762
65
    ReverseOrderSLT = false;
3763
65
    IsUnsigned =
3764
65
        ((PseudoOpcode == Mips::BLTU) || 
(PseudoOpcode == Mips::BLTUL)45
);
3765
65
    IsLikely = ((PseudoOpcode == Mips::BLTL) || 
(PseudoOpcode == Mips::BLTUL)53
);
3766
65
    ZeroSrcOpcode = Mips::BGTZ;
3767
65
    ZeroTrgOpcode = Mips::BLTZ;
3768
65
    break;
3769
65
  case Mips::BLE:
3770
64
  case Mips::BLEU:
3771
64
  case Mips::BLEL:
3772
64
  case Mips::BLEUL:
3773
64
    AcceptsEquality = true;
3774
64
    ReverseOrderSLT = true;
3775
64
    IsUnsigned =
3776
64
        ((PseudoOpcode == Mips::BLEU) || 
(PseudoOpcode == Mips::BLEUL)44
);
3777
64
    IsLikely = ((PseudoOpcode == Mips::BLEL) || 
(PseudoOpcode == Mips::BLEUL)52
);
3778
64
    ZeroSrcOpcode = Mips::BGEZ;
3779
64
    ZeroTrgOpcode = Mips::BLEZ;
3780
64
    break;
3781
64
  case Mips::BGE:
3782
64
  case Mips::BGEU:
3783
64
  case Mips::BGEL:
3784
64
  case Mips::BGEUL:
3785
64
    AcceptsEquality = true;
3786
64
    ReverseOrderSLT = false;
3787
64
    IsUnsigned =
3788
64
        ((PseudoOpcode == Mips::BGEU) || 
(PseudoOpcode == Mips::BGEUL)44
);
3789
64
    IsLikely = ((PseudoOpcode == Mips::BGEL) || 
(PseudoOpcode == Mips::BGEUL)52
);
3790
64
    ZeroSrcOpcode = Mips::BLEZ;
3791
64
    ZeroTrgOpcode = Mips::BGEZ;
3792
64
    break;
3793
64
  case Mips::BGT:
3794
64
  case Mips::BGTU:
3795
64
  case Mips::BGTL:
3796
64
  case Mips::BGTUL:
3797
64
    AcceptsEquality = false;
3798
64
    ReverseOrderSLT = true;
3799
64
    IsUnsigned =
3800
64
        ((PseudoOpcode == Mips::BGTU) || 
(PseudoOpcode == Mips::BGTUL)44
);
3801
64
    IsLikely = ((PseudoOpcode == Mips::BGTL) || 
(PseudoOpcode == Mips::BGTUL)52
);
3802
64
    ZeroSrcOpcode = Mips::BLTZ;
3803
64
    ZeroTrgOpcode = Mips::BGTZ;
3804
64
    break;
3805
64
  default:
3806
0
    llvm_unreachable("unknown opcode for branch pseudo-instruction");
3807
257
  }
3808
257
3809
257
  bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3810
257
  bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3811
257
  if (IsSrcRegZero && 
IsTrgRegZero96
) {
3812
48
    // FIXME: All of these Opcode-specific if's are needed for compatibility
3813
48
    // with GAS' behaviour. However, they may not generate the most efficient
3814
48
    // code in some circumstances.
3815
48
    if (PseudoOpcode == Mips::BLT) {
3816
4
      TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3817
4
                  IDLoc, STI);
3818
4
      return false;
3819
4
    }
3820
44
    if (PseudoOpcode == Mips::BLE) {
3821
4
      TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3822
4
                  IDLoc, STI);
3823
4
      Warning(IDLoc, "branch is always taken");
3824
4
      return false;
3825
4
    }
3826
40
    if (PseudoOpcode == Mips::BGE) {
3827
4
      TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3828
4
                  IDLoc, STI);
3829
4
      Warning(IDLoc, "branch is always taken");
3830
4
      return false;
3831
4
    }
3832
36
    if (PseudoOpcode == Mips::BGT) {
3833
4
      TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3834
4
                  IDLoc, STI);
3835
4
      return false;
3836
4
    }
3837
32
    if (PseudoOpcode == Mips::BGTU) {
3838
4
      TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3839
4
                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3840
4
      return false;
3841
4
    }
3842
28
    if (AcceptsEquality) {
3843
16
      // If both registers are $0 and the pseudo-branch accepts equality, it
3844
16
      // will always be taken, so we emit an unconditional branch.
3845
16
      TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3846
16
                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3847
16
      Warning(IDLoc, "branch is always taken");
3848
16
      return false;
3849
16
    }
3850
12
    // If both registers are $0 and the pseudo-branch does not accept
3851
12
    // equality, it will never be taken, so we don't have to emit anything.
3852
12
    return false;
3853
12
  }
3854
209
  if (IsSrcRegZero || 
IsTrgRegZero161
) {
3855
96
    if ((IsSrcRegZero && 
PseudoOpcode == Mips::BGTU48
) ||
3856
96
        
(92
IsTrgRegZero92
&&
PseudoOpcode == Mips::BLTU48
)) {
3857
8
      // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3858
8
      // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3859
8
      // the pseudo-branch will never be taken, so we don't emit anything.
3860
8
      // This only applies to unsigned pseudo-branches.
3861
8
      return false;
3862
8
    }
3863
88
    if ((IsSrcRegZero && 
PseudoOpcode == Mips::BLEU44
) ||
3864
88
        
(84
IsTrgRegZero84
&&
PseudoOpcode == Mips::BGEU44
)) {
3865
8
      // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3866
8
      // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3867
8
      // the pseudo-branch will always be taken, so we emit an unconditional
3868
8
      // branch.
3869
8
      // This only applies to unsigned pseudo-branches.
3870
8
      TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3871
8
                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3872
8
      Warning(IDLoc, "branch is always taken");
3873
8
      return false;
3874
8
    }
3875
80
    if (IsUnsigned) {
3876
32
      // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3877
32
      // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3878
32
      // the pseudo-branch will be taken only when the non-zero register is
3879
32
      // different from 0, so we emit a BNEZ.
3880
32
      //
3881
32
      // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3882
32
      // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3883
32
      // the pseudo-branch will be taken only when the non-zero register is
3884
32
      // equal to 0, so we emit a BEQZ.
3885
32
      //
3886
32
      // Because only BLEU and BGEU branch on equality, we can use the
3887
32
      // AcceptsEquality variable to decide when to emit the BEQZ.
3888
32
      TOut.emitRRX(AcceptsEquality ? 
Mips::BEQ16
:
Mips::BNE16
,
3889
32
                   IsSrcRegZero ? 
TrgReg16
:
SrcReg16
, Mips::ZERO,
3890
32
                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3891
32
      return false;
3892
32
    }
3893
48
    // If we have a signed pseudo-branch and one of the registers is $0,
3894
48
    // we can use an appropriate compare-to-zero branch. We select which one
3895
48
    // to use in the switch statement above.
3896
48
    TOut.emitRX(IsSrcRegZero ? 
ZeroSrcOpcode24
:
ZeroTrgOpcode24
,
3897
48
                IsSrcRegZero ? 
TrgReg24
:
SrcReg24
,
3898
48
                MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3899
48
    return false;
3900
48
  }
3901
113
3902
113
  // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3903
113
  // expansions. If it is not available, we return.
3904
113
  unsigned ATRegNum = getATReg(IDLoc);
3905
113
  if (!ATRegNum)
3906
16
    return true;
3907
97
3908
97
  if (!EmittedNoMacroWarning)
3909
80
    warnIfNoMacro(IDLoc);
3910
97
3911
97
  // SLT fits well with 2 of our 4 pseudo-branches:
3912
97
  //   BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3913
97
  //   BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3914
97
  // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3915
97
  // This is accomplished by using a BNEZ with the result of the SLT.
3916
97
  //
3917
97
  // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3918
97
  // and BLE with BGT), so we change the BNEZ into a BEQZ.
3919
97
  // Because only BGE and BLE branch on equality, we can use the
3920
97
  // AcceptsEquality variable to decide when to emit the BEQZ.
3921
97
  // Note that the order of the SLT arguments doesn't change between
3922
97
  // opposites.
3923
97
  //
3924
97
  // The same applies to the unsigned variants, except that SLTu is used
3925
97
  // instead of SLT.
3926
97
  TOut.emitRRR(IsUnsigned ? 
Mips::SLTu48
:
Mips::SLT49
, ATRegNum,
3927
97
               ReverseOrderSLT ? 
TrgReg48
:
SrcReg49
,
3928
97
               ReverseOrderSLT ? 
SrcReg48
:
TrgReg49
, IDLoc, STI);
3929
97
3930
97
  TOut.emitRRX(IsLikely ? 
(AcceptsEquality 40
?
Mips::BEQL20
:
Mips::BNEL20
)
3931
97
                        : 
(AcceptsEquality 57
?
Mips::BEQ28
:
Mips::BNE29
),
3932
97
               ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3933
97
               STI);
3934
97
  return false;
3935
97
}
3936
3937
// Expand a integer division macro.
3938
//
3939
// Notably we don't have to emit a warning when encountering $rt as the $zero
3940
// register, or 0 as an immediate. processInstruction() has already done that.
3941
//
3942
// The destination register can only be $zero when expanding (S)DivIMacro or
3943
// D(S)DivMacro.
3944
3945
bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3946
                                 const MCSubtargetInfo *STI, const bool IsMips64,
3947
468
                                 const bool Signed) {
3948
468
  MipsTargetStreamer &TOut = getTargetStreamer();
3949
468
3950
468
  warnIfNoMacro(IDLoc);
3951
468
3952
468
  const MCOperand &RdRegOp = Inst.getOperand(0);
3953
468
  assert(RdRegOp.isReg() && "expected register operand kind");
3954
468
  unsigned RdReg = RdRegOp.getReg();
3955
468
3956
468
  const MCOperand &RsRegOp = Inst.getOperand(1);
3957
468
  assert(RsRegOp.isReg() && "expected register operand kind");
3958
468
  unsigned RsReg = RsRegOp.getReg();
3959
468
3960
468
  unsigned RtReg;
3961
468
  int64_t ImmValue;
3962
468
3963
468
  const MCOperand &RtOp = Inst.getOperand(2);
3964
468
  assert((RtOp.isReg() || RtOp.isImm()) &&
3965
468
         "expected register or immediate operand kind");
3966
468
  if (RtOp.isReg())
3967
144
    RtReg = RtOp.getReg();
3968
324
  else
3969
324
    ImmValue = RtOp.getImm();
3970
468
3971
468
  unsigned DivOp;
3972
468
  unsigned ZeroReg;
3973
468
  unsigned SubOp;
3974
468
3975
468
  if (IsMips64) {
3976
292
    DivOp = Signed ? 
Mips::DSDIV172
:
Mips::DUDIV120
;
3977
292
    ZeroReg = Mips::ZERO_64;
3978
292
    SubOp = Mips::DSUB;
3979
292
  } else {
3980
176
    DivOp = Signed ? 
Mips::SDIV100
:
Mips::UDIV76
;
3981
176
    ZeroReg = Mips::ZERO;
3982
176
    SubOp = Mips::SUB;
3983
176
  }
3984
468
3985
468
  bool UseTraps = useTraps();
3986
468
3987
468
  unsigned Opcode = Inst.getOpcode();
3988
468
  bool isDiv = Opcode == Mips::SDivMacro || 
Opcode == Mips::SDivIMacro454
||
3989
468
               
Opcode == Mips::UDivMacro416
||
Opcode == Mips::UDivIMacro390
||
3990
468
               
Opcode == Mips::DSDivMacro388
||
Opcode == Mips::DSDivIMacro372
||
3991
468
               
Opcode == Mips::DUDivMacro316
||
Opcode == Mips::DUDivIMacro294
;
3992
468
3993
468
  bool isRem = Opcode == Mips::SRemMacro || 
Opcode == Mips::SRemIMacro456
||
3994
468
               
Opcode == Mips::URemMacro420
||
Opcode == Mips::URemIMacro408
||
3995
468
               
Opcode == Mips::DSRemMacro372
||
Opcode == Mips::DSRemIMacro344
||
3996
468
               
Opcode == Mips::DURemMacro272
||
Opcode == Mips::DURemIMacro258
;
3997
468
3998
468
  if (RtOp.isImm()) {
3999
324
    unsigned ATReg = getATReg(IDLoc);
4000
324
    if (!ATReg)
4001
0
      return true;
4002
324
4003
324
    if (ImmValue == 0) {
4004
66
      if (UseTraps)
4005
33
        TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4006
33
      else
4007
33
        TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4008
66
      return false;
4009
66
    }
4010
258
4011
258
    if (isRem && 
(132
ImmValue == 1132
||
(112
Signed112
&&
(ImmValue == -1)72
))) {
4012
32
      TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4013
32
      return false;
4014
226
    } else if (isDiv && 
ImmValue == 1126
) {
4015
12
      TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4016
12
      return false;
4017
214
    } else if (isDiv && 
Signed114
&&
ImmValue == -170
) {
4018
8
      TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4019
8
      return false;
4020
206
    } else {
4021
206
      if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4022
206
                        false, Inst.getLoc(), Out, STI))
4023
0
        return true;
4024
206
      TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4025
206
      TOut.emitR(isDiv ? 
Mips::MFLO106
:
Mips::MFHI100
, RdReg, IDLoc, STI);
4026
206
      return false;
4027
206
    }
4028
0
    return true;
4029
0
  }
4030
144
4031
144
  // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4032
144
  // break, insert the trap/break and exit. This gives a different result to
4033
144
  // GAS. GAS has an inconsistency/missed optimization in that not all cases
4034
144
  // are handled equivalently. As the observed behaviour is the same, we're ok.
4035
144
  if (RtReg == Mips::ZERO || 
RtReg == Mips::ZERO_64110
) {
4036
72
    if (UseTraps) {
4037
32
      TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4038
32
      return false;
4039
32
    }
4040
40
    TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4041
40
    return false;
4042
40
  }
4043
72
4044
72
  // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4045
72
  // not expand to macro sequence.
4046
72
  if (isRem && 
(36
RdReg == Mips::ZERO36
||
RdReg == Mips::ZERO_6432
)) {
4047
16
    TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4048
16
    return false;
4049
16
  }
4050
56
4051
56
  // Temporary label for first branch traget
4052
56
  MCContext &Context = TOut.getStreamer().getContext();
4053
56
  MCSymbol *BrTarget;
4054
56
  MCOperand LabelOp;
4055
56
4056
56
  if (UseTraps) {
4057
27
    TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4058
29
  } else {
4059
29
    // Branch to the li instruction.
4060
29
    BrTarget = Context.createTempSymbol();
4061
29
    LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4062
29
    TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4063
29
  }
4064
56
4065
56
  TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4066
56
4067
56
  if (!UseTraps)
4068
29
    TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4069
56
4070
56
  if (!Signed) {
4071
30
    if (!UseTraps)
4072
16
      TOut.getStreamer().EmitLabel(BrTarget);
4073
30
4074
30
    TOut.emitR(isDiv ? 
Mips::MFLO22
:
Mips::MFHI8
, RdReg, IDLoc, STI);
4075
30
    return false;
4076
30
  }
4077
26
4078
26
  unsigned ATReg = getATReg(IDLoc);
4079
26
  if (!ATReg)
4080
0
    return true;
4081
26
4082
26
  if (!UseTraps)
4083
13
    TOut.getStreamer().EmitLabel(BrTarget);
4084
26
4085
26
  TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4086
26
4087
26
  // Temporary label for the second branch target.
4088
26
  MCSymbol *BrTargetEnd = Context.createTempSymbol();
4089
26
  MCOperand LabelOpEnd =
4090
26
      MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4091
26
4092
26
  // Branch to the mflo instruction.
4093
26
  TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4094
26
4095
26
  if (IsMips64) {
4096
16
    TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4097
16
    TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4098
16
  } else {
4099
10
    TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4100
10
  }
4101
26
4102
26
  if (UseTraps)
4103
13
    TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4104
13
  else {
4105
13
    // Branch to the mflo instruction.
4106
13
    TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4107
13
    TOut.emitNop(IDLoc, STI);
4108
13
    TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4109
13
  }
4110
26
4111
26
  TOut.getStreamer().EmitLabel(BrTargetEnd);
4112
26
  TOut.emitR(isDiv ? 
Mips::MFLO14
:
Mips::MFHI12
, RdReg, IDLoc, STI);
4113
26
  return false;
4114
26
}
4115
4116
bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4117
                                SMLoc IDLoc, MCStreamer &Out,
4118
26
                                const MCSubtargetInfo *STI) {
4119
26
  MipsTargetStreamer &TOut = getTargetStreamer();
4120
26
4121
26
  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4122
26
  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4123
26
         Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4124
26
4125
26
  unsigned FirstReg = Inst.getOperand(0).getReg();
4126
26
  unsigned SecondReg = Inst.getOperand(1).getReg();
4127
26
  unsigned ThirdReg = Inst.getOperand(2).getReg();
4128
26
4129
26
  if (hasMips1() && !hasMips2()) {
4130
2
    unsigned ATReg = getATReg(IDLoc);
4131
2
    if (!ATReg)
4132
0
      return true;
4133
2
    TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4134
2
    TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4135
2
    TOut.emitNop(IDLoc, STI);
4136
2
    TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4137
2
    TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4138
2
    TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4139
2
    TOut.emitNop(IDLoc, STI);
4140
2
    TOut.emitRR(IsDouble ? 
(Is64FPU 1
?
Mips::CVT_W_D640
:
Mips::CVT_W_D321
)
4141
2
                         : 
Mips::CVT_W_S1
,
4142
2
                FirstReg, SecondReg, IDLoc, STI);
4143
2
    TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4144
2
    TOut.emitNop(IDLoc, STI);
4145
2
    return false;
4146
2
  }
4147
24
4148
24
  TOut.emitRR(IsDouble ? 
(Is64FPU 12
?
Mips::TRUNC_W_D647
:
Mips::TRUNC_W_D325
)
4149
24
                       : 
Mips::TRUNC_W_S12
,
4150
24
              FirstReg, SecondReg, IDLoc, STI);
4151
24
4152
24
  return false;
4153
24
}
4154
4155
bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4156
96
                              MCStreamer &Out, const MCSubtargetInfo *STI) {
4157
96
  if (hasMips32r6() || 
hasMips64r6()84
) {
4158
12
    return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4159
12
  }
4160
84
4161
84
  const MCOperand &DstRegOp = Inst.getOperand(0);
4162
84
  assert(DstRegOp.isReg() && "expected register operand kind");
4163
84
  const MCOperand &SrcRegOp = Inst.getOperand(1);
4164
84
  assert(SrcRegOp.isReg() && "expected register operand kind");
4165
84
  const MCOperand &OffsetImmOp = Inst.getOperand(2);
4166
84
  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4167
84
4168
84
  MipsTargetStreamer &TOut = getTargetStreamer();
4169
84
  unsigned DstReg = DstRegOp.getReg();
4170
84
  unsigned SrcReg = SrcRegOp.getReg();
4171
84
  int64_t OffsetValue = OffsetImmOp.getImm();
4172
84
4173
84
  // NOTE: We always need AT for ULHU, as it is always used as the source
4174
84
  // register for one of the LBu's.
4175
84
  warnIfNoMacro(IDLoc);
4176
84
  unsigned ATReg = getATReg(IDLoc);
4177
84
  if (!ATReg)
4178
0
    return true;
4179
84
4180
84
  bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && 
isInt<16>(OffsetValue)44
);
4181
84
  if (IsLargeOffset) {
4182
48
    if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4183
48
                      IDLoc, Out, STI))
4184
0
      return true;
4185
84
  }
4186
84
4187
84
  int64_t FirstOffset = IsLargeOffset ? 
048
:
OffsetValue36
;
4188
84
  int64_t SecondOffset = IsLargeOffset ? 
148
:
(OffsetValue + 1)36
;
4189
84
  if (isLittle())
4190
41
    std::swap(FirstOffset, SecondOffset);
4191
84
4192
84
  unsigned FirstLbuDstReg = IsLargeOffset ? 
DstReg48
:
ATReg36
;
4193
84
  unsigned SecondLbuDstReg = IsLargeOffset ? 
ATReg48
:
DstReg36
;
4194
84
4195
84
  unsigned LbuSrcReg = IsLargeOffset ? 
ATReg48
:
SrcReg36
;
4196
84
  unsigned SllReg = IsLargeOffset ? 
DstReg48
:
ATReg36
;
4197
84
4198
84
  TOut.emitRRI(Signed ? 
Mips::LB39
:
Mips::LBu45
, FirstLbuDstReg, LbuSrcReg,
4199
84
               FirstOffset, IDLoc, STI);
4200
84
  TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4201
84
  TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4202
84
  TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4203
84
4204
84
  return false;
4205
84
}
4206
4207
bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4208
48
                              const MCSubtargetInfo *STI) {
4209
48
  if (hasMips32r6() || hasMips64r6()) {
4210
0
    return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4211
0
  }
4212
48
4213
48
  const MCOperand &DstRegOp = Inst.getOperand(0);
4214
48
  assert(DstRegOp.isReg() && "expected register operand kind");
4215
48
  const MCOperand &SrcRegOp = Inst.getOperand(1);
4216
48
  assert(SrcRegOp.isReg() && "expected register operand kind");
4217
48
  const MCOperand &OffsetImmOp = Inst.getOperand(2);
4218
48
  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4219
48
4220
48
  MipsTargetStreamer &TOut = getTargetStreamer();
4221
48
  unsigned DstReg = DstRegOp.getReg();
4222
48
  unsigned SrcReg = SrcRegOp.getReg();
4223
48
  int64_t OffsetValue = OffsetImmOp.getImm();
4224
48
4225
48
  warnIfNoMacro(IDLoc);
4226
48
  unsigned ATReg = getATReg(IDLoc);
4227
48
  if (!ATReg)
4228
0
    return true;
4229
48
4230
48
  bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && 
isInt<16>(OffsetValue)24
);
4231
48
  if (IsLargeOffset) {
4232
30
    if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4233
30
                      IDLoc, Out, STI))
4234
0
      return true;
4235
48
  }
4236
48
4237
48
  int64_t FirstOffset = IsLargeOffset ? 
130
:
(OffsetValue + 1)18
;
4238
48
  int64_t SecondOffset = IsLargeOffset ? 
030
:
OffsetValue18
;
4239
48
  if (isLittle())
4240
24
    std::swap(FirstOffset, SecondOffset);
4241
48
4242
48
  if (IsLargeOffset) {
4243
30
    TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4244
30
    TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4245
30
    TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4246
30
    TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4247
30
    TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4248
30
    TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4249
30
  } else {
4250
18
    TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4251
18
    TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4252
18
    TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4253
18
  }
4254
48
4255
48
  return false;
4256
48
}
4257
4258
bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4259
121
                              const MCSubtargetInfo *STI) {
4260
121
  if (hasMips32r6() || 
hasMips64r6()115
) {
4261
6
    return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4262
6
  }
4263
115
4264
115
  const MCOperand &DstRegOp = Inst.getOperand(0);
4265
115
  assert(DstRegOp.isReg() && "expected register operand kind");
4266
115
  const MCOperand &SrcRegOp = Inst.getOperand(1);
4267
115
  assert(SrcRegOp.isReg() && "expected register operand kind");
4268
115
  const MCOperand &OffsetImmOp = Inst.getOperand(2);
4269
115
  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4270
115
4271
115
  MipsTargetStreamer &TOut = getTargetStreamer();
4272
115
  unsigned DstReg = DstRegOp.getReg();
4273
115
  unsigned SrcReg = SrcRegOp.getReg();
4274
115
  int64_t OffsetValue = OffsetImmOp.getImm();
4275
115
4276
115
  // Compute left/right load/store offsets.
4277
115
  bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && 
isInt<16>(OffsetValue)55
);
4278
115
  int64_t LxlOffset = IsLargeOffset ? 
072
:
OffsetValue43
;
4279
115
  int64_t LxrOffset = IsLargeOffset ? 
372
:
(OffsetValue + 3)43
;
4280
115
  if (isLittle())
4281
56
    std::swap(LxlOffset, LxrOffset);
4282
115
4283
115
  bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4284
115
  bool DoMove = IsLoadInst && 
(SrcReg == DstReg)67
&&
!IsLargeOffset16
;
4285
115
  unsigned TmpReg = SrcReg;
4286
115
  if (IsLargeOffset || 
DoMove43
) {
4287
78
    warnIfNoMacro(IDLoc);
4288
78
    TmpReg = getATReg(IDLoc);
4289
78
    if (!TmpReg)
4290
0
      return true;
4291
115
  }
4292
115
4293
115
  if (IsLargeOffset) {
4294
72
    if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4295
72
                      IDLoc, Out, STI))
4296
0
      return true;
4297
115
  }
4298
115
4299
115
  if (DoMove)
4300
6
    std::swap(DstReg, TmpReg);
4301
115
4302
115
  unsigned XWL = IsLoadInst ? 
Mips::LWL67
:
Mips::SWL48
;
4303
115
  unsigned XWR = IsLoadInst ? 
Mips::LWR67
:
Mips::SWR48
;
4304
115
  TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4305
115
  TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4306
115
4307
115
  if (DoMove)
4308
6
    TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4309
115
4310
115
  return false;
4311
115
}
4312
4313
bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4314
8
                              const MCSubtargetInfo *STI) {
4315
8
  MipsTargetStreamer &TOut = getTargetStreamer();
4316
8
4317
8
  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4318
8
  assert(Inst.getOperand(0).isReg() &&
4319
8
         Inst.getOperand(1).isReg() &&
4320
8
         Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4321
8
4322
8
  unsigned DstReg = Inst.getOperand(0).getReg();
4323
8
  unsigned SrcReg = Inst.getOperand(1).getReg();
4324
8
  unsigned OpReg = Inst.getOperand(2).getReg();
4325
8
  unsigned OpCode;
4326
8
4327
8
  warnIfNoMacro(IDLoc);
4328
8
4329
8
  switch (Inst.getOpcode()) {
4330
8
  case Mips::SGE:
4331
4
    OpCode = Mips::SLT;
4332
4
    break;
4333
8
  case Mips::SGEU:
4334
4
    OpCode = Mips::SLTu;
4335
4
    break;
4336
8
  default:
4337
0
    llvm_unreachable("unexpected 'sge' opcode");
4338
8
  }
4339
8
4340
8
  // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4341
8
  TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4342
8
  TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4343
8
4344
8
  return false;
4345
8
}
4346
4347
bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4348
20
                                 const MCSubtargetInfo *STI) {
4349
20
  MipsTargetStreamer &TOut = getTargetStreamer();
4350
20
4351
20
  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4352
20
  assert(Inst.getOperand(0).isReg() &&
4353
20
         Inst.getOperand(1).isReg() &&
4354
20
         Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4355
20
4356
20
  unsigned DstReg = Inst.getOperand(0).getReg();
4357
20
  unsigned SrcReg = Inst.getOperand(1).getReg();
4358
20
  int64_t ImmValue = Inst.getOperand(2).getImm();
4359
20
  unsigned OpRegCode, OpImmCode;
4360
20
4361
20
  warnIfNoMacro(IDLoc);
4362
20
4363
20
  switch (Inst.getOpcode()) {
4364
20
  case Mips::SGEImm:
4365
10
  case Mips::SGEImm64:
4366
10
    OpRegCode = Mips::SLT;
4367
10
    OpImmCode = Mips::SLTi;
4368
10
    break;
4369
10
  case Mips::SGEUImm:
4370
10
  case Mips::SGEUImm64:
4371
10
    OpRegCode = Mips::SLTu;
4372
10
    OpImmCode = Mips::SLTiu;
4373
10
    break;
4374
10
  default:
4375
0
    llvm_unreachable("unexpected 'sge' opcode with immediate");
4376
20
  }
4377
20
4378
20
  // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4379
20
  if (isInt<16>(ImmValue)) {
4380
8
    // Use immediate version of STL.
4381
8
    TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4382
8
    TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4383
12
  } else {
4384
12
    unsigned ImmReg = DstReg;
4385
12
    if (DstReg == SrcReg) {
4386
6
      unsigned ATReg = getATReg(Inst.getLoc());
4387
6
      if (!ATReg)
4388
0
        return true;
4389
6
      ImmReg = ATReg;
4390
6
    }
4391
12
4392
12
    if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4393
12
                      false, IDLoc, Out, STI))
4394
0
      return true;
4395
12
4396
12
    TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4397
12
    TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4398
12
  }
4399
20
4400
20
  return false;
4401
20
}
4402
4403
bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4404
12
                                 const MCSubtargetInfo *STI) {
4405
12
  MipsTargetStreamer &TOut = getTargetStreamer();
4406
12
4407
12
  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4408
12
  assert(Inst.getOperand(0).isReg() &&
4409
12
         Inst.getOperand(1).isReg() &&
4410
12
         Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4411
12
4412
12
  unsigned DstReg = Inst.getOperand(0).getReg();
4413
12
  unsigned SrcReg = Inst.getOperand(1).getReg();
4414
12
  unsigned ImmReg = DstReg;
4415
12
  int64_t ImmValue = Inst.getOperand(2).getImm();
4416
12
  unsigned OpCode;
4417
12
4418
12
  warnIfNoMacro(IDLoc);
4419
12
4420
12
  switch (Inst.getOpcode()) {
4421
12
  case Mips::SGTImm:
4422
6
  case Mips::SGTImm64:
4423
6
    OpCode = Mips::SLT;
4424
6
    break;
4425
6
  case Mips::SGTUImm:
4426
6
  case Mips::SGTUImm64:
4427
6
    OpCode = Mips::SLTu;
4428
6
    break;
4429
6
  default:
4430
0
    llvm_unreachable("unexpected 'sgt' opcode with immediate");
4431
12
  }
4432
12
4433
12
  if (DstReg == SrcReg) {
4434
6
    unsigned ATReg = getATReg(Inst.getLoc());
4435
6
    if (!ATReg)
4436
0
      return true;
4437
6
    ImmReg = ATReg;
4438
6
  }
4439
12
4440
12
  if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4441
12
                    false, IDLoc, Out, STI))
4442
0
    return true;
4443
12
4444
12
  // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4445
12
  TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4446
12
4447
12
  return false;
4448
12
}
4449
4450
bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4451
                                         MCStreamer &Out,
4452
314
                                         const MCSubtargetInfo *STI) {
4453
314
  MipsTargetStreamer &TOut = getTargetStreamer();
4454
314
4455
314
  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4456
314
  assert(Inst.getOperand(0).isReg() &&
4457
314
         Inst.getOperand(1).isReg() &&
4458
314
         Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4459
314
4460
314
  unsigned ATReg = Mips::NoRegister;
4461
314
  unsigned FinalDstReg = Mips::NoRegister;
4462
314
  unsigned DstReg = Inst.getOperand(0).getReg();
4463
314
  unsigned SrcReg = Inst.getOperand(1).getReg();
4464
314
  int64_t ImmValue = Inst.getOperand(2).getImm();
4465
314
4466
314
  bool Is32Bit = isInt<32>(ImmValue) || 
(62
!isGP64bit()62
&&
isUInt<32>(ImmValue)0
);
4467
314
4468
314
  unsigned FinalOpcode = Inst.getOpcode();
4469
314
4470
314
  if (DstReg == SrcReg) {
4471
148
    ATReg = getATReg(Inst.getLoc());
4472
148
    if (!ATReg)
4473
0
      return true;
4474
148
    FinalDstReg = DstReg;
4475
148
    DstReg = ATReg;
4476
148
  }
4477
314
4478
314
  if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4479
314
                     Inst.getLoc(), Out, STI)) {
4480
314
    switch (FinalOpcode) {
4481
314
    default:
4482
0
      llvm_unreachable("unimplemented expansion");
4483
314
    case Mips::ADDi:
4484
20
      FinalOpcode = Mips::ADD;
4485
20
      break;
4486
314
    case Mips::ADDiu:
4487
20
      FinalOpcode = Mips::ADDu;
4488
20
      break;
4489
314
    case Mips::ANDi:
4490
12
      FinalOpcode = Mips::AND;
4491
12
      break;
4492
314
    case Mips::NORImm:
4493
28
      FinalOpcode = Mips::NOR;
4494
28
      break;
4495
314
    case Mips::ORi:
4496
12
      FinalOpcode = Mips::OR;
4497
12
      break;
4498
314
    case Mips::SLTi:
4499
5
      FinalOpcode = Mips::SLT;
4500
5
      break;
4501
314
    case Mips::SLTiu:
4502
5
      FinalOpcode = Mips::SLTu;
4503
5
      break;
4504
314
    case Mips::XORi:
4505
12
      FinalOpcode = Mips::XOR;
4506
12
      break;
4507
314
    case Mips::ADDi_MM:
4508
10
      FinalOpcode = Mips::ADD_MM;
4509
10
      break;
4510
314
    case Mips::ADDiu_MM:
4511
10
      FinalOpcode = Mips::ADDu_MM;
4512
10
      break;
4513
314
    case Mips::ANDi_MM:
4514
12
      FinalOpcode = Mips::AND_MM;
4515
12
      break;
4516
314
    case Mips::ORi_MM:
4517
12
      FinalOpcode = Mips::OR_MM;
4518
12
      break;
4519
314
    case Mips::SLTi_MM:
4520
5
      FinalOpcode = Mips::SLT_MM;
4521
5
      break;
4522
314
    case Mips::SLTiu_MM:
4523
5
      FinalOpcode = Mips::SLTu_MM;
4524
5
      break;
4525
314
    case Mips::XORi_MM:
4526
12
      FinalOpcode = Mips::XOR_MM;
4527
12
      break;
4528
314
    case Mips::ANDi64:
4529
22
      FinalOpcode = Mips::AND64;
4530
22
      break;
4531
314
    case Mips::NORImm64:
4532
28
      FinalOpcode = Mips::NOR64;
4533
28
      break;
4534
314
    case Mips::ORi64:
4535
22
      FinalOpcode = Mips::OR64;
4536
22
      break;
4537
314
    case Mips::SLTImm64:
4538
20
      FinalOpcode = Mips::SLT64;
4539
20
      break;
4540
314
    case Mips::SLTUImm64:
4541
20
      FinalOpcode = Mips::SLTu64;
4542
20
      break;
4543
314
    case Mips::XORi64:
4544
22
      FinalOpcode = Mips::XOR64;
4545
22
      break;
4546
314
    }
4547
314
4548
314
    if (FinalDstReg == Mips::NoRegister)
4549
166
      TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4550
148
    else
4551
148
      TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4552
314
    return false;
4553
314
  }
4554
0
  return true;
4555
0
}
4556
4557
bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4558
40
                                   const MCSubtargetInfo *STI) {
4559
40
  MipsTargetStreamer &TOut = getTargetStreamer();
4560
40
  unsigned ATReg = Mips::NoRegister;
4561
40
  unsigned DReg = Inst.getOperand(0).getReg();
4562
40
  unsigned SReg = Inst.getOperand(1).getReg();
4563
40
  unsigned TReg = Inst.ge