Bug Summary

File:lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 2642, column 18
The result of the right shift is undefined due to shifting by '4294967295', which is greater or equal to the width of type 'uint64_t'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name MipsAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~svn374877/build-llvm/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips -I /build/llvm-toolchain-snapshot-10~svn374877/build-llvm/lib/Target/Mips -I /build/llvm-toolchain-snapshot-10~svn374877/build-llvm/include -I /build/llvm-toolchain-snapshot-10~svn374877/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-10~svn374877/build-llvm/lib/Target/Mips/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~svn374877=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2019-10-15-233810-7101-1 -x c++ /build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

1//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "MCTargetDesc/MipsABIFlagsSection.h"
10#include "MCTargetDesc/MipsABIInfo.h"
11#include "MCTargetDesc/MipsBaseInfo.h"
12#include "MCTargetDesc/MipsMCExpr.h"
13#include "MCTargetDesc/MipsMCTargetDesc.h"
14#include "MipsTargetStreamer.h"
15#include "TargetInfo/MipsTargetInfo.h"
16#include "llvm/ADT/APFloat.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/ADT/Triple.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/BinaryFormat/ELF.h"
24#include "llvm/MC/MCContext.h"
25#include "llvm/MC/MCExpr.h"
26#include "llvm/MC/MCInst.h"
27#include "llvm/MC/MCInstrDesc.h"
28#include "llvm/MC/MCObjectFileInfo.h"
29#include "llvm/MC/MCParser/MCAsmLexer.h"
30#include "llvm/MC/MCParser/MCAsmParser.h"
31#include "llvm/MC/MCParser/MCAsmParserExtension.h"
32#include "llvm/MC/MCParser/MCAsmParserUtils.h"
33#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34#include "llvm/MC/MCParser/MCTargetAsmParser.h"
35#include "llvm/MC/MCSectionELF.h"
36#include "llvm/MC/MCStreamer.h"
37#include "llvm/MC/MCSubtargetInfo.h"
38#include "llvm/MC/MCSymbol.h"
39#include "llvm/MC/MCSymbolELF.h"
40#include "llvm/MC/MCValue.h"
41#include "llvm/MC/SubtargetFeature.h"
42#include "llvm/Support/Alignment.h"
43#include "llvm/Support/Casting.h"
44#include "llvm/Support/CommandLine.h"
45#include "llvm/Support/Compiler.h"
46#include "llvm/Support/Debug.h"
47#include "llvm/Support/ErrorHandling.h"
48#include "llvm/Support/MathExtras.h"
49#include "llvm/Support/SMLoc.h"
50#include "llvm/Support/SourceMgr.h"
51#include "llvm/Support/TargetRegistry.h"
52#include "llvm/Support/raw_ostream.h"
53#include <algorithm>
54#include <cassert>
55#include <cstdint>
56#include <memory>
57#include <string>
58#include <utility>
59
60using namespace llvm;
61
62#define DEBUG_TYPE"mips-asm-parser" "mips-asm-parser"
63
64namespace llvm {
65
66class MCInstrInfo;
67
68} // end namespace llvm
69
70extern cl::opt<bool> EmitJalrReloc;
71
72namespace {
73
74class MipsAssemblerOptions {
75public:
76 MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
77
78 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
83 }
84
85 unsigned getATRegIndex() const { return ATReg; }
86 bool setATRegIndex(unsigned Reg) {
87 if (Reg > 31)
88 return false;
89
90 ATReg = Reg;
91 return true;
92 }
93
94 bool isReorder() const { return Reorder; }
95 void setReorder() { Reorder = true; }
96 void setNoReorder() { Reorder = false; }
97
98 bool isMacro() const { return Macro; }
99 void setMacro() { Macro = true; }
100 void setNoMacro() { Macro = false; }
101
102 const FeatureBitset &getFeatures() const { return Features; }
103 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
104
105 // Set of features that are either architecture features or referenced
106 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
107 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
108 // The reason we need this mask is explained in the selectArch function.
109 // FIXME: Ideally we would like TableGen to generate this information.
110 static const FeatureBitset AllArchRelatedMask;
111
112private:
113 unsigned ATReg = 1;
114 bool Reorder = true;
115 bool Macro = true;
116 FeatureBitset Features;
117};
118
119} // end anonymous namespace
120
121const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
130};
131
132namespace {
133
134class MipsAsmParser : public MCTargetAsmParser {
135 MipsTargetStreamer &getTargetStreamer() {
136 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
137 return static_cast<MipsTargetStreamer &>(TS);
138 }
139
140 MipsABIInfo ABI;
141 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
142 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
143 // nullptr, which indicates that no function is currently
144 // selected. This usually happens after an '.end func'
145 // directive.
146 bool IsLittleEndian;
147 bool IsPicEnabled;
148 bool IsCpRestoreSet;
149 int CpRestoreOffset;
150 unsigned GPReg;
151 unsigned CpSaveLocation;
152 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
153 bool CpSaveLocationIsRegister;
154
155 // Map of register aliases created via the .set directive.
156 StringMap<AsmToken> RegisterSets;
157
158 // Print a warning along with its fix-it message at the given range.
159 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
160 SMRange Range, bool ShowColors = true);
161
162 void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
163
164#define GET_ASSEMBLER_HEADER
165#include "MipsGenAsmMatcher.inc"
166
167 unsigned
168 checkEarlyTargetMatchPredicate(MCInst &Inst,
169 const OperandVector &Operands) override;
170 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
171
172 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
173 OperandVector &Operands, MCStreamer &Out,
174 uint64_t &ErrorInfo,
175 bool MatchingInlineAsm) override;
176
177 /// Parse a register as used in CFI directives
178 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
179
180 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
181
182 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
183
184 bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
185
186 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
187 SMLoc NameLoc, OperandVector &Operands) override;
188
189 bool ParseDirective(AsmToken DirectiveID) override;
190
191 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
192 OperandMatchResultTy
193 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
194 StringRef Identifier, SMLoc S);
195 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
196 const AsmToken &Token,
197 SMLoc S);
198 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
199 SMLoc S);
200 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
201 OperandMatchResultTy parseImm(OperandVector &Operands);
202 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
203 OperandMatchResultTy parseInvNum(OperandVector &Operands);
204 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
205
206 bool searchSymbolAlias(OperandVector &Operands);
207
208 bool parseOperand(OperandVector &, StringRef Mnemonic);
209
210 enum MacroExpanderResultTy {
211 MER_NotAMacro,
212 MER_Success,
213 MER_Fail,
214 };
215
216 // Expands assembly pseudo instructions.
217 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
218 MCStreamer &Out,
219 const MCSubtargetInfo *STI);
220
221 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
222 const MCSubtargetInfo *STI);
223
224 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
225 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
226 MCStreamer &Out, const MCSubtargetInfo *STI);
227
228 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
229 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
230 MCStreamer &Out, const MCSubtargetInfo *STI);
231
232 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
233
234 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
235 MCStreamer &Out, const MCSubtargetInfo *STI);
236
237 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
238 const MCSubtargetInfo *STI);
239 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
240 const MCSubtargetInfo *STI);
241 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
242 const MCSubtargetInfo *STI);
243 bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
244 MCStreamer &Out, const MCSubtargetInfo *STI);
245
246 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
247 const MCOperand &Offset, bool Is32BitAddress,
248 SMLoc IDLoc, MCStreamer &Out,
249 const MCSubtargetInfo *STI);
250
251 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
252 const MCSubtargetInfo *STI);
253
254 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI, bool IsLoad);
256
257 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI);
259
260 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI);
262
263 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264 const MCSubtargetInfo *STI);
265
266 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
267 const MCSubtargetInfo *STI);
268
269 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270 const MCSubtargetInfo *STI, const bool IsMips64,
271 const bool Signed);
272
273 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
274 MCStreamer &Out, const MCSubtargetInfo *STI);
275
276 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI);
278
279 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
281
282 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
284
285 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
287
288 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289 const MCSubtargetInfo *STI);
290
291 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292 const MCSubtargetInfo *STI);
293
294 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
295 MCStreamer &Out, const MCSubtargetInfo *STI);
296 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
298 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
300 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301 const MCSubtargetInfo *STI);
302
303 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304 const MCSubtargetInfo *STI);
305
306 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
307 const MCSubtargetInfo *STI);
308
309 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310 const MCSubtargetInfo *STI);
311
312 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI);
314
315 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316 const MCSubtargetInfo *STI);
317
318 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319 const MCSubtargetInfo *STI, bool IsLoad);
320
321 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322 const MCSubtargetInfo *STI);
323
324 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325 const MCSubtargetInfo *STI);
326
327 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
328 const MCSubtargetInfo *STI);
329
330 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
331 const MCSubtargetInfo *STI);
332
333 bool reportParseError(Twine ErrorMsg);
334 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
335
336 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
337
338 bool isEvaluated(const MCExpr *Expr);
339 bool parseSetMips0Directive();
340 bool parseSetArchDirective();
341 bool parseSetFeature(uint64_t Feature);
342 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
343 bool parseDirectiveCpLoad(SMLoc Loc);
344 bool parseDirectiveCpLocal(SMLoc Loc);
345 bool parseDirectiveCpRestore(SMLoc Loc);
346 bool parseDirectiveCPSetup();
347 bool parseDirectiveCPReturn();
348 bool parseDirectiveNaN();
349 bool parseDirectiveSet();
350 bool parseDirectiveOption();
351 bool parseInsnDirective();
352 bool parseRSectionDirective(StringRef Section);
353 bool parseSSectionDirective(StringRef Section, unsigned Type);
354
355 bool parseSetAtDirective();
356 bool parseSetNoAtDirective();
357 bool parseSetMacroDirective();
358 bool parseSetNoMacroDirective();
359 bool parseSetMsaDirective();
360 bool parseSetNoMsaDirective();
361 bool parseSetNoDspDirective();
362 bool parseSetReorderDirective();
363 bool parseSetNoReorderDirective();
364 bool parseSetMips16Directive();
365 bool parseSetNoMips16Directive();
366 bool parseSetFpDirective();
367 bool parseSetOddSPRegDirective();
368 bool parseSetNoOddSPRegDirective();
369 bool parseSetPopDirective();
370 bool parseSetPushDirective();
371 bool parseSetSoftFloatDirective();
372 bool parseSetHardFloatDirective();
373 bool parseSetMtDirective();
374 bool parseSetNoMtDirective();
375 bool parseSetNoCRCDirective();
376 bool parseSetNoVirtDirective();
377 bool parseSetNoGINVDirective();
378
379 bool parseSetAssignment();
380
381 bool parseDirectiveGpWord();
382 bool parseDirectiveGpDWord();
383 bool parseDirectiveDtpRelWord();
384 bool parseDirectiveDtpRelDWord();
385 bool parseDirectiveTpRelWord();
386 bool parseDirectiveTpRelDWord();
387 bool parseDirectiveModule();
388 bool parseDirectiveModuleFP();
389 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
390 StringRef Directive);
391
392 bool parseInternalDirectiveReallowModule();
393
394 bool eatComma(StringRef ErrorStr);
395
396 int matchCPURegisterName(StringRef Symbol);
397
398 int matchHWRegsRegisterName(StringRef Symbol);
399
400 int matchFPURegisterName(StringRef Name);
401
402 int matchFCCRegisterName(StringRef Name);
403
404 int matchACRegisterName(StringRef Name);
405
406 int matchMSA128RegisterName(StringRef Name);
407
408 int matchMSA128CtrlRegisterName(StringRef Name);
409
410 unsigned getReg(int RC, int RegNo);
411
412 /// Returns the internal register number for the current AT. Also checks if
413 /// the current AT is unavailable (set to $0) and gives an error if it is.
414 /// This should be used in pseudo-instruction expansions which need AT.
415 unsigned getATReg(SMLoc Loc);
416
417 bool canUseATReg();
418
419 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
420 const MCSubtargetInfo *STI);
421
422 // Helper function that checks if the value of a vector index is within the
423 // boundaries of accepted values for each RegisterKind
424 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
425 bool validateMSAIndex(int Val, int RegKind);
426
427 // Selects a new architecture by updating the FeatureBits with the necessary
428 // info including implied dependencies.
429 // Internally, it clears all the feature bits related to *any* architecture
430 // and selects the new one using the ToggleFeature functionality of the
431 // MCSubtargetInfo object that handles implied dependencies. The reason we
432 // clear all the arch related bits manually is because ToggleFeature only
433 // clears the features that imply the feature being cleared and not the
434 // features implied by the feature being cleared. This is easier to see
435 // with an example:
436 // --------------------------------------------------
437 // | Feature | Implies |
438 // | -------------------------------------------------|
439 // | FeatureMips1 | None |
440 // | FeatureMips2 | FeatureMips1 |
441 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
442 // | FeatureMips4 | FeatureMips3 |
443 // | ... | |
444 // --------------------------------------------------
445 //
446 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
447 // FeatureMipsGP64 | FeatureMips1)
448 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
449 void selectArch(StringRef ArchFeature) {
450 MCSubtargetInfo &STI = copySTI();
451 FeatureBitset FeatureBits = STI.getFeatureBits();
452 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
453 STI.setFeatureBits(FeatureBits);
454 setAvailableFeatures(
455 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
456 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
457 }
458
459 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
460 if (!(getSTI().getFeatureBits()[Feature])) {
461 MCSubtargetInfo &STI = copySTI();
462 setAvailableFeatures(
463 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
464 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
465 }
466 }
467
468 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
469 if (getSTI().getFeatureBits()[Feature]) {
470 MCSubtargetInfo &STI = copySTI();
471 setAvailableFeatures(
472 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
473 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
474 }
475 }
476
477 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
478 setFeatureBits(Feature, FeatureString);
479 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
480 }
481
482 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
483 clearFeatureBits(Feature, FeatureString);
484 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
485 }
486
487public:
488 enum MipsMatchResultTy {
489 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
490 Match_RequiresDifferentOperands,
491 Match_RequiresNoZeroRegister,
492 Match_RequiresSameSrcAndDst,
493 Match_NoFCCRegisterForCurrentISA,
494 Match_NonZeroOperandForSync,
495 Match_NonZeroOperandForMTCX,
496 Match_RequiresPosSizeRange0_32,
497 Match_RequiresPosSizeRange33_64,
498 Match_RequiresPosSizeUImm6,
499#define GET_OPERAND_DIAGNOSTIC_TYPES
500#include "MipsGenAsmMatcher.inc"
501#undef GET_OPERAND_DIAGNOSTIC_TYPES
502 };
503
504 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
505 const MCInstrInfo &MII, const MCTargetOptions &Options)
506 : MCTargetAsmParser(Options, sti, MII),
507 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
508 sti.getCPU(), Options)) {
509 MCAsmParserExtension::Initialize(parser);
510
511 parser.addAliasForDirective(".asciiz", ".asciz");
512 parser.addAliasForDirective(".hword", ".2byte");
513 parser.addAliasForDirective(".word", ".4byte");
514 parser.addAliasForDirective(".dword", ".8byte");
515
516 // Initialize the set of available features.
517 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
518
519 // Remember the initial assembler options. The user can not modify these.
520 AssemblerOptions.push_back(
521 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
522
523 // Create an assembler options environment for the user to modify.
524 AssemblerOptions.push_back(
525 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
526
527 getTargetStreamer().updateABIInfo(*this);
528
529 if (!isABI_O32() && !useOddSPReg() != 0)
530 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
531
532 CurrentFn = nullptr;
533
534 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
535
536 IsCpRestoreSet = false;
537 CpRestoreOffset = -1;
538 GPReg = ABI.GetGlobalPtr();
539
540 const Triple &TheTriple = sti.getTargetTriple();
541 IsLittleEndian = TheTriple.isLittleEndian();
542
543 if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
544 report_fatal_error("microMIPS64R6 is not supported", false);
545
546 if (!isABI_O32() && inMicroMipsMode())
547 report_fatal_error("microMIPS64 is not supported", false);
548 }
549
550 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
551 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
552
553 bool isGP64bit() const {
554 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
555 }
556
557 bool isFP64bit() const {
558 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
559 }
560
561 const MipsABIInfo &getABI() const { return ABI; }
562 bool isABI_N32() const { return ABI.IsN32(); }
563 bool isABI_N64() const { return ABI.IsN64(); }
564 bool isABI_O32() const { return ABI.IsO32(); }
565 bool isABI_FPXX() const {
566 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
567 }
568
569 bool useOddSPReg() const {
570 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
571 }
572
573 bool inMicroMipsMode() const {
574 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
575 }
576
577 bool hasMips1() const {
578 return getSTI().getFeatureBits()[Mips::FeatureMips1];
579 }
580
581 bool hasMips2() const {
582 return getSTI().getFeatureBits()[Mips::FeatureMips2];
583 }
584
585 bool hasMips3() const {
586 return getSTI().getFeatureBits()[Mips::FeatureMips3];
587 }
588
589 bool hasMips4() const {
590 return getSTI().getFeatureBits()[Mips::FeatureMips4];
591 }
592
593 bool hasMips5() const {
594 return getSTI().getFeatureBits()[Mips::FeatureMips5];
595 }
596
597 bool hasMips32() const {
598 return getSTI().getFeatureBits()[Mips::FeatureMips32];
599 }
600
601 bool hasMips64() const {
602 return getSTI().getFeatureBits()[Mips::FeatureMips64];
603 }
604
605 bool hasMips32r2() const {
606 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
607 }
608
609 bool hasMips64r2() const {
610 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
611 }
612
613 bool hasMips32r3() const {
614 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
615 }
616
617 bool hasMips64r3() const {
618 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
619 }
620
621 bool hasMips32r5() const {
622 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
623 }
624
625 bool hasMips64r5() const {
626 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
627 }
628
629 bool hasMips32r6() const {
630 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
631 }
632
633 bool hasMips64r6() const {
634 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
635 }
636
637 bool hasDSP() const {
638 return getSTI().getFeatureBits()[Mips::FeatureDSP];
639 }
640
641 bool hasDSPR2() const {
642 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
643 }
644
645 bool hasDSPR3() const {
646 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
647 }
648
649 bool hasMSA() const {
650 return getSTI().getFeatureBits()[Mips::FeatureMSA];
651 }
652
653 bool hasCnMips() const {
654 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
655 }
656
657 bool inPicMode() {
658 return IsPicEnabled;
659 }
660
661 bool inMips16Mode() const {
662 return getSTI().getFeatureBits()[Mips::FeatureMips16];
663 }
664
665 bool useTraps() const {
666 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
667 }
668
669 bool useSoftFloat() const {
670 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
671 }
672 bool hasMT() const {
673 return getSTI().getFeatureBits()[Mips::FeatureMT];
674 }
675
676 bool hasCRC() const {
677 return getSTI().getFeatureBits()[Mips::FeatureCRC];
678 }
679
680 bool hasVirt() const {
681 return getSTI().getFeatureBits()[Mips::FeatureVirt];
682 }
683
684 bool hasGINV() const {
685 return getSTI().getFeatureBits()[Mips::FeatureGINV];
686 }
687
688 /// Warn if RegIndex is the same as the current AT.
689 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
690
691 void warnIfNoMacro(SMLoc Loc);
692
693 bool isLittle() const { return IsLittleEndian; }
694
695 const MCExpr *createTargetUnaryExpr(const MCExpr *E,
696 AsmToken::TokenKind OperatorToken,
697 MCContext &Ctx) override {
698 switch(OperatorToken) {
699 default:
700 llvm_unreachable("Unknown token")::llvm::llvm_unreachable_internal("Unknown token", "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 700)
;
701 return nullptr;
702 case AsmToken::PercentCall16:
703 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, E, Ctx);
704 case AsmToken::PercentCall_Hi:
705 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, E, Ctx);
706 case AsmToken::PercentCall_Lo:
707 return MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, E, Ctx);
708 case AsmToken::PercentDtprel_Hi:
709 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_HI, E, Ctx);
710 case AsmToken::PercentDtprel_Lo:
711 return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL_LO, E, Ctx);
712 case AsmToken::PercentGot:
713 return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
714 case AsmToken::PercentGot_Disp:
715 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, E, Ctx);
716 case AsmToken::PercentGot_Hi:
717 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, E, Ctx);
718 case AsmToken::PercentGot_Lo:
719 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_LO16, E, Ctx);
720 case AsmToken::PercentGot_Ofst:
721 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_OFST, E, Ctx);
722 case AsmToken::PercentGot_Page:
723 return MipsMCExpr::create(MipsMCExpr::MEK_GOT_PAGE, E, Ctx);
724 case AsmToken::PercentGottprel:
725 return MipsMCExpr::create(MipsMCExpr::MEK_GOTTPREL, E, Ctx);
726 case AsmToken::PercentGp_Rel:
727 return MipsMCExpr::create(MipsMCExpr::MEK_GPREL, E, Ctx);
728 case AsmToken::PercentHi:
729 return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
730 case AsmToken::PercentHigher:
731 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, E, Ctx);
732 case AsmToken::PercentHighest:
733 return MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, E, Ctx);
734 case AsmToken::PercentLo:
735 return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
736 case AsmToken::PercentNeg:
737 return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
738 case AsmToken::PercentPcrel_Hi:
739 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_HI16, E, Ctx);
740 case AsmToken::PercentPcrel_Lo:
741 return MipsMCExpr::create(MipsMCExpr::MEK_PCREL_LO16, E, Ctx);
742 case AsmToken::PercentTlsgd:
743 return MipsMCExpr::create(MipsMCExpr::MEK_TLSGD, E, Ctx);
744 case AsmToken::PercentTlsldm:
745 return MipsMCExpr::create(MipsMCExpr::MEK_TLSLDM, E, Ctx);
746 case AsmToken::PercentTprel_Hi:
747 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_HI, E, Ctx);
748 case AsmToken::PercentTprel_Lo:
749 return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
750 }
751 }
752};
753
754/// MipsOperand - Instances of this class represent a parsed Mips machine
755/// instruction.
756class MipsOperand : public MCParsedAsmOperand {
757public:
758 /// Broad categories of register classes
759 /// The exact class is finalized by the render method.
760 enum RegKind {
761 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
762 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
763 /// isFP64bit())
764 RegKind_FCC = 4, /// FCC
765 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
766 RegKind_MSACtrl = 16, /// MSA control registers
767 RegKind_COP2 = 32, /// COP2
768 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
769 /// context).
770 RegKind_CCR = 128, /// CCR
771 RegKind_HWRegs = 256, /// HWRegs
772 RegKind_COP3 = 512, /// COP3
773 RegKind_COP0 = 1024, /// COP0
774 /// Potentially any (e.g. $1)
775 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
776 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
777 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
778 };
779
780private:
781 enum KindTy {
782 k_Immediate, /// An immediate (possibly involving symbol references)
783 k_Memory, /// Base + Offset Memory Address
784 k_RegisterIndex, /// A register index in one or more RegKind.
785 k_Token, /// A simple token
786 k_RegList, /// A physical register list
787 } Kind;
788
789public:
790 MipsOperand(KindTy K, MipsAsmParser &Parser)
791 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
792
793 ~MipsOperand() override {
794 switch (Kind) {
795 case k_Memory:
796 delete Mem.Base;
797 break;
798 case k_RegList:
799 delete RegList.List;
800 break;
801 case k_Immediate:
802 case k_RegisterIndex:
803 case k_Token:
804 break;
805 }
806 }
807
808private:
809 /// For diagnostics, and checking the assembler temporary
810 MipsAsmParser &AsmParser;
811
812 struct Token {
813 const char *Data;
814 unsigned Length;
815 };
816
817 struct RegIdxOp {
818 unsigned Index; /// Index into the register class
819 RegKind Kind; /// Bitfield of the kinds it could possibly be
820 struct Token Tok; /// The input token this operand originated from.
821 const MCRegisterInfo *RegInfo;
822 };
823
824 struct ImmOp {
825 const MCExpr *Val;
826 };
827
828 struct MemOp {
829 MipsOperand *Base;
830 const MCExpr *Off;
831 };
832
833 struct RegListOp {
834 SmallVector<unsigned, 10> *List;
835 };
836
837 union {
838 struct Token Tok;
839 struct RegIdxOp RegIdx;
840 struct ImmOp Imm;
841 struct MemOp Mem;
842 struct RegListOp RegList;
843 };
844
845 SMLoc StartLoc, EndLoc;
846
847 /// Internal constructor for register kinds
848 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
849 RegKind RegKind,
850 const MCRegisterInfo *RegInfo,
851 SMLoc S, SMLoc E,
852 MipsAsmParser &Parser) {
853 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
854 Op->RegIdx.Index = Index;
855 Op->RegIdx.RegInfo = RegInfo;
856 Op->RegIdx.Kind = RegKind;
857 Op->RegIdx.Tok.Data = Str.data();
858 Op->RegIdx.Tok.Length = Str.size();
859 Op->StartLoc = S;
860 Op->EndLoc = E;
861 return Op;
862 }
863
864public:
865 /// Coerce the register to GPR32 and return the real register for the current
866 /// target.
867 unsigned getGPR32Reg() const {
868 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 868, __PRETTY_FUNCTION__))
;
869 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
870 unsigned ClassID = Mips::GPR32RegClassID;
871 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
872 }
873
874 /// Coerce the register to GPR32 and return the real register for the current
875 /// target.
876 unsigned getGPRMM16Reg() const {
877 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 877, __PRETTY_FUNCTION__))
;
878 unsigned ClassID = Mips::GPR32RegClassID;
879 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
880 }
881
882 /// Coerce the register to GPR64 and return the real register for the current
883 /// target.
884 unsigned getGPR64Reg() const {
885 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_GPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 885, __PRETTY_FUNCTION__))
;
886 unsigned ClassID = Mips::GPR64RegClassID;
887 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
888 }
889
890private:
891 /// Coerce the register to AFGR64 and return the real register for the current
892 /// target.
893 unsigned getAFGR64Reg() const {
894 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 894, __PRETTY_FUNCTION__))
;
895 if (RegIdx.Index % 2 != 0)
896 AsmParser.Warning(StartLoc, "Float register should be even.");
897 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
898 .getRegister(RegIdx.Index / 2);
899 }
900
901 /// Coerce the register to FGR64 and return the real register for the current
902 /// target.
903 unsigned getFGR64Reg() const {
904 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 904, __PRETTY_FUNCTION__))
;
905 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
906 .getRegister(RegIdx.Index);
907 }
908
909 /// Coerce the register to FGR32 and return the real register for the current
910 /// target.
911 unsigned getFGR32Reg() const {
912 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FGR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 912, __PRETTY_FUNCTION__))
;
913 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
914 .getRegister(RegIdx.Index);
915 }
916
917 /// Coerce the register to FCC and return the real register for the current
918 /// target.
919 unsigned getFCCReg() const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_FCC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 920, __PRETTY_FUNCTION__))
;
921 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
922 .getRegister(RegIdx.Index);
923 }
924
925 /// Coerce the register to MSA128 and return the real register for the current
926 /// target.
927 unsigned getMSA128Reg() const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 928, __PRETTY_FUNCTION__))
;
929 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
930 // identical
931 unsigned ClassID = Mips::MSA128BRegClassID;
932 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
933 }
934
935 /// Coerce the register to MSACtrl and return the real register for the
936 /// current target.
937 unsigned getMSACtrlReg() const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 938, __PRETTY_FUNCTION__))
;
939 unsigned ClassID = Mips::MSACtrlRegClassID;
940 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
941 }
942
943 /// Coerce the register to COP0 and return the real register for the
944 /// current target.
945 unsigned getCOP0Reg() const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP0) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 946, __PRETTY_FUNCTION__))
;
947 unsigned ClassID = Mips::COP0RegClassID;
948 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
949 }
950
951 /// Coerce the register to COP2 and return the real register for the
952 /// current target.
953 unsigned getCOP2Reg() const {
954 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP2) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 954, __PRETTY_FUNCTION__))
;
955 unsigned ClassID = Mips::COP2RegClassID;
956 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
957 }
958
959 /// Coerce the register to COP3 and return the real register for the
960 /// current target.
961 unsigned getCOP3Reg() const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_COP3) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 962, __PRETTY_FUNCTION__))
;
963 unsigned ClassID = Mips::COP3RegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
965 }
966
967 /// Coerce the register to ACC64DSP and return the real register for the
968 /// current target.
969 unsigned getACC64DSPReg() const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 970, __PRETTY_FUNCTION__))
;
971 unsigned ClassID = Mips::ACC64DSPRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
973 }
974
975 /// Coerce the register to HI32DSP and return the real register for the
976 /// current target.
977 unsigned getHI32DSPReg() const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 978, __PRETTY_FUNCTION__))
;
979 unsigned ClassID = Mips::HI32DSPRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
981 }
982
983 /// Coerce the register to LO32DSP and return the real register for the
984 /// current target.
985 unsigned getLO32DSPReg() const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_ACC) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 986, __PRETTY_FUNCTION__))
;
987 unsigned ClassID = Mips::LO32DSPRegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
989 }
990
991 /// Coerce the register to CCR and return the real register for the
992 /// current target.
993 unsigned getCCRReg() const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_CCR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 994, __PRETTY_FUNCTION__))
;
995 unsigned ClassID = Mips::CCRRegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
997 }
998
999 /// Coerce the register to HWRegs and return the real register for the
1000 /// current target.
1001 unsigned getHWRegsReg() const {
1002 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!")((isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!") ? static_cast<void> (0) : __assert_fail
("isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1002, __PRETTY_FUNCTION__))
;
1003 unsigned ClassID = Mips::HWRegsRegClassID;
1004 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1005 }
1006
1007public:
1008 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1009 // Add as immediate when possible. Null MCExpr = 0.
1010 if (!Expr)
1011 Inst.addOperand(MCOperand::createImm(0));
1012 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1013 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1014 else
1015 Inst.addOperand(MCOperand::createExpr(Expr));
1016 }
1017
1018 void addRegOperands(MCInst &Inst, unsigned N) const {
1019 llvm_unreachable("Use a custom parser instead")::llvm::llvm_unreachable_internal("Use a custom parser instead"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1019)
;
1020 }
1021
1022 /// Render the operand to an MCInst as a GPR32
1023 /// Asserts if the wrong number of operands are requested, or the operand
1024 /// is not a k_RegisterIndex compatible with RegKind_GPR
1025 void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1026 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1026, __PRETTY_FUNCTION__))
;
1027 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1028 }
1029
1030 void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1031 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1031, __PRETTY_FUNCTION__))
;
1032 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1033 }
1034
1035 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1036 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1036, __PRETTY_FUNCTION__))
;
1037 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1038 }
1039
1040 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1041 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1041, __PRETTY_FUNCTION__))
;
1042 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1043 }
1044
1045 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1046 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1046, __PRETTY_FUNCTION__))
;
1047 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1048 }
1049
1050 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1051 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1051, __PRETTY_FUNCTION__))
;
1052 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1053 }
1054
1055 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1056 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1056, __PRETTY_FUNCTION__))
;
1057 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1058 }
1059
1060 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1061 unsigned N) const {
1062 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1062, __PRETTY_FUNCTION__))
;
1063 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1064 }
1065
1066 /// Render the operand to an MCInst as a GPR64
1067 /// Asserts if the wrong number of operands are requested, or the operand
1068 /// is not a k_RegisterIndex compatible with RegKind_GPR
1069 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1070 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1070, __PRETTY_FUNCTION__))
;
1071 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1072 }
1073
1074 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1075 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1075, __PRETTY_FUNCTION__))
;
1076 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1077 }
1078
1079 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1080 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1080, __PRETTY_FUNCTION__))
;
1081 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1082 }
1083
1084 void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1085 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1085, __PRETTY_FUNCTION__))
;
1086 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1087 }
1088
1089 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1090 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1090, __PRETTY_FUNCTION__))
;
1091 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1092 }
1093
1094 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1095 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1095, __PRETTY_FUNCTION__))
;
1096 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1097 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1098 // FIXME: This should propagate failure up to parseStatement.
1099 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1100 AsmParser.getParser().printError(
1101 StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1102 "registers");
1103 }
1104
1105 void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1106 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1106, __PRETTY_FUNCTION__))
;
1107 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1108 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1109 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1110 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1111 "registers");
1112 }
1113
1114 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1115 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1115, __PRETTY_FUNCTION__))
;
1116 Inst.addOperand(MCOperand::createReg(getFCCReg()));
1117 }
1118
1119 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1120 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1120, __PRETTY_FUNCTION__))
;
1121 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1122 }
1123
1124 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1125 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1125, __PRETTY_FUNCTION__))
;
1126 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1127 }
1128
1129 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1130 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1130, __PRETTY_FUNCTION__))
;
1131 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1132 }
1133
1134 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1135 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1135, __PRETTY_FUNCTION__))
;
1136 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1137 }
1138
1139 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1140 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1140, __PRETTY_FUNCTION__))
;
1141 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1142 }
1143
1144 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1145 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1145, __PRETTY_FUNCTION__))
;
1146 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1147 }
1148
1149 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1150 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1150, __PRETTY_FUNCTION__))
;
1151 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1152 }
1153
1154 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1155 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1155, __PRETTY_FUNCTION__))
;
1156 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1157 }
1158
1159 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1160 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1160, __PRETTY_FUNCTION__))
;
1161 Inst.addOperand(MCOperand::createReg(getCCRReg()));
1162 }
1163
1164 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1165 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1165, __PRETTY_FUNCTION__))
;
1166 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1167 }
1168
1169 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1170 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1171 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1171, __PRETTY_FUNCTION__))
;
1172 uint64_t Imm = getConstantImm() - Offset;
1173 Imm &= (1ULL << Bits) - 1;
1174 Imm += Offset;
1175 Imm += AdjustOffset;
1176 Inst.addOperand(MCOperand::createImm(Imm));
1177 }
1178
1179 template <unsigned Bits>
1180 void addSImmOperands(MCInst &Inst, unsigned N) const {
1181 if (isImm() && !isConstantImm()) {
1182 addExpr(Inst, getImm());
1183 return;
1184 }
1185 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1186 }
1187
1188 template <unsigned Bits>
1189 void addUImmOperands(MCInst &Inst, unsigned N) const {
1190 if (isImm() && !isConstantImm()) {
1191 addExpr(Inst, getImm());
1192 return;
1193 }
1194 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1195 }
1196
1197 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1198 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1199 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1199, __PRETTY_FUNCTION__))
;
1200 int64_t Imm = getConstantImm() - Offset;
1201 Imm = SignExtend64<Bits>(Imm);
1202 Imm += Offset;
1203 Imm += AdjustOffset;
1204 Inst.addOperand(MCOperand::createImm(Imm));
1205 }
1206
1207 void addImmOperands(MCInst &Inst, unsigned N) const {
1208 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1208, __PRETTY_FUNCTION__))
;
1209 const MCExpr *Expr = getImm();
1210 addExpr(Inst, Expr);
1211 }
1212
1213 void addMemOperands(MCInst &Inst, unsigned N) const {
1214 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1214, __PRETTY_FUNCTION__))
;
1215
1216 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1217 ? getMemBase()->getGPR64Reg()
1218 : getMemBase()->getGPR32Reg()));
1219
1220 const MCExpr *Expr = getMemOff();
1221 addExpr(Inst, Expr);
1222 }
1223
1224 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1225 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1225, __PRETTY_FUNCTION__))
;
1226
1227 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1228
1229 const MCExpr *Expr = getMemOff();
1230 addExpr(Inst, Expr);
1231 }
1232
1233 void addRegListOperands(MCInst &Inst, unsigned N) const {
1234 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1234, __PRETTY_FUNCTION__))
;
1235
1236 for (auto RegNo : getRegList())
1237 Inst.addOperand(MCOperand::createReg(RegNo));
1238 }
1239
1240 bool isReg() const override {
1241 // As a special case until we sort out the definition of div/divu, accept
1242 // $0/$zero here so that MCK_ZERO works correctly.
1243 return isGPRAsmReg() && RegIdx.Index == 0;
1244 }
1245
1246 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1247 bool isImm() const override { return Kind == k_Immediate; }
1248
1249 bool isConstantImm() const {
1250 int64_t Res;
1251 return isImm() && getImm()->evaluateAsAbsolute(Res);
1252 }
1253
1254 bool isConstantImmz() const {
1255 return isConstantImm() && getConstantImm() == 0;
1256 }
1257
1258 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1259 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1260 }
1261
1262 template <unsigned Bits> bool isSImm() const {
1263 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1264 }
1265
1266 template <unsigned Bits> bool isUImm() const {
1267 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1268 }
1269
1270 template <unsigned Bits> bool isAnyImm() const {
1271 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1272 isUInt<Bits>(getConstantImm()))
1273 : isImm();
1274 }
1275
1276 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1277 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1278 }
1279
1280 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1281 return isConstantImm() && getConstantImm() >= Bottom &&
1282 getConstantImm() <= Top;
1283 }
1284
1285 bool isToken() const override {
1286 // Note: It's not possible to pretend that other operand kinds are tokens.
1287 // The matcher emitter checks tokens first.
1288 return Kind == k_Token;
1289 }
1290
1291 bool isMem() const override { return Kind == k_Memory; }
1292
1293 bool isConstantMemOff() const {
1294 return isMem() && isa<MCConstantExpr>(getMemOff());
1295 }
1296
1297 // Allow relocation operators.
1298 // FIXME: This predicate and others need to look through binary expressions
1299 // and determine whether a Value is a constant or not.
1300 template <unsigned Bits, unsigned ShiftAmount = 0>
1301 bool isMemWithSimmOffset() const {
1302 if (!isMem())
1303 return false;
1304 if (!getMemBase()->isGPRAsmReg())
1305 return false;
1306 if (isa<MCTargetExpr>(getMemOff()) ||
1307 (isConstantMemOff() &&
1308 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1309 return true;
1310 MCValue Res;
1311 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1312 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1313 }
1314
1315 bool isMemWithPtrSizeOffset() const {
1316 if (!isMem())
1317 return false;
1318 if (!getMemBase()->isGPRAsmReg())
1319 return false;
1320 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1321 if (isa<MCTargetExpr>(getMemOff()) ||
1322 (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1323 return true;
1324 MCValue Res;
1325 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1326 return IsReloc && isIntN(PtrBits, Res.getConstant());
1327 }
1328
1329 bool isMemWithGRPMM16Base() const {
1330 return isMem() && getMemBase()->isMM16AsmReg();
1331 }
1332
1333 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1334 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1335 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1336 }
1337
1338 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1339 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1340 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1341 && (getMemBase()->getGPR32Reg() == Mips::SP);
1342 }
1343
1344 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1345 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1346 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1347 && (getMemBase()->getGPR32Reg() == Mips::GP);
1348 }
1349
1350 template <unsigned Bits, unsigned ShiftLeftAmount>
1351 bool isScaledUImm() const {
1352 return isConstantImm() &&
1353 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1354 }
1355
1356 template <unsigned Bits, unsigned ShiftLeftAmount>
1357 bool isScaledSImm() const {
1358 if (isConstantImm() &&
1359 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1360 return true;
1361 // Operand can also be a symbol or symbol plus
1362 // offset in case of relocations.
1363 if (Kind != k_Immediate)
1364 return false;
1365 MCValue Res;
1366 bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1367 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1368 }
1369
1370 bool isRegList16() const {
1371 if (!isRegList())
1372 return false;
1373
1374 int Size = RegList.List->size();
1375 if (Size < 2 || Size > 5)
1376 return false;
1377
1378 unsigned R0 = RegList.List->front();
1379 unsigned R1 = RegList.List->back();
1380 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1381 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1382 return false;
1383
1384 int PrevReg = *RegList.List->begin();
1385 for (int i = 1; i < Size - 1; i++) {
1386 int Reg = (*(RegList.List))[i];
1387 if ( Reg != PrevReg + 1)
1388 return false;
1389 PrevReg = Reg;
1390 }
1391
1392 return true;
1393 }
1394
1395 bool isInvNum() const { return Kind == k_Immediate; }
1396
1397 bool isLSAImm() const {
1398 if (!isConstantImm())
1399 return false;
1400 int64_t Val = getConstantImm();
1401 return 1 <= Val && Val <= 4;
1402 }
1403
1404 bool isRegList() const { return Kind == k_RegList; }
1405
1406 StringRef getToken() const {
1407 assert(Kind == k_Token && "Invalid access!")((Kind == k_Token && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Token && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1407, __PRETTY_FUNCTION__))
;
1408 return StringRef(Tok.Data, Tok.Length);
1409 }
1410
1411 unsigned getReg() const override {
1412 // As a special case until we sort out the definition of div/divu, accept
1413 // $0/$zero here so that MCK_ZERO works correctly.
1414 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1415 RegIdx.Kind & RegKind_GPR)
1416 return getGPR32Reg(); // FIXME: GPR64 too
1417
1418 llvm_unreachable("Invalid access!")::llvm::llvm_unreachable_internal("Invalid access!", "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1418)
;
1419 return 0;
1420 }
1421
1422 const MCExpr *getImm() const {
1423 assert((Kind == k_Immediate) && "Invalid access!")(((Kind == k_Immediate) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Immediate) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1423, __PRETTY_FUNCTION__))
;
1424 return Imm.Val;
1425 }
1426
1427 int64_t getConstantImm() const {
1428 const MCExpr *Val = getImm();
1429 int64_t Value = 0;
1430 (void)Val->evaluateAsAbsolute(Value);
1431 return Value;
1432 }
1433
1434 MipsOperand *getMemBase() const {
1435 assert((Kind == k_Memory) && "Invalid access!")(((Kind == k_Memory) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Memory) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1435, __PRETTY_FUNCTION__))
;
1436 return Mem.Base;
1437 }
1438
1439 const MCExpr *getMemOff() const {
1440 assert((Kind == k_Memory) && "Invalid access!")(((Kind == k_Memory) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_Memory) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1440, __PRETTY_FUNCTION__))
;
1441 return Mem.Off;
1442 }
1443
1444 int64_t getConstantMemOff() const {
1445 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1446 }
1447
1448 const SmallVectorImpl<unsigned> &getRegList() const {
1449 assert((Kind == k_RegList) && "Invalid access!")(((Kind == k_RegList) && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("(Kind == k_RegList) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1449, __PRETTY_FUNCTION__))
;
1450 return *(RegList.List);
1451 }
1452
1453 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1454 MipsAsmParser &Parser) {
1455 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1456 Op->Tok.Data = Str.data();
1457 Op->Tok.Length = Str.size();
1458 Op->StartLoc = S;
1459 Op->EndLoc = S;
1460 return Op;
1461 }
1462
1463 /// Create a numeric register (e.g. $1). The exact register remains
1464 /// unresolved until an instruction successfully matches
1465 static std::unique_ptr<MipsOperand>
1466 createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1467 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1468 LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("mips-asm-parser")) { dbgs() << "createNumericReg(" <<
Index << ", ...)\n"; } } while (false)
;
1469 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1470 }
1471
1472 /// Create a register that is definitely a GPR.
1473 /// This is typically only used for named registers such as $gp.
1474 static std::unique_ptr<MipsOperand>
1475 createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1476 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1477 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1478 }
1479
1480 /// Create a register that is definitely a FGR.
1481 /// This is typically only used for named registers such as $f0.
1482 static std::unique_ptr<MipsOperand>
1483 createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1484 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1485 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1486 }
1487
1488 /// Create a register that is definitely a HWReg.
1489 /// This is typically only used for named registers such as $hwr_cpunum.
1490 static std::unique_ptr<MipsOperand>
1491 createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1492 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1493 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1494 }
1495
1496 /// Create a register that is definitely an FCC.
1497 /// This is typically only used for named registers such as $fcc0.
1498 static std::unique_ptr<MipsOperand>
1499 createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1500 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1501 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1502 }
1503
1504 /// Create a register that is definitely an ACC.
1505 /// This is typically only used for named registers such as $ac0.
1506 static std::unique_ptr<MipsOperand>
1507 createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1508 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1509 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1510 }
1511
1512 /// Create a register that is definitely an MSA128.
1513 /// This is typically only used for named registers such as $w0.
1514 static std::unique_ptr<MipsOperand>
1515 createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1516 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1517 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1518 }
1519
1520 /// Create a register that is definitely an MSACtrl.
1521 /// This is typically only used for named registers such as $msaaccess.
1522 static std::unique_ptr<MipsOperand>
1523 createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1524 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1525 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1526 }
1527
1528 static std::unique_ptr<MipsOperand>
1529 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1530 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1531 Op->Imm.Val = Val;
1532 Op->StartLoc = S;
1533 Op->EndLoc = E;
1534 return Op;
1535 }
1536
1537 static std::unique_ptr<MipsOperand>
1538 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1539 SMLoc E, MipsAsmParser &Parser) {
1540 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1541 Op->Mem.Base = Base.release();
1542 Op->Mem.Off = Off;
1543 Op->StartLoc = S;
1544 Op->EndLoc = E;
1545 return Op;
1546 }
1547
1548 static std::unique_ptr<MipsOperand>
1549 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1550 MipsAsmParser &Parser) {
1551 assert(Regs.size() > 0 && "Empty list not allowed")((Regs.size() > 0 && "Empty list not allowed") ? static_cast
<void> (0) : __assert_fail ("Regs.size() > 0 && \"Empty list not allowed\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1551, __PRETTY_FUNCTION__))
;
1552
1553 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1554 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1555 Op->StartLoc = StartLoc;
1556 Op->EndLoc = EndLoc;
1557 return Op;
1558 }
1559
1560 bool isGPRZeroAsmReg() const {
1561 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1562 }
1563
1564 bool isGPRNonZeroAsmReg() const {
1565 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1566 RegIdx.Index <= 31;
1567 }
1568
1569 bool isGPRAsmReg() const {
1570 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1571 }
1572
1573 bool isMM16AsmReg() const {
1574 if (!(isRegIdx() && RegIdx.Kind))
1575 return false;
1576 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1577 || RegIdx.Index == 16 || RegIdx.Index == 17);
1578
1579 }
1580 bool isMM16AsmRegZero() const {
1581 if (!(isRegIdx() && RegIdx.Kind))
1582 return false;
1583 return (RegIdx.Index == 0 ||
1584 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1585 RegIdx.Index == 17);
1586 }
1587
1588 bool isMM16AsmRegMoveP() const {
1589 if (!(isRegIdx() && RegIdx.Kind))
1590 return false;
1591 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1592 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1593 }
1594
1595 bool isMM16AsmRegMovePPairFirst() const {
1596 if (!(isRegIdx() && RegIdx.Kind))
1597 return false;
1598 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1599 }
1600
1601 bool isMM16AsmRegMovePPairSecond() const {
1602 if (!(isRegIdx() && RegIdx.Kind))
1603 return false;
1604 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1605 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1606 }
1607
1608 bool isFGRAsmReg() const {
1609 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1610 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1611 }
1612
1613 bool isStrictlyFGRAsmReg() const {
1614 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1615 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1616 }
1617
1618 bool isHWRegsAsmReg() const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1620 }
1621
1622 bool isCCRAsmReg() const {
1623 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1624 }
1625
1626 bool isFCCAsmReg() const {
1627 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1628 return false;
1629 return RegIdx.Index <= 7;
1630 }
1631
1632 bool isACCAsmReg() const {
1633 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1634 }
1635
1636 bool isCOP0AsmReg() const {
1637 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1638 }
1639
1640 bool isCOP2AsmReg() const {
1641 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1642 }
1643
1644 bool isCOP3AsmReg() const {
1645 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1646 }
1647
1648 bool isMSA128AsmReg() const {
1649 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1650 }
1651
1652 bool isMSACtrlAsmReg() const {
1653 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1654 }
1655
1656 /// getStartLoc - Get the location of the first token of this operand.
1657 SMLoc getStartLoc() const override { return StartLoc; }
1658 /// getEndLoc - Get the location of the last token of this operand.
1659 SMLoc getEndLoc() const override { return EndLoc; }
1660
1661 void print(raw_ostream &OS) const override {
1662 switch (Kind) {
1663 case k_Immediate:
1664 OS << "Imm<";
1665 OS << *Imm.Val;
1666 OS << ">";
1667 break;
1668 case k_Memory:
1669 OS << "Mem<";
1670 Mem.Base->print(OS);
1671 OS << ", ";
1672 OS << *Mem.Off;
1673 OS << ">";
1674 break;
1675 case k_RegisterIndex:
1676 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1677 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1678 break;
1679 case k_Token:
1680 OS << getToken();
1681 break;
1682 case k_RegList:
1683 OS << "RegList< ";
1684 for (auto Reg : (*RegList.List))
1685 OS << Reg << " ";
1686 OS << ">";
1687 break;
1688 }
1689 }
1690
1691 bool isValidForTie(const MipsOperand &Other) const {
1692 if (Kind != Other.Kind)
1693 return false;
1694
1695 switch (Kind) {
1696 default:
1697 llvm_unreachable("Unexpected kind")::llvm::llvm_unreachable_internal("Unexpected kind", "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1697)
;
1698 return false;
1699 case k_RegisterIndex: {
1700 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1701 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1702 return Token == OtherToken;
1703 }
1704 }
1705 }
1706}; // class MipsOperand
1707
1708} // end anonymous namespace
1709
1710namespace llvm {
1711
1712extern const MCInstrDesc MipsInsts[];
1713
1714} // end namespace llvm
1715
1716static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1717 return MipsInsts[Opcode];
1718}
1719
1720static bool hasShortDelaySlot(MCInst &Inst) {
1721 switch (Inst.getOpcode()) {
1722 case Mips::BEQ_MM:
1723 case Mips::BNE_MM:
1724 case Mips::BLTZ_MM:
1725 case Mips::BGEZ_MM:
1726 case Mips::BLEZ_MM:
1727 case Mips::BGTZ_MM:
1728 case Mips::JRC16_MM:
1729 case Mips::JALS_MM:
1730 case Mips::JALRS_MM:
1731 case Mips::JALRS16_MM:
1732 case Mips::BGEZALS_MM:
1733 case Mips::BLTZALS_MM:
1734 return true;
1735 case Mips::J_MM:
1736 return !Inst.getOperand(0).isReg();
1737 default:
1738 return false;
1739 }
1740}
1741
1742static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1743 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1744 return &SRExpr->getSymbol();
1745 }
1746
1747 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1748 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1749 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1750
1751 if (LHSSym)
1752 return LHSSym;
1753
1754 if (RHSSym)
1755 return RHSSym;
1756
1757 return nullptr;
1758 }
1759
1760 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1761 return getSingleMCSymbol(UExpr->getSubExpr());
1762
1763 return nullptr;
1764}
1765
1766static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1767 if (isa<MCSymbolRefExpr>(Expr))
1768 return 1;
1769
1770 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1771 return countMCSymbolRefExpr(BExpr->getLHS()) +
1772 countMCSymbolRefExpr(BExpr->getRHS());
1773
1774 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1775 return countMCSymbolRefExpr(UExpr->getSubExpr());
1776
1777 return 0;
1778}
1779
1780bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1781 MCStreamer &Out,
1782 const MCSubtargetInfo *STI) {
1783 MipsTargetStreamer &TOut = getTargetStreamer();
1784 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1785 bool ExpandedJalSym = false;
1786
1787 Inst.setLoc(IDLoc);
1788
1789 if (MCID.isBranch() || MCID.isCall()) {
1790 const unsigned Opcode = Inst.getOpcode();
1791 MCOperand Offset;
1792
1793 switch (Opcode) {
1794 default:
1795 break;
1796 case Mips::BBIT0:
1797 case Mips::BBIT032:
1798 case Mips::BBIT1:
1799 case Mips::BBIT132:
1800 assert(hasCnMips() && "instruction only valid for octeon cpus")((hasCnMips() && "instruction only valid for octeon cpus"
) ? static_cast<void> (0) : __assert_fail ("hasCnMips() && \"instruction only valid for octeon cpus\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1800, __PRETTY_FUNCTION__))
;
1801 LLVM_FALLTHROUGH[[gnu::fallthrough]];
1802
1803 case Mips::BEQ:
1804 case Mips::BNE:
1805 case Mips::BEQ_MM:
1806 case Mips::BNE_MM:
1807 assert(MCID.getNumOperands() == 3 && "unexpected number of operands")((MCID.getNumOperands() == 3 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 3 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1807, __PRETTY_FUNCTION__))
;
1808 Offset = Inst.getOperand(2);
1809 if (!Offset.isImm())
1810 break; // We'll deal with this situation later on when applying fixups.
1811 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1812 return Error(IDLoc, "branch target out of range");
1813 if (offsetToAlignment(Offset.getImm(),
1814 (inMicroMipsMode() ? Align(2) : Align(4))))
1815 return Error(IDLoc, "branch to misaligned address");
1816 break;
1817 case Mips::BGEZ:
1818 case Mips::BGTZ:
1819 case Mips::BLEZ:
1820 case Mips::BLTZ:
1821 case Mips::BGEZAL:
1822 case Mips::BLTZAL:
1823 case Mips::BC1F:
1824 case Mips::BC1T:
1825 case Mips::BGEZ_MM:
1826 case Mips::BGTZ_MM:
1827 case Mips::BLEZ_MM:
1828 case Mips::BLTZ_MM:
1829 case Mips::BGEZAL_MM:
1830 case Mips::BLTZAL_MM:
1831 case Mips::BC1F_MM:
1832 case Mips::BC1T_MM:
1833 case Mips::BC1EQZC_MMR6:
1834 case Mips::BC1NEZC_MMR6:
1835 case Mips::BC2EQZC_MMR6:
1836 case Mips::BC2NEZC_MMR6:
1837 assert(MCID.getNumOperands() == 2 && "unexpected number of operands")((MCID.getNumOperands() == 2 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 2 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1837, __PRETTY_FUNCTION__))
;
1838 Offset = Inst.getOperand(1);
1839 if (!Offset.isImm())
1840 break; // We'll deal with this situation later on when applying fixups.
1841 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1842 return Error(IDLoc, "branch target out of range");
1843 if (offsetToAlignment(Offset.getImm(),
1844 (inMicroMipsMode() ? Align(2) : Align(4))))
1845 return Error(IDLoc, "branch to misaligned address");
1846 break;
1847 case Mips::BGEC: case Mips::BGEC_MMR6:
1848 case Mips::BLTC: case Mips::BLTC_MMR6:
1849 case Mips::BGEUC: case Mips::BGEUC_MMR6:
1850 case Mips::BLTUC: case Mips::BLTUC_MMR6:
1851 case Mips::BEQC: case Mips::BEQC_MMR6:
1852 case Mips::BNEC: case Mips::BNEC_MMR6:
1853 assert(MCID.getNumOperands() == 3 && "unexpected number of operands")((MCID.getNumOperands() == 3 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 3 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1853, __PRETTY_FUNCTION__))
;
1854 Offset = Inst.getOperand(2);
1855 if (!Offset.isImm())
1856 break; // We'll deal with this situation later on when applying fixups.
1857 if (!isIntN(18, Offset.getImm()))
1858 return Error(IDLoc, "branch target out of range");
1859 if (offsetToAlignment(Offset.getImm(), Align(4)))
1860 return Error(IDLoc, "branch to misaligned address");
1861 break;
1862 case Mips::BLEZC: case Mips::BLEZC_MMR6:
1863 case Mips::BGEZC: case Mips::BGEZC_MMR6:
1864 case Mips::BGTZC: case Mips::BGTZC_MMR6:
1865 case Mips::BLTZC: case Mips::BLTZC_MMR6:
1866 assert(MCID.getNumOperands() == 2 && "unexpected number of operands")((MCID.getNumOperands() == 2 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 2 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1866, __PRETTY_FUNCTION__))
;
1867 Offset = Inst.getOperand(1);
1868 if (!Offset.isImm())
1869 break; // We'll deal with this situation later on when applying fixups.
1870 if (!isIntN(18, Offset.getImm()))
1871 return Error(IDLoc, "branch target out of range");
1872 if (offsetToAlignment(Offset.getImm(), Align(4)))
1873 return Error(IDLoc, "branch to misaligned address");
1874 break;
1875 case Mips::BEQZC: case Mips::BEQZC_MMR6:
1876 case Mips::BNEZC: case Mips::BNEZC_MMR6:
1877 assert(MCID.getNumOperands() == 2 && "unexpected number of operands")((MCID.getNumOperands() == 2 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 2 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1877, __PRETTY_FUNCTION__))
;
1878 Offset = Inst.getOperand(1);
1879 if (!Offset.isImm())
1880 break; // We'll deal with this situation later on when applying fixups.
1881 if (!isIntN(23, Offset.getImm()))
1882 return Error(IDLoc, "branch target out of range");
1883 if (offsetToAlignment(Offset.getImm(), Align(4)))
1884 return Error(IDLoc, "branch to misaligned address");
1885 break;
1886 case Mips::BEQZ16_MM:
1887 case Mips::BEQZC16_MMR6:
1888 case Mips::BNEZ16_MM:
1889 case Mips::BNEZC16_MMR6:
1890 assert(MCID.getNumOperands() == 2 && "unexpected number of operands")((MCID.getNumOperands() == 2 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 2 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1890, __PRETTY_FUNCTION__))
;
1891 Offset = Inst.getOperand(1);
1892 if (!Offset.isImm())
1893 break; // We'll deal with this situation later on when applying fixups.
1894 if (!isInt<8>(Offset.getImm()))
1895 return Error(IDLoc, "branch target out of range");
1896 if (offsetToAlignment(Offset.getImm(), Align(2)))
1897 return Error(IDLoc, "branch to misaligned address");
1898 break;
1899 }
1900 }
1901
1902 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1903 // We still accept it but it is a normal nop.
1904 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1905 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1906 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1907 "nop instruction");
1908 }
1909
1910 if (hasCnMips()) {
1911 const unsigned Opcode = Inst.getOpcode();
1912 MCOperand Opnd;
1913 int Imm;
1914
1915 switch (Opcode) {
1916 default:
1917 break;
1918
1919 case Mips::BBIT0:
1920 case Mips::BBIT032:
1921 case Mips::BBIT1:
1922 case Mips::BBIT132:
1923 assert(MCID.getNumOperands() == 3 && "unexpected number of operands")((MCID.getNumOperands() == 3 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 3 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1923, __PRETTY_FUNCTION__))
;
1924 // The offset is handled above
1925 Opnd = Inst.getOperand(1);
1926 if (!Opnd.isImm())
1927 return Error(IDLoc, "expected immediate operand kind");
1928 Imm = Opnd.getImm();
1929 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1930 Opcode == Mips::BBIT1 ? 63 : 31))
1931 return Error(IDLoc, "immediate operand value out of range");
1932 if (Imm > 31) {
1933 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1934 : Mips::BBIT132);
1935 Inst.getOperand(1).setImm(Imm - 32);
1936 }
1937 break;
1938
1939 case Mips::SEQi:
1940 case Mips::SNEi:
1941 assert(MCID.getNumOperands() == 3 && "unexpected number of operands")((MCID.getNumOperands() == 3 && "unexpected number of operands"
) ? static_cast<void> (0) : __assert_fail ("MCID.getNumOperands() == 3 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 1941, __PRETTY_FUNCTION__))
;
1942 Opnd = Inst.getOperand(2);
1943 if (!Opnd.isImm())
1944 return Error(IDLoc, "expected immediate operand kind");
1945 Imm = Opnd.getImm();
1946 if (!isInt<10>(Imm))
1947 return Error(IDLoc, "immediate operand value out of range");
1948 break;
1949 }
1950 }
1951
1952 // Warn on division by zero. We're checking here as all instructions get
1953 // processed here, not just the macros that need expansion.
1954 //
1955 // The MIPS backend models most of the divison instructions and macros as
1956 // three operand instructions. The pre-R6 divide instructions however have
1957 // two operands and explicitly define HI/LO as part of the instruction,
1958 // not in the operands.
1959 unsigned FirstOp = 1;
1960 unsigned SecondOp = 2;
1961 switch (Inst.getOpcode()) {
1962 default:
1963 break;
1964 case Mips::SDivIMacro:
1965 case Mips::UDivIMacro:
1966 case Mips::DSDivIMacro:
1967 case Mips::DUDivIMacro:
1968 if (Inst.getOperand(2).getImm() == 0) {
1969 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
1970 Inst.getOperand(1).getReg() == Mips::ZERO_64)
1971 Warning(IDLoc, "dividing zero by zero");
1972 else
1973 Warning(IDLoc, "division by zero");
1974 }
1975 break;
1976 case Mips::DSDIV:
1977 case Mips::SDIV:
1978 case Mips::UDIV:
1979 case Mips::DUDIV:
1980 case Mips::UDIV_MM:
1981 case Mips::SDIV_MM:
1982 FirstOp = 0;
1983 SecondOp = 1;
1984 LLVM_FALLTHROUGH[[gnu::fallthrough]];
1985 case Mips::SDivMacro:
1986 case Mips::DSDivMacro:
1987 case Mips::UDivMacro:
1988 case Mips::DUDivMacro:
1989 case Mips::DIV:
1990 case Mips::DIVU:
1991 case Mips::DDIV:
1992 case Mips::DDIVU:
1993 case Mips::DIVU_MMR6:
1994 case Mips::DIV_MMR6:
1995 if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
1996 Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
1997 if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
1998 Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
1999 Warning(IDLoc, "dividing zero by zero");
2000 else
2001 Warning(IDLoc, "division by zero");
2002 }
2003 break;
2004 }
2005
2006 // For PIC code convert unconditional jump to unconditional branch.
2007 if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
2008 inPicMode()) {
2009 MCInst BInst;
2010 BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2011 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2012 BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2013 BInst.addOperand(Inst.getOperand(0));
2014 Inst = BInst;
2015 }
2016
2017 // This expansion is not in a function called by tryExpandInstruction()
2018 // because the pseudo-instruction doesn't have a distinct opcode.
2019 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
2020 inPicMode()) {
2021 warnIfNoMacro(IDLoc);
2022
2023 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2024
2025 // We can do this expansion if there's only 1 symbol in the argument
2026 // expression.
2027 if (countMCSymbolRefExpr(JalExpr) > 1)
2028 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2029
2030 // FIXME: This is checking the expression can be handled by the later stages
2031 // of the assembler. We ought to leave it to those later stages.
2032 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2033
2034 // FIXME: Add support for label+offset operands (currently causes an error).
2035 // FIXME: Add support for forward-declared local symbols.
2036 // FIXME: Add expansion for when the LargeGOT option is enabled.
2037 if (JalSym->isInSection() || JalSym->isTemporary() ||
2038 (JalSym->isELF() &&
2039 cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
2040 if (isABI_O32()) {
2041 // If it's a local symbol and the O32 ABI is being used, we expand to:
2042 // lw $25, 0($gp)
2043 // R_(MICRO)MIPS_GOT16 label
2044 // addiu $25, $25, 0
2045 // R_(MICRO)MIPS_LO16 label
2046 // jalr $25
2047 const MCExpr *Got16RelocExpr =
2048 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
2049 const MCExpr *Lo16RelocExpr =
2050 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
2051
2052 TOut.emitRRX(Mips::LW, Mips::T9, GPReg,
2053 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
2054 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2055 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
2056 } else if (isABI_N32() || isABI_N64()) {
2057 // If it's a local symbol and the N32/N64 ABIs are being used,
2058 // we expand to:
2059 // lw/ld $25, 0($gp)
2060 // R_(MICRO)MIPS_GOT_DISP label
2061 // jalr $25
2062 const MCExpr *GotDispRelocExpr =
2063 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
2064
2065 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
2066 GPReg, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
2067 STI);
2068 }
2069 } else {
2070 // If it's an external/weak symbol, we expand to:
2071 // lw/ld $25, 0($gp)
2072 // R_(MICRO)MIPS_CALL16 label
2073 // jalr $25
2074 const MCExpr *Call16RelocExpr =
2075 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
2076
2077 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, GPReg,
2078 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
2079 }
2080
2081 MCInst JalrInst;
2082 if (IsCpRestoreSet && inMicroMipsMode())
2083 JalrInst.setOpcode(Mips::JALRS_MM);
2084 else
2085 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2086 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2087 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2088
2089 if (EmitJalrReloc) {
2090 // As an optimization hint for the linker, before the JALR we add:
2091 // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2092 // tmplabel:
2093 MCSymbol *TmpLabel = getContext().createTempSymbol();
2094 const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2095 const MCExpr *RelocJalrExpr =
2096 MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
2097 getContext(), IDLoc);
2098
2099 TOut.getStreamer().EmitRelocDirective(*TmpExpr,
2100 inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2101 RelocJalrExpr, IDLoc, *STI);
2102 TOut.getStreamer().EmitLabel(TmpLabel);
2103 }
2104
2105 Inst = JalrInst;
2106 ExpandedJalSym = true;
2107 }
2108
2109 bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
2110 if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
2111 // Check the offset of memory operand, if it is a symbol
2112 // reference or immediate we may have to expand instructions.
2113 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2114 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2115 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2116 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2117 MCOperand &Op = Inst.getOperand(i);
2118 if (Op.isImm()) {
2119 int64_t MemOffset = Op.getImm();
2120 if (MemOffset < -32768 || MemOffset > 32767) {
2121 // Offset can't exceed 16bit value.
2122 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2123 return getParser().hasPendingError();
2124 }
2125 } else if (Op.isExpr()) {
2126 const MCExpr *Expr = Op.getExpr();
2127 if (Expr->getKind() == MCExpr::SymbolRef) {
2128 const MCSymbolRefExpr *SR =
2129 static_cast<const MCSymbolRefExpr *>(Expr);
2130 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
2131 // Expand symbol.
2132 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2133 return getParser().hasPendingError();
2134 }
2135 } else if (!isEvaluated(Expr)) {
2136 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2137 return getParser().hasPendingError();
2138 }
2139 }
2140 }
2141 } // for
2142 } // if load/store
2143
2144 if (inMicroMipsMode()) {
2145 if (MCID.mayLoad() && Inst.getOpcode() != Mips::LWP_MM) {
2146 // Try to create 16-bit GP relative load instruction.
2147 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2148 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2149 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2150 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2151 MCOperand &Op = Inst.getOperand(i);
2152 if (Op.isImm()) {
2153 int MemOffset = Op.getImm();
2154 MCOperand &DstReg = Inst.getOperand(0);
2155 MCOperand &BaseReg = Inst.getOperand(1);
2156 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2157 getContext().getRegisterInfo()->getRegClass(
2158 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2159 (BaseReg.getReg() == Mips::GP ||
2160 BaseReg.getReg() == Mips::GP_64)) {
2161
2162 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2163 IDLoc, STI);
2164 return false;
2165 }
2166 }
2167 }
2168 } // for
2169 } // if load
2170
2171 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2172
2173 MCOperand Opnd;
2174 int Imm;
2175
2176 switch (Inst.getOpcode()) {
2177 default:
2178 break;
2179 case Mips::ADDIUSP_MM:
2180 Opnd = Inst.getOperand(0);
2181 if (!Opnd.isImm())
2182 return Error(IDLoc, "expected immediate operand kind");
2183 Imm = Opnd.getImm();
2184 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2185 Imm % 4 != 0)
2186 return Error(IDLoc, "immediate operand value out of range");
2187 break;
2188 case Mips::SLL16_MM:
2189 case Mips::SRL16_MM:
2190 Opnd = Inst.getOperand(2);
2191 if (!Opnd.isImm())
2192 return Error(IDLoc, "expected immediate operand kind");
2193 Imm = Opnd.getImm();
2194 if (Imm < 1 || Imm > 8)
2195 return Error(IDLoc, "immediate operand value out of range");
2196 break;
2197 case Mips::LI16_MM:
2198 Opnd = Inst.getOperand(1);
2199 if (!Opnd.isImm())
2200 return Error(IDLoc, "expected immediate operand kind");
2201 Imm = Opnd.getImm();
2202 if (Imm < -1 || Imm > 126)
2203 return Error(IDLoc, "immediate operand value out of range");
2204 break;
2205 case Mips::ADDIUR2_MM:
2206 Opnd = Inst.getOperand(2);
2207 if (!Opnd.isImm())
2208 return Error(IDLoc, "expected immediate operand kind");
2209 Imm = Opnd.getImm();
2210 if (!(Imm == 1 || Imm == -1 ||
2211 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2212 return Error(IDLoc, "immediate operand value out of range");
2213 break;
2214 case Mips::ANDI16_MM:
2215 Opnd = Inst.getOperand(2);
2216 if (!Opnd.isImm())
2217 return Error(IDLoc, "expected immediate operand kind");
2218 Imm = Opnd.getImm();
2219 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2220 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2221 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2222 return Error(IDLoc, "immediate operand value out of range");
2223 break;
2224 case Mips::LBU16_MM:
2225 Opnd = Inst.getOperand(2);
2226 if (!Opnd.isImm())
2227 return Error(IDLoc, "expected immediate operand kind");
2228 Imm = Opnd.getImm();
2229 if (Imm < -1 || Imm > 14)
2230 return Error(IDLoc, "immediate operand value out of range");
2231 break;
2232 case Mips::SB16_MM:
2233 case Mips::SB16_MMR6:
2234 Opnd = Inst.getOperand(2);
2235 if (!Opnd.isImm())
2236 return Error(IDLoc, "expected immediate operand kind");
2237 Imm = Opnd.getImm();
2238 if (Imm < 0 || Imm > 15)
2239 return Error(IDLoc, "immediate operand value out of range");
2240 break;
2241 case Mips::LHU16_MM:
2242 case Mips::SH16_MM:
2243 case Mips::SH16_MMR6:
2244 Opnd = Inst.getOperand(2);
2245 if (!Opnd.isImm())
2246 return Error(IDLoc, "expected immediate operand kind");
2247 Imm = Opnd.getImm();
2248 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2249 return Error(IDLoc, "immediate operand value out of range");
2250 break;
2251 case Mips::LW16_MM:
2252 case Mips::SW16_MM:
2253 case Mips::SW16_MMR6:
2254 Opnd = Inst.getOperand(2);
2255 if (!Opnd.isImm())
2256 return Error(IDLoc, "expected immediate operand kind");
2257 Imm = Opnd.getImm();
2258 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2259 return Error(IDLoc, "immediate operand value out of range");
2260 break;
2261 case Mips::ADDIUPC_MM:
2262 Opnd = Inst.getOperand(1);
2263 if (!Opnd.isImm())
2264 return Error(IDLoc, "expected immediate operand kind");
2265 Imm = Opnd.getImm();
2266 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2267 return Error(IDLoc, "immediate operand value out of range");
2268 break;
2269 case Mips::LWP_MM:
2270 case Mips::SWP_MM:
2271 if (Inst.getOperand(0).getReg() == Mips::RA)
2272 return Error(IDLoc, "invalid operand for instruction");
2273 break;
2274 case Mips::MOVEP_MM:
2275 case Mips::MOVEP_MMR6: {
2276 unsigned R0 = Inst.getOperand(0).getReg();
2277 unsigned R1 = Inst.getOperand(1).getReg();
2278 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2279 (R0 == Mips::A1 && R1 == Mips::A3) ||
2280 (R0 == Mips::A2 && R1 == Mips::A3) ||
2281 (R0 == Mips::A0 && R1 == Mips::S5) ||
2282 (R0 == Mips::A0 && R1 == Mips::S6) ||
2283 (R0 == Mips::A0 && R1 == Mips::A1) ||
2284 (R0 == Mips::A0 && R1 == Mips::A2) ||
2285 (R0 == Mips::A0 && R1 == Mips::A3));
2286 if (!RegPair)
2287 return Error(IDLoc, "invalid operand for instruction");
2288 break;
2289 }
2290 }
2291 }
2292
2293 bool FillDelaySlot =
2294 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2295 if (FillDelaySlot)
2296 TOut.emitDirectiveSetNoReorder();
2297
2298 MacroExpanderResultTy ExpandResult =
2299 tryExpandInstruction(Inst, IDLoc, Out, STI);
2300 switch (ExpandResult) {
2301 case MER_NotAMacro:
2302 Out.EmitInstruction(Inst, *STI);
2303 break;
2304 case MER_Success:
2305 break;
2306 case MER_Fail:
2307 return true;
2308 }
2309
2310 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2311 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2312 if (inMicroMipsMode()) {
2313 TOut.setUsesMicroMips();
2314 TOut.updateABIInfo(*this);
2315 }
2316
2317 // If this instruction has a delay slot and .set reorder is active,
2318 // emit a NOP after it.
2319 if (FillDelaySlot) {
2320 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2321 TOut.emitDirectiveSetReorder();
2322 }
2323
2324 if ((Inst.getOpcode() == Mips::JalOneReg ||
2325 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2326 isPicAndNotNxxAbi()) {
2327 if (IsCpRestoreSet) {
2328 // We need a NOP between the JALR and the LW:
2329 // If .set reorder has been used, we've already emitted a NOP.
2330 // If .set noreorder has been used, we need to emit a NOP at this point.
2331 if (!AssemblerOptions.back()->isReorder())
2332 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2333 STI);
2334
2335 // Load the $gp from the stack.
2336 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2337 } else
2338 Warning(IDLoc, "no .cprestore used in PIC mode");
2339 }
2340
2341 return false;
2342}
2343
2344MipsAsmParser::MacroExpanderResultTy
2345MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2346 const MCSubtargetInfo *STI) {
2347 switch (Inst.getOpcode()) {
2348 default:
2349 return MER_NotAMacro;
2350 case Mips::LoadImm32:
2351 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2352 case Mips::LoadImm64:
2353 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2354 case Mips::LoadAddrImm32:
2355 case Mips::LoadAddrImm64:
2356 assert(Inst.getOperand(0).isReg() && "expected register operand kind")((Inst.getOperand(0).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2356, __PRETTY_FUNCTION__))
;
2357 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&(((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2358, __PRETTY_FUNCTION__))
2358 "expected immediate operand kind")(((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2358, __PRETTY_FUNCTION__))
;
2359
2360 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2361 Inst.getOperand(1),
2362 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2363 Out, STI)
2364 ? MER_Fail
2365 : MER_Success;
2366 case Mips::LoadAddrReg32:
2367 case Mips::LoadAddrReg64:
2368 assert(Inst.getOperand(0).isReg() && "expected register operand kind")((Inst.getOperand(0).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2368, __PRETTY_FUNCTION__))
;
2369 assert(Inst.getOperand(1).isReg() && "expected register operand kind")((Inst.getOperand(1).isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(1).isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2369, __PRETTY_FUNCTION__))
;
2370 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&(((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2371, __PRETTY_FUNCTION__))
2371 "expected immediate operand kind")(((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr())
&& "expected immediate operand kind") ? static_cast<
void> (0) : __assert_fail ("(Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2371, __PRETTY_FUNCTION__))
;
2372
2373 return expandLoadAddress(Inst.getOperand(0).getReg(),
2374 Inst.getOperand(1).getReg(), Inst.getOperand(2),
2375 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2376 Out, STI)
2377 ? MER_Fail
2378 : MER_Success;
2379 case Mips::B_MM_Pseudo:
2380 case Mips::B_MMR6_Pseudo:
2381 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2382 : MER_Success;
2383 case Mips::SWM_MM:
2384 case Mips::LWM_MM:
2385 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2386 : MER_Success;
2387 case Mips::JalOneReg:
2388 case Mips::JalTwoReg:
2389 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2390 case Mips::BneImm:
2391 case Mips::BeqImm:
2392 case Mips::BEQLImmMacro:
2393 case Mips::BNELImmMacro:
2394 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2395 case Mips::BLT:
2396 case Mips::BLE:
2397 case Mips::BGE:
2398 case Mips::BGT:
2399 case Mips::BLTU:
2400 case Mips::BLEU:
2401 case Mips::BGEU:
2402 case Mips::BGTU:
2403 case Mips::BLTL:
2404 case Mips::BLEL:
2405 case Mips::BGEL:
2406 case Mips::BGTL:
2407 case Mips::BLTUL:
2408 case Mips::BLEUL:
2409 case Mips::BGEUL:
2410 case Mips::BGTUL:
2411 case Mips::BLTImmMacro:
2412 case Mips::BLEImmMacro:
2413 case Mips::BGEImmMacro:
2414 case Mips::BGTImmMacro:
2415 case Mips::BLTUImmMacro:
2416 case Mips::BLEUImmMacro:
2417 case Mips::BGEUImmMacro:
2418 case Mips::BGTUImmMacro:
2419 case Mips::BLTLImmMacro:
2420 case Mips::BLELImmMacro:
2421 case Mips::BGELImmMacro:
2422 case Mips::BGTLImmMacro:
2423 case Mips::BLTULImmMacro:
2424 case Mips::BLEULImmMacro:
2425 case Mips::BGEULImmMacro:
2426 case Mips::BGTULImmMacro:
2427 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2428 case Mips::SDivMacro:
2429 case Mips::SDivIMacro:
2430 case Mips::SRemMacro:
2431 case Mips::SRemIMacro:
2432 return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2433 : MER_Success;
2434 case Mips::DSDivMacro:
2435 case Mips::DSDivIMacro:
2436 case Mips::DSRemMacro:
2437 case Mips::DSRemIMacro:
2438 return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2439 : MER_Success;
2440 case Mips::UDivMacro:
2441 case Mips::UDivIMacro:
2442 case Mips::URemMacro:
2443 case Mips::URemIMacro:
2444 return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2445 : MER_Success;
2446 case Mips::DUDivMacro:
2447 case Mips::DUDivIMacro:
2448 case Mips::DURemMacro:
2449 case Mips::DURemIMacro:
2450 return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2451 : MER_Success;
2452 case Mips::PseudoTRUNC_W_S:
2453 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2454 : MER_Success;
2455 case Mips::PseudoTRUNC_W_D32:
2456 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2457 : MER_Success;
2458 case Mips::PseudoTRUNC_W_D:
2459 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2460 : MER_Success;
2461
2462 case Mips::LoadImmSingleGPR:
2463 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2464 : MER_Success;
2465 case Mips::LoadImmSingleFGR:
2466 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2467 : MER_Success;
2468 case Mips::LoadImmDoubleGPR:
2469 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2470 : MER_Success;
2471 case Mips::LoadImmDoubleFGR:
2472 return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2473 : MER_Success;
2474 case Mips::LoadImmDoubleFGR_32:
2475 return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2476 : MER_Success;
2477
2478 case Mips::Ulh:
2479 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2480 case Mips::Ulhu:
2481 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2482 case Mips::Ush:
2483 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 case Mips::Ulw:
2485 case Mips::Usw:
2486 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2487 case Mips::NORImm:
2488 case Mips::NORImm64:
2489 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 case Mips::SGE:
2491 case Mips::SGEU:
2492 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2493 case Mips::SGEImm:
2494 case Mips::SGEUImm:
2495 case Mips::SGEImm64:
2496 case Mips::SGEUImm64:
2497 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2498 case Mips::SGTImm:
2499 case Mips::SGTUImm:
2500 case Mips::SGTImm64:
2501 case Mips::SGTUImm64:
2502 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2503 case Mips::SLTImm64:
2504 if (isInt<16>(Inst.getOperand(2).getImm())) {
2505 Inst.setOpcode(Mips::SLTi64);
2506 return MER_NotAMacro;
2507 }
2508 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2509 case Mips::SLTUImm64:
2510 if (isInt<16>(Inst.getOperand(2).getImm())) {
2511 Inst.setOpcode(Mips::SLTiu64);
2512 return MER_NotAMacro;
2513 }
2514 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2515 case Mips::ADDi: case Mips::ADDi_MM:
2516 case Mips::ADDiu: case Mips::ADDiu_MM:
2517 case Mips::SLTi: case Mips::SLTi_MM:
2518 case Mips::SLTiu: case Mips::SLTiu_MM:
2519 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2520 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2521 int64_t ImmValue = Inst.getOperand(2).getImm();
2522 if (isInt<16>(ImmValue))
2523 return MER_NotAMacro;
2524 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2525 : MER_Success;
2526 }
2527 return MER_NotAMacro;
2528 case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2529 case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2530 case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2531 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2532 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2533 int64_t ImmValue = Inst.getOperand(2).getImm();
2534 if (isUInt<16>(ImmValue))
2535 return MER_NotAMacro;
2536 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2537 : MER_Success;
2538 }
2539 return MER_NotAMacro;
2540 case Mips::ROL:
2541 case Mips::ROR:
2542 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 case Mips::ROLImm:
2544 case Mips::RORImm:
2545 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2546 case Mips::DROL:
2547 case Mips::DROR:
2548 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 case Mips::DROLImm:
2550 case Mips::DRORImm:
2551 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 case Mips::ABSMacro:
2553 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2554 case Mips::MULImmMacro:
2555 case Mips::DMULImmMacro:
2556 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 case Mips::MULOMacro:
2558 case Mips::DMULOMacro:
2559 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2560 case Mips::MULOUMacro:
2561 case Mips::DMULOUMacro:
2562 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2563 case Mips::DMULMacro:
2564 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 case Mips::LDMacro:
2566 case Mips::SDMacro:
2567 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2568 Inst.getOpcode() == Mips::LDMacro)
2569 ? MER_Fail
2570 : MER_Success;
2571 case Mips::SDC1_M1:
2572 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2573 ? MER_Fail
2574 : MER_Success;
2575 case Mips::SEQMacro:
2576 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 case Mips::SEQIMacro:
2578 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 case Mips::MFTC0: case Mips::MTTC0:
2580 case Mips::MFTGPR: case Mips::MTTGPR:
2581 case Mips::MFTLO: case Mips::MTTLO:
2582 case Mips::MFTHI: case Mips::MTTHI:
2583 case Mips::MFTACX: case Mips::MTTACX:
2584 case Mips::MFTDSP: case Mips::MTTDSP:
2585 case Mips::MFTC1: case Mips::MTTC1:
2586 case Mips::MFTHC1: case Mips::MTTHC1:
2587 case Mips::CFTC1: case Mips::CTTC1:
2588 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2589 }
2590}
2591
2592bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2593 MCStreamer &Out,
2594 const MCSubtargetInfo *STI) {
2595 MipsTargetStreamer &TOut = getTargetStreamer();
2596
2597 // Create a JALR instruction which is going to replace the pseudo-JAL.
2598 MCInst JalrInst;
2599 JalrInst.setLoc(IDLoc);
2600 const MCOperand FirstRegOp = Inst.getOperand(0);
2601 const unsigned Opcode = Inst.getOpcode();
2602
2603 if (Opcode == Mips::JalOneReg) {
2604 // jal $rs => jalr $rs
2605 if (IsCpRestoreSet && inMicroMipsMode()) {
2606 JalrInst.setOpcode(Mips::JALRS16_MM);
2607 JalrInst.addOperand(FirstRegOp);
2608 } else if (inMicroMipsMode()) {
2609 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2610 JalrInst.addOperand(FirstRegOp);
2611 } else {
2612 JalrInst.setOpcode(Mips::JALR);
2613 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2614 JalrInst.addOperand(FirstRegOp);
2615 }
2616 } else if (Opcode == Mips::JalTwoReg) {
2617 // jal $rd, $rs => jalr $rd, $rs
2618 if (IsCpRestoreSet && inMicroMipsMode())
2619 JalrInst.setOpcode(Mips::JALRS_MM);
2620 else
2621 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2622 JalrInst.addOperand(FirstRegOp);
2623 const MCOperand SecondRegOp = Inst.getOperand(1);
2624 JalrInst.addOperand(SecondRegOp);
2625 }
2626 Out.EmitInstruction(JalrInst, *STI);
2627
2628 // If .set reorder is active and branch instruction has a delay slot,
2629 // emit a NOP after it.
2630 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2631 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2632 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2633 STI);
2634
2635 return false;
2636}
2637
2638/// Can the value be represented by a unsigned N-bit value and a shift left?
2639template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2640 unsigned BitNum = findFirstSet(x);
1
Calling 'findFirstSet<unsigned long>'
8
Returning from 'findFirstSet<unsigned long>'
9
'BitNum' initialized to 4294967295
2641
2642 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
10
The result of the right shift is undefined due to shifting by '4294967295', which is greater or equal to the width of type 'uint64_t'
2643}
2644
2645/// Load (or add) an immediate into a register.
2646///
2647/// @param ImmValue The immediate to load.
2648/// @param DstReg The register that will hold the immediate.
2649/// @param SrcReg A register to add to the immediate or Mips::NoRegister
2650/// for a simple initialization.
2651/// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2652/// @param IsAddress True if the immediate represents an address. False if it
2653/// is an integer.
2654/// @param IDLoc Location of the immediate in the source file.
2655bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2656 unsigned SrcReg, bool Is32BitImm,
2657 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2658 const MCSubtargetInfo *STI) {
2659 MipsTargetStreamer &TOut = getTargetStreamer();
2660
2661 if (!Is32BitImm && !isGP64bit()) {
2662 Error(IDLoc, "instruction requires a 64-bit architecture");
2663 return true;
2664 }
2665
2666 if (Is32BitImm) {
2667 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2668 // Sign extend up to 64-bit so that the predicates match the hardware
2669 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2670 // true.
2671 ImmValue = SignExtend64<32>(ImmValue);
2672 } else {
2673 Error(IDLoc, "instruction requires a 32-bit immediate");
2674 return true;
2675 }
2676 }
2677
2678 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2679 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2680
2681 bool UseSrcReg = false;
2682 if (SrcReg != Mips::NoRegister)
2683 UseSrcReg = true;
2684
2685 unsigned TmpReg = DstReg;
2686 if (UseSrcReg &&
2687 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2688 // At this point we need AT to perform the expansions and we exit if it is
2689 // not available.
2690 unsigned ATReg = getATReg(IDLoc);
2691 if (!ATReg)
2692 return true;
2693 TmpReg = ATReg;
2694 }
2695
2696 if (isInt<16>(ImmValue)) {
2697 if (!UseSrcReg)
2698 SrcReg = ZeroReg;
2699
2700 // This doesn't quite follow the usual ABI expectations for N32 but matches
2701 // traditional assembler behaviour. N32 would normally use addiu for both
2702 // integers and addresses.
2703 if (IsAddress && !Is32BitImm) {
2704 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2705 return false;
2706 }
2707
2708 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2709 return false;
2710 }
2711
2712 if (isUInt<16>(ImmValue)) {
2713 unsigned TmpReg = DstReg;
2714 if (SrcReg == DstReg) {
2715 TmpReg = getATReg(IDLoc);
2716 if (!TmpReg)
2717 return true;
2718 }
2719
2720 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2721 if (UseSrcReg)
2722 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2723 return false;
2724 }
2725
2726 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2727 warnIfNoMacro(IDLoc);
2728
2729 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2730 uint16_t Bits15To0 = ImmValue & 0xffff;
2731 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2732 // Traditional behaviour seems to special case this particular value. It's
2733 // not clear why other masks are handled differently.
2734 if (ImmValue == 0xffffffff) {
2735 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2736 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2737 if (UseSrcReg)
2738 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2739 return false;
2740 }
2741
2742 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2743 // upper 32 bits.
2744 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2745 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2746 if (Bits15To0)
2747 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2748 if (UseSrcReg)
2749 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2750 return false;
2751 }
2752
2753 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2754 if (Bits15To0)
2755 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2756 if (UseSrcReg)
2757 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2758 return false;
2759 }
2760
2761 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2762 if (Is32BitImm) {
2763 Error(IDLoc, "instruction requires a 32-bit immediate");
2764 return true;
2765 }
2766
2767 // Traditionally, these immediates are shifted as little as possible and as
2768 // such we align the most significant bit to bit 15 of our temporary.
2769 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2770 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2771 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2772 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2773 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2774 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2775
2776 if (UseSrcReg)
2777 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2778
2779 return false;
2780 }
2781
2782 warnIfNoMacro(IDLoc);
2783
2784 // The remaining case is packed with a sequence of dsll and ori with zeros
2785 // being omitted and any neighbouring dsll's being coalesced.
2786 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2787
2788 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2789 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2790 IDLoc, Out, STI))
2791 return false;
2792
2793 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2794 // skip it and defer the shift to the next chunk.
2795 unsigned ShiftCarriedForwards = 16;
2796 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2797 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2798
2799 if (ImmChunk != 0) {
2800 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2801 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2802 ShiftCarriedForwards = 0;
2803 }
2804
2805 ShiftCarriedForwards += 16;
2806 }
2807 ShiftCarriedForwards -= 16;
2808
2809 // Finish any remaining shifts left by trailing zeros.
2810 if (ShiftCarriedForwards)
2811 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2812
2813 if (UseSrcReg)
2814 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2815
2816 return false;
2817}
2818
2819bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2820 MCStreamer &Out, const MCSubtargetInfo *STI) {
2821 const MCOperand &ImmOp = Inst.getOperand(1);
2822 assert(ImmOp.isImm() && "expected immediate operand kind")((ImmOp.isImm() && "expected immediate operand kind")
? static_cast<void> (0) : __assert_fail ("ImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2822, __PRETTY_FUNCTION__))
;
2823 const MCOperand &DstRegOp = Inst.getOperand(0);
2824 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 2824, __PRETTY_FUNCTION__))
;
2825
2826 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2827 Is32BitImm, false, IDLoc, Out, STI))
2828 return true;
2829
2830 return false;
2831}
2832
2833bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2834 const MCOperand &Offset,
2835 bool Is32BitAddress, SMLoc IDLoc,
2836 MCStreamer &Out,
2837 const MCSubtargetInfo *STI) {
2838 // la can't produce a usable address when addresses are 64-bit.
2839 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2840 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2841 // We currently can't do this because we depend on the equality
2842 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2843 Error(IDLoc, "la used to load 64-bit address");
2844 // Continue as if we had 'dla' instead.
2845 Is32BitAddress = false;
2846 return true;
2847 }
2848
2849 // dla requires 64-bit addresses.
2850 if (!Is32BitAddress && !hasMips3()) {
2851 Error(IDLoc, "instruction requires a 64-bit architecture");
2852 return true;
2853 }
2854
2855 if (!Offset.isImm())
2856 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2857 Is32BitAddress, IDLoc, Out, STI);
2858
2859 if (!ABI.ArePtrs64bit()) {
2860 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2861 Is32BitAddress = true;
2862 }
2863
2864 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2865 IDLoc, Out, STI);
2866}
2867
2868bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2869 unsigned DstReg, unsigned SrcReg,
2870 bool Is32BitSym, SMLoc IDLoc,
2871 MCStreamer &Out,
2872 const MCSubtargetInfo *STI) {
2873 MipsTargetStreamer &TOut = getTargetStreamer();
2874 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2875 SrcReg != Mips::ZERO_64;
2876 warnIfNoMacro(IDLoc);
2877
2878 if (inPicMode()) {
2879 MCValue Res;
2880 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2881 Error(IDLoc, "expected relocatable expression");
2882 return true;
2883 }
2884 if (Res.getSymB() != nullptr) {
2885 Error(IDLoc, "expected relocatable expression with only one symbol");
2886 return true;
2887 }
2888
2889 bool IsPtr64 = ABI.ArePtrs64bit();
2890 bool IsLocalSym =
2891 Res.getSymA()->getSymbol().isInSection() ||
2892 Res.getSymA()->getSymbol().isTemporary() ||
2893 (Res.getSymA()->getSymbol().isELF() &&
2894 cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2895 ELF::STB_LOCAL);
2896 bool UseXGOT = STI->getFeatureBits()[Mips::FeatureXGOT] && !IsLocalSym;
2897
2898 // The case where the result register is $25 is somewhat special. If the
2899 // symbol in the final relocation is external and not modified with a
2900 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2901 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2902 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2903 Res.getConstant() == 0 && !IsLocalSym) {
2904 if (UseXGOT) {
2905 const MCExpr *CallHiExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16,
2906 SymExpr, getContext());
2907 const MCExpr *CallLoExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16,
2908 SymExpr, getContext());
2909 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2910 STI);
2911 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2912 IDLoc, STI);
2913 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2914 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2915 } else {
2916 const MCExpr *CallExpr =
2917 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2918 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2919 MCOperand::createExpr(CallExpr), IDLoc, STI);
2920 }
2921 return false;
2922 }
2923
2924 unsigned TmpReg = DstReg;
2925 if (UseSrcReg &&
2926 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2927 SrcReg)) {
2928 // If $rs is the same as $rd, we need to use AT.
2929 // If it is not available we exit.
2930 unsigned ATReg = getATReg(IDLoc);
2931 if (!ATReg)
2932 return true;
2933 TmpReg = ATReg;
2934 }
2935
2936 if (UseXGOT) {
2937 // Loading address from XGOT
2938 // External GOT: lui $tmp, %got_hi(symbol)($gp)
2939 // addu $tmp, $tmp, $gp
2940 // lw $tmp, %got_lo(symbol)($tmp)
2941 // >addiu $tmp, $tmp, offset
2942 // >addiu $rd, $tmp, $rs
2943 // The addiu's marked with a '>' may be omitted if they are redundant. If
2944 // this happens then the last instruction must use $rd as the result
2945 // register.
2946 const MCExpr *CallHiExpr =
2947 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
2948 const MCExpr *CallLoExpr = MipsMCExpr::create(
2949 MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
2950
2951 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2952 STI);
2953 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2954 IDLoc, STI);
2955 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
2956 MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2957
2958 if (Res.getConstant() != 0)
2959 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
2960 MCOperand::createExpr(MCConstantExpr::create(
2961 Res.getConstant(), getContext())),
2962 IDLoc, STI);
2963
2964 if (UseSrcReg)
2965 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
2966 IDLoc, STI);
2967 return false;
2968 }
2969
2970 const MipsMCExpr *GotExpr = nullptr;
2971 const MCExpr *LoExpr = nullptr;
2972 if (IsPtr64) {
2973 // The remaining cases are:
2974 // Small offset: ld $tmp, %got_disp(symbol)($gp)
2975 // >daddiu $tmp, $tmp, offset
2976 // >daddu $rd, $tmp, $rs
2977 // The daddiu's marked with a '>' may be omitted if they are redundant. If
2978 // this happens then the last instruction must use $rd as the result
2979 // register.
2980 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, Res.getSymA(),
2981 getContext());
2982 if (Res.getConstant() != 0) {
2983 // Symbols fully resolve with just the %got_disp(symbol) but we
2984 // must still account for any offset to the symbol for
2985 // expressions like symbol+8.
2986 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2987
2988 // FIXME: Offsets greater than 16 bits are not yet implemented.
2989 // FIXME: The correct range is a 32-bit sign-extended number.
2990 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
2991 Error(IDLoc, "macro instruction uses large offset, which is not "
2992 "currently supported");
2993 return true;
2994 }
2995 }
2996 } else {
2997 // The remaining cases are:
2998 // External GOT: lw $tmp, %got(symbol)($gp)
2999 // >addiu $tmp, $tmp, offset
3000 // >addiu $rd, $tmp, $rs
3001 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3002 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3003 // >addiu $rd, $tmp, $rs
3004 // The addiu's marked with a '>' may be omitted if they are redundant. If
3005 // this happens then the last instruction must use $rd as the result
3006 // register.
3007 if (IsLocalSym) {
3008 GotExpr =
3009 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3010 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3011 } else {
3012 // External symbols fully resolve the symbol with just the %got(symbol)
3013 // but we must still account for any offset to the symbol for
3014 // expressions like symbol+8.
3015 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, Res.getSymA(),
3016 getContext());
3017 if (Res.getConstant() != 0)
3018 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3019 }
3020 }
3021
3022 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3023 MCOperand::createExpr(GotExpr), IDLoc, STI);
3024
3025 if (LoExpr)
3026 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3027 MCOperand::createExpr(LoExpr), IDLoc, STI);
3028
3029 if (UseSrcReg)
3030 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3031 IDLoc, STI);
3032
3033 return false;
3034 }
3035
3036 const MipsMCExpr *HiExpr =
3037 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3038 const MipsMCExpr *LoExpr =
3039 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3040
3041 // This is the 64-bit symbol address expansion.
3042 if (ABI.ArePtrs64bit() && isGP64bit()) {
3043 // We need AT for the 64-bit expansion in the cases where the optional
3044 // source register is the destination register and for the superscalar
3045 // scheduled form.
3046 //
3047 // If it is not available we exit if the destination is the same as the
3048 // source register.
3049
3050 const MipsMCExpr *HighestExpr =
3051 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3052 const MipsMCExpr *HigherExpr =
3053 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3054
3055 bool RdRegIsRsReg =
3056 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3057
3058 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3059 unsigned ATReg = getATReg(IDLoc);
3060
3061 // If $rs is the same as $rd:
3062 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3063 // daddiu $at, $at, %higher(sym)
3064 // dsll $at, $at, 16
3065 // daddiu $at, $at, %hi(sym)
3066 // dsll $at, $at, 16
3067 // daddiu $at, $at, %lo(sym)
3068 // daddu $rd, $at, $rd
3069 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3070 STI);
3071 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3072 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3073 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3074 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3075 IDLoc, STI);
3076 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3077 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3078 IDLoc, STI);
3079 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3080
3081 return false;
3082 } else if (canUseATReg() && !RdRegIsRsReg) {
3083 unsigned ATReg = getATReg(IDLoc);
3084
3085 // If the $rs is different from $rd or if $rs isn't specified and we
3086 // have $at available:
3087 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3088 // lui $at, %hi(sym)
3089 // daddiu $rd, $rd, %higher(sym)
3090 // daddiu $at, $at, %lo(sym)
3091 // dsll32 $rd, $rd, 0
3092 // daddu $rd, $rd, $at
3093 // (daddu $rd, $rd, $rs)
3094 //
3095 // Which is preferred for superscalar issue.
3096 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3097 STI);
3098 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3099 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3100 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3101 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3102 IDLoc, STI);
3103 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3104 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3105 if (UseSrcReg)
3106 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3107
3108 return false;
3109 } else if (!canUseATReg() && !RdRegIsRsReg) {
3110 // Otherwise, synthesize the address in the destination register
3111 // serially:
3112 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3113 // daddiu $rd, $rd, %higher(sym)
3114 // dsll $rd, $rd, 16
3115 // daddiu $rd, $rd, %hi(sym)
3116 // dsll $rd, $rd, 16
3117 // daddiu $rd, $rd, %lo(sym)
3118 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3119 STI);
3120 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3121 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3122 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3123 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3124 MCOperand::createExpr(HiExpr), IDLoc, STI);
3125 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3126 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3127 MCOperand::createExpr(LoExpr), IDLoc, STI);
3128 if (UseSrcReg)
3129 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3130
3131 return false;
3132 } else {
3133 // We have a case where SrcReg == DstReg and we don't have $at
3134 // available. We can't expand this case, so error out appropriately.
3135 assert(SrcReg == DstReg && !canUseATReg() &&((SrcReg == DstReg && !canUseATReg() && "Could have expanded dla but didn't?"
) ? static_cast<void> (0) : __assert_fail ("SrcReg == DstReg && !canUseATReg() && \"Could have expanded dla but didn't?\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3136, __PRETTY_FUNCTION__))
3136 "Could have expanded dla but didn't?")((SrcReg == DstReg && !canUseATReg() && "Could have expanded dla but didn't?"
) ? static_cast<void> (0) : __assert_fail ("SrcReg == DstReg && !canUseATReg() && \"Could have expanded dla but didn't?\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3136, __PRETTY_FUNCTION__))
;
3137 reportParseError(IDLoc,
3138 "pseudo-instruction requires $at, which is not available");
3139 return true;
3140 }
3141 }
3142
3143 // And now, the 32-bit symbol address expansion:
3144 // If $rs is the same as $rd:
3145 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3146 // ori $at, $at, %lo(sym)
3147 // addu $rd, $at, $rd
3148 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3149 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3150 // ori $rd, $rd, %lo(sym)
3151 // (addu $rd, $rd, $rs)
3152 unsigned TmpReg = DstReg;
3153 if (UseSrcReg &&
3154 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3155 // If $rs is the same as $rd, we need to use AT.
3156 // If it is not available we exit.
3157 unsigned ATReg = getATReg(IDLoc);
3158 if (!ATReg)
3159 return true;
3160 TmpReg = ATReg;
3161 }
3162
3163 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3164 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3165 IDLoc, STI);
3166
3167 if (UseSrcReg)
3168 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3169 else
3170 assert(((getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg)) ? static_cast<void> (0) : __assert_fail ("getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3171, __PRETTY_FUNCTION__))
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg))((getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg
, TmpReg)) ? static_cast<void> (0) : __assert_fail ("getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3171, __PRETTY_FUNCTION__))
;
3172
3173 return false;
3174}
3175
3176// Each double-precision register DO-D15 overlaps with two of the single
3177// precision registers F0-F31. As an example, all of the following hold true:
3178// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3179static unsigned nextReg(unsigned Reg) {
3180 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3181 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3182 switch (Reg) {
3183 default: llvm_unreachable("Unknown register in assembly macro expansion!")::llvm::llvm_unreachable_internal("Unknown register in assembly macro expansion!"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3183)
;
3184 case Mips::ZERO: return Mips::AT;
3185 case Mips::AT: return Mips::V0;
3186 case Mips::V0: return Mips::V1;
3187 case Mips::V1: return Mips::A0;
3188 case Mips::A0: return Mips::A1;
3189 case Mips::A1: return Mips::A2;
3190 case Mips::A2: return Mips::A3;
3191 case Mips::A3: return Mips::T0;
3192 case Mips::T0: return Mips::T1;
3193 case Mips::T1: return Mips::T2;
3194 case Mips::T2: return Mips::T3;
3195 case Mips::T3: return Mips::T4;
3196 case Mips::T4: return Mips::T5;
3197 case Mips::T5: return Mips::T6;
3198 case Mips::T6: return Mips::T7;
3199 case Mips::T7: return Mips::S0;
3200 case Mips::S0: return Mips::S1;
3201 case Mips::S1: return Mips::S2;
3202 case Mips::S2: return Mips::S3;
3203 case Mips::S3: return Mips::S4;
3204 case Mips::S4: return Mips::S5;
3205 case Mips::S5: return Mips::S6;
3206 case Mips::S6: return Mips::S7;
3207 case Mips::S7: return Mips::T8;
3208 case Mips::T8: return Mips::T9;
3209 case Mips::T9: return Mips::K0;
3210 case Mips::K0: return Mips::K1;
3211 case Mips::K1: return Mips::GP;
3212 case Mips::GP: return Mips::SP;
3213 case Mips::SP: return Mips::FP;
3214 case Mips::FP: return Mips::RA;
3215 case Mips::RA: return Mips::ZERO;
3216 case Mips::D0: return Mips::F1;
3217 case Mips::D1: return Mips::F3;
3218 case Mips::D2: return Mips::F5;
3219 case Mips::D3: return Mips::F7;
3220 case Mips::D4: return Mips::F9;
3221 case Mips::D5: return Mips::F11;
3222 case Mips::D6: return Mips::F13;
3223 case Mips::D7: return Mips::F15;
3224 case Mips::D8: return Mips::F17;
3225 case Mips::D9: return Mips::F19;
3226 case Mips::D10: return Mips::F21;
3227 case Mips::D11: return Mips::F23;
3228 case Mips::D12: return Mips::F25;
3229 case Mips::D13: return Mips::F27;
3230 case Mips::D14: return Mips::F29;
3231 case Mips::D15: return Mips::F31;
3232 }
3233}
3234
3235// FIXME: This method is too general. In principle we should compute the number
3236// of instructions required to synthesize the immediate inline compared to
3237// synthesizing the address inline and relying on non .text sections.
3238// For static O32 and N32 this may yield a small benefit, for static N64 this is
3239// likely to yield a much larger benefit as we have to synthesize a 64bit
3240// address to load a 64 bit value.
3241bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3242 MCSymbol *Sym) {
3243 unsigned ATReg = getATReg(IDLoc);
3244 if (!ATReg)
3245 return true;
3246
3247 if(IsPicEnabled) {
3248 const MCExpr *GotSym =
3249 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3250 const MipsMCExpr *GotExpr =
3251 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3252
3253 if(isABI_O32() || isABI_N32()) {
3254 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3255 IDLoc, STI);
3256 } else { //isABI_N64()
3257 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3258 IDLoc, STI);
3259 }
3260 } else { //!IsPicEnabled
3261 const MCExpr *HiSym =
3262 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3263 const MipsMCExpr *HiExpr =
3264 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3265
3266 // FIXME: This is technically correct but gives a different result to gas,
3267 // but gas is incomplete there (it has a fixme noting it doesn't work with
3268 // 64-bit addresses).
3269 // FIXME: With -msym32 option, the address expansion for N64 should probably
3270 // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3271 // symbol's value is considered sign extended.
3272 if(isABI_O32() || isABI_N32()) {
3273 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3274 } else { //isABI_N64()
3275 const MCExpr *HighestSym =
3276 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3277 const MipsMCExpr *HighestExpr =
3278 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3279 const MCExpr *HigherSym =
3280 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3281 const MipsMCExpr *HigherExpr =
3282 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3283
3284 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3285 STI);
3286 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3287 MCOperand::createExpr(HigherExpr), IDLoc, STI);
3288 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3289 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3290 IDLoc, STI);
3291 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3292 }
3293 }
3294 return false;
3295}
3296
3297static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) {
3298 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3299 // exponent field), convert it to double (e.g. 1 to 1.0)
3300 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3301 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3302 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3303 }
3304 return ImmOp64;
3305}
3306
3307static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) {
3308 // Conversion of a double in an uint64_t to a float in a uint32_t,
3309 // retaining the bit pattern of a float.
3310 double DoubleImm = BitsToDouble(ImmOp64);
3311 float TmpFloat = static_cast<float>(DoubleImm);
3312 return FloatToBits(TmpFloat);
3313}
3314
3315bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3316 MCStreamer &Out,
3317 const MCSubtargetInfo *STI) {
3318 assert(Inst.getNumOperands() == 2 && "Invalid operand count")((Inst.getNumOperands() == 2 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 2 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3318, __PRETTY_FUNCTION__))
;
3319 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3320, __PRETTY_FUNCTION__))
3320 "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3320, __PRETTY_FUNCTION__))
;
3321
3322 unsigned FirstReg = Inst.getOperand(0).getReg();
3323 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3324
3325 uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3326
3327 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3328 Out, STI);
3329}
3330
3331bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3332 MCStreamer &Out,
3333 const MCSubtargetInfo *STI) {
3334 MipsTargetStreamer &TOut = getTargetStreamer();
3335 assert(Inst.getNumOperands() == 2 && "Invalid operand count")((Inst.getNumOperands() == 2 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 2 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3335, __PRETTY_FUNCTION__))
;
3336 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3337, __PRETTY_FUNCTION__))
3337 "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3337, __PRETTY_FUNCTION__))
;
3338
3339 unsigned FirstReg = Inst.getOperand(0).getReg();
3340 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3341
3342 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3343
3344 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3345
3346 unsigned TmpReg = Mips::ZERO;
3347 if (ImmOp32 != 0) {
3348 TmpReg = getATReg(IDLoc);
3349 if (!TmpReg)
3350 return true;
3351 }
3352
3353 if (Lo_32(ImmOp64) == 0) {
3354 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3355 true, false, IDLoc, Out, STI))
3356 return true;
3357 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3358 return false;
3359 }
3360
3361 MCSection *CS = getStreamer().getCurrentSectionOnly();
3362 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3363 // where appropriate.
3364 MCSection *ReadOnlySection =
3365 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3366
3367 MCSymbol *Sym = getContext().createTempSymbol();
3368 const MCExpr *LoSym =
3369 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3370 const MipsMCExpr *LoExpr =
3371 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3372
3373 getStreamer().SwitchSection(ReadOnlySection);
3374 getStreamer().EmitLabel(Sym, IDLoc);
3375 getStreamer().EmitIntValue(ImmOp32, 4);
3376 getStreamer().SwitchSection(CS);
3377
3378 if (emitPartialAddress(TOut, IDLoc, Sym))
3379 return true;
3380 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3381 IDLoc, STI);
3382 return false;
3383}
3384
3385bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3386 MCStreamer &Out,
3387 const MCSubtargetInfo *STI) {
3388 MipsTargetStreamer &TOut = getTargetStreamer();
3389 assert(Inst.getNumOperands() == 2 && "Invalid operand count")((Inst.getNumOperands() == 2 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 2 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3389, __PRETTY_FUNCTION__))
;
3390 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3391, __PRETTY_FUNCTION__))
3391 "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3391, __PRETTY_FUNCTION__))
;
3392
3393 unsigned FirstReg = Inst.getOperand(0).getReg();
3394 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3395
3396 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3397
3398 if (Lo_32(ImmOp64) == 0) {
3399 if (isGP64bit()) {
3400 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3401 IDLoc, Out, STI))
3402 return true;
3403 } else {
3404 if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3405 IDLoc, Out, STI))
3406 return true;
3407
3408 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3409 IDLoc, Out, STI))
3410 return true;
3411 }
3412 return false;
3413 }
3414
3415 MCSection *CS = getStreamer().getCurrentSectionOnly();
3416 MCSection *ReadOnlySection =
3417 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3418
3419 MCSymbol *Sym = getContext().createTempSymbol();
3420 const MCExpr *LoSym =
3421 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3422 const MipsMCExpr *LoExpr =
3423 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3424
3425 getStreamer().SwitchSection(ReadOnlySection);
3426 getStreamer().EmitLabel(Sym, IDLoc);
3427 getStreamer().EmitValueToAlignment(8);
3428 getStreamer().EmitIntValue(ImmOp64, 8);
3429 getStreamer().SwitchSection(CS);
3430
3431 unsigned TmpReg = getATReg(IDLoc);
3432 if (!TmpReg)
3433 return true;
3434
3435 if (emitPartialAddress(TOut, IDLoc, Sym))
3436 return true;
3437
3438 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3439 MCOperand::createExpr(LoExpr), IDLoc, STI);
3440
3441 if (isGP64bit())
3442 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3443 else {
3444 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3445 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3446 }
3447 return false;
3448}
3449
3450bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3451 SMLoc IDLoc, MCStreamer &Out,
3452 const MCSubtargetInfo *STI) {
3453 MipsTargetStreamer &TOut = getTargetStreamer();
3454 assert(Inst.getNumOperands() == 2 && "Invalid operand count")((Inst.getNumOperands() == 2 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 2 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3454, __PRETTY_FUNCTION__))
;
3455 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3456, __PRETTY_FUNCTION__))
3456 "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3456, __PRETTY_FUNCTION__))
;
3457
3458 unsigned FirstReg = Inst.getOperand(0).getReg();
3459 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3460
3461 ImmOp64 = convertIntToDoubleImm(ImmOp64);
3462
3463 unsigned TmpReg = Mips::ZERO;
3464 if (ImmOp64 != 0) {
3465 TmpReg = getATReg(IDLoc);
3466 if (!TmpReg)
3467 return true;
3468 }
3469
3470 if ((Lo_32(ImmOp64) == 0) &&
3471 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3472 if (isGP64bit()) {
3473 if (TmpReg != Mips::ZERO &&
3474 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3475 Out, STI))
3476 return true;
3477 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3478 return false;
3479 }
3480
3481 if (TmpReg != Mips::ZERO &&
3482 loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3483 IDLoc, Out, STI))
3484 return true;
3485
3486 if (hasMips32r2()) {
3487 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3488 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3489 } else {
3490 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3491 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3492 }
3493 return false;
3494 }
3495
3496 MCSection *CS = getStreamer().getCurrentSectionOnly();
3497 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3498 // where appropriate.
3499 MCSection *ReadOnlySection =
3500 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3501
3502 MCSymbol *Sym = getContext().createTempSymbol();
3503 const MCExpr *LoSym =
3504 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3505 const MipsMCExpr *LoExpr =
3506 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3507
3508 getStreamer().SwitchSection(ReadOnlySection);
3509 getStreamer().EmitLabel(Sym, IDLoc);
3510 getStreamer().EmitValueToAlignment(8);
3511 getStreamer().EmitIntValue(ImmOp64, 8);
3512 getStreamer().SwitchSection(CS);
3513
3514 if (emitPartialAddress(TOut, IDLoc, Sym))
3515 return true;
3516
3517 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3518 MCOperand::createExpr(LoExpr), IDLoc, STI);
3519
3520 return false;
3521}
3522
3523bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3524 MCStreamer &Out,
3525 const MCSubtargetInfo *STI) {
3526 MipsTargetStreamer &TOut = getTargetStreamer();
3527
3528 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&((getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
"unexpected number of operands") ? static_cast<void> (
0) : __assert_fail ("getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3529, __PRETTY_FUNCTION__))
3529 "unexpected number of operands")((getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
"unexpected number of operands") ? static_cast<void> (
0) : __assert_fail ("getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && \"unexpected number of operands\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3529, __PRETTY_FUNCTION__))
;
3530
3531 MCOperand Offset = Inst.getOperand(0);
3532 if (Offset.isExpr()) {
3533 Inst.clear();
3534 Inst.setOpcode(Mips::BEQ_MM);
3535 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3536 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3537 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3538 } else {
3539 assert(Offset.isImm() && "expected immediate operand kind")((Offset.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("Offset.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3539, __PRETTY_FUNCTION__))
;
3540 if (isInt<11>(Offset.getImm())) {
3541 // If offset fits into 11 bits then this instruction becomes microMIPS
3542 // 16-bit unconditional branch instruction.
3543 if (inMicroMipsMode())
3544 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3545 } else {
3546 if (!isInt<17>(Offset.getImm()))
3547 return Error(IDLoc, "branch target out of range");
3548 if (offsetToAlignment(Offset.getImm(), Align(2)))
3549 return Error(IDLoc, "branch to misaligned address");
3550 Inst.clear();
3551 Inst.setOpcode(Mips::BEQ_MM);
3552 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3553 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3554 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3555 }
3556 }
3557 Out.EmitInstruction(Inst, *STI);
3558
3559 // If .set reorder is active and branch instruction has a delay slot,
3560 // emit a NOP after it.
3561 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3562 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3563 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3564
3565 return false;
3566}
3567
3568bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3569 const MCSubtargetInfo *STI) {
3570 MipsTargetStreamer &TOut = getTargetStreamer();
3571 const MCOperand &DstRegOp = Inst.getOperand(0);
3572 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3572, __PRETTY_FUNCTION__))
;
3573
3574 const MCOperand &ImmOp = Inst.getOperand(1);
3575 assert(ImmOp.isImm() && "expected immediate operand kind")((ImmOp.isImm() && "expected immediate operand kind")
? static_cast<void> (0) : __assert_fail ("ImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3575, __PRETTY_FUNCTION__))
;
3576
3577 const MCOperand &MemOffsetOp = Inst.getOperand(2);
3578 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&(((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && "expected immediate or expression operand"
) ? static_cast<void> (0) : __assert_fail ("(MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && \"expected immediate or expression operand\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3579, __PRETTY_FUNCTION__))
3579 "expected immediate or expression operand")(((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && "expected immediate or expression operand"
) ? static_cast<void> (0) : __assert_fail ("(MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && \"expected immediate or expression operand\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3579, __PRETTY_FUNCTION__))
;
3580
3581 bool IsLikely = false;
3582
3583 unsigned OpCode = 0;
3584 switch(Inst.getOpcode()) {
3585 case Mips::BneImm:
3586 OpCode = Mips::BNE;
3587 break;
3588 case Mips::BeqImm:
3589 OpCode = Mips::BEQ;
3590 break;
3591 case Mips::BEQLImmMacro:
3592 OpCode = Mips::BEQL;
3593 IsLikely = true;
3594 break;
3595 case Mips::BNELImmMacro:
3596 OpCode = Mips::BNEL;
3597 IsLikely = true;
3598 break;
3599 default:
3600 llvm_unreachable("Unknown immediate branch pseudo-instruction.")::llvm::llvm_unreachable_internal("Unknown immediate branch pseudo-instruction."
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3600)
;
3601 break;
3602 }
3603
3604 int64_t ImmValue = ImmOp.getImm();
3605 if (ImmValue == 0) {
3606 if (IsLikely) {
3607 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3608 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3609 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3610 } else
3611 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3612 STI);
3613 } else {
3614 warnIfNoMacro(IDLoc);
3615
3616 unsigned ATReg = getATReg(IDLoc);
3617 if (!ATReg)
3618 return true;
3619
3620 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3621 IDLoc, Out, STI))
3622 return true;
3623
3624 if (IsLikely) {
3625 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3626 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3627 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3628 } else
3629 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3630 }
3631 return false;
3632}
3633
3634void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3635 const MCSubtargetInfo *STI, bool IsLoad) {
3636 const MCOperand &DstRegOp = Inst.getOperand(0);
3637 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3637, __PRETTY_FUNCTION__))
;
3638 const MCOperand &BaseRegOp = Inst.getOperand(1);
3639 assert(BaseRegOp.isReg() && "expected register operand kind")((BaseRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("BaseRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3639, __PRETTY_FUNCTION__))
;
3640
3641 MipsTargetStreamer &TOut = getTargetStreamer();
3642 unsigned DstReg = DstRegOp.getReg();
3643 unsigned BaseReg = BaseRegOp.getReg();
3644 unsigned TmpReg = DstReg;
3645
3646 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
3647 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
3648 unsigned DstRegClassID =
3649 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3650 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3651 (DstRegClassID == Mips::GPR64RegClassID);
3652
3653 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3654 // At this point we need AT to perform the expansions
3655 // and we exit if it is not available.
3656 TmpReg = getATReg(IDLoc);
3657 if (!TmpReg)
3658 return;
3659 }
3660
3661 if (Inst.getNumOperands() > 3) {
3662 const MCOperand &BaseRegOp = Inst.getOperand(2);
3663 assert(BaseRegOp.isReg() && "expected register operand kind")((BaseRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("BaseRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3663, __PRETTY_FUNCTION__))
;
3664 const MCOperand &ExprOp = Inst.getOperand(3);
3665 assert(ExprOp.isExpr() && "expected expression oprand kind")((ExprOp.isExpr() && "expected expression oprand kind"
) ? static_cast<void> (0) : __assert_fail ("ExprOp.isExpr() && \"expected expression oprand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3665, __PRETTY_FUNCTION__))
;
3666
3667 unsigned BaseReg = BaseRegOp.getReg();
3668 const MCExpr *ExprOffset = ExprOp.getExpr();
3669
3670 MCOperand LoOperand = MCOperand::createExpr(
3671 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3672 MCOperand HiOperand = MCOperand::createExpr(
3673 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3674 TOut.emitSCWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
3675 LoOperand, TmpReg, IDLoc, STI);
3676 return;
3677 }
3678
3679 const MCOperand &OffsetOp = Inst.getOperand(2);
3680
3681 if (OffsetOp.isImm()) {
3682 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3683 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3684
3685 // If msb of LoOffset is 1(negative number) we must increment
3686 // HiOffset to account for the sign-extension of the low part.
3687 if (LoOffset & 0x8000)
3688 HiOffset += 0x10000;
3689
3690 bool IsLargeOffset = HiOffset != 0;
3691
3692 if (IsLargeOffset) {
3693 bool Is32BitImm = (HiOffset >> 32) == 0;
3694 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3695 IDLoc, Out, STI))
3696 return;
3697 }
3698
3699 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3700 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3701 BaseReg, IDLoc, STI);
3702 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3703 return;
3704 }
3705
3706 if (OffsetOp.isExpr()) {
3707 if (inPicMode()) {
3708 // FIXME:
3709 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3710 // do not exceed 16-bit.
3711 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3712 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3713 // of GOT entries.
3714 MCValue Res;
3715 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3716 Error(IDLoc, "expected relocatable expression");
3717 return;
3718 }
3719 if (Res.getSymB() != nullptr) {
3720 Error(IDLoc, "expected relocatable expression with only one symbol");
3721 return;
3722 }
3723
3724 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3725 !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3726 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, Res.getConstant(), IDLoc,
3727 STI);
3728 } else {
3729 // FIXME: Implement 64-bit case.
3730 // 1) lw $8, sym => lui $8, %hi(sym)
3731 // lw $8, %lo(sym)($8)
3732 // 2) sw $8, sym => lui $at, %hi(sym)
3733 // sw $8, %lo(sym)($at)
3734 const MCExpr *ExprOffset = OffsetOp.getExpr();
3735 MCOperand LoOperand = MCOperand::createExpr(
3736 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
3737 MCOperand HiOperand = MCOperand::createExpr(
3738 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
3739
3740 // Generate the base address in TmpReg.
3741 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3742 if (BaseReg != Mips::ZERO)
3743 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3744 // Emit the load or store with the adjusted base and offset.
3745 TOut.emitRRX(Inst.getOpcode(), DstReg, TmpReg, LoOperand, IDLoc, STI);
3746 }
3747 return;
3748 }
3749
3750 llvm_unreachable("unexpected operand type")::llvm::llvm_unreachable_internal("unexpected operand type", "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3750)
;
3751}
3752
3753bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3754 MCStreamer &Out,
3755 const MCSubtargetInfo *STI) {
3756 unsigned OpNum = Inst.getNumOperands();
3757 unsigned Opcode = Inst.getOpcode();
3758 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3759
3760 assert(Inst.getOperand(OpNum - 1).isImm() &&((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3762, __PRETTY_FUNCTION__))
3761 Inst.getOperand(OpNum - 2).isReg() &&((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3762, __PRETTY_FUNCTION__))
3762 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.")((Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand
(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg
() && "Invalid instruction operand.") ? static_cast<
void> (0) : __assert_fail ("Inst.getOperand(OpNum - 1).isImm() && Inst.getOperand(OpNum - 2).isReg() && Inst.getOperand(OpNum - 3).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3762, __PRETTY_FUNCTION__))
;
3763
3764 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3765 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3766 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3767 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3768 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3769 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3770 // It can be implemented as SWM16 or LWM16 instruction.
3771 if (inMicroMipsMode() && hasMips32r6())
3772 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3773 else
3774 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3775 }
3776
3777 Inst.setOpcode(NewOpcode);
3778 Out.EmitInstruction(Inst, *STI);
3779 return false;
3780}
3781
3782bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3783 MCStreamer &Out,
3784 const MCSubtargetInfo *STI) {
3785 MipsTargetStreamer &TOut = getTargetStreamer();
3786 bool EmittedNoMacroWarning = false;
3787 unsigned PseudoOpcode = Inst.getOpcode();
3788 unsigned SrcReg = Inst.getOperand(0).getReg();
3789 const MCOperand &TrgOp = Inst.getOperand(1);
3790 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3791
3792 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3793 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3794
3795 unsigned TrgReg;
3796 if (TrgOp.isReg())
3797 TrgReg = TrgOp.getReg();
3798 else if (TrgOp.isImm()) {
3799 warnIfNoMacro(IDLoc);
3800 EmittedNoMacroWarning = true;
3801
3802 TrgReg = getATReg(IDLoc);
3803 if (!TrgReg)
3804 return true;
3805
3806 switch(PseudoOpcode) {
3807 default:
3808 llvm_unreachable("unknown opcode for branch pseudo-instruction")::llvm::llvm_unreachable_internal("unknown opcode for branch pseudo-instruction"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3808)
;
3809 case Mips::BLTImmMacro:
3810 PseudoOpcode = Mips::BLT;
3811 break;
3812 case Mips::BLEImmMacro:
3813 PseudoOpcode = Mips::BLE;
3814 break;
3815 case Mips::BGEImmMacro:
3816 PseudoOpcode = Mips::BGE;
3817 break;
3818 case Mips::BGTImmMacro:
3819 PseudoOpcode = Mips::BGT;
3820 break;
3821 case Mips::BLTUImmMacro:
3822 PseudoOpcode = Mips::BLTU;
3823 break;
3824 case Mips::BLEUImmMacro:
3825 PseudoOpcode = Mips::BLEU;
3826 break;
3827 case Mips::BGEUImmMacro:
3828 PseudoOpcode = Mips::BGEU;
3829 break;
3830 case Mips::BGTUImmMacro:
3831 PseudoOpcode = Mips::BGTU;
3832 break;
3833 case Mips::BLTLImmMacro:
3834 PseudoOpcode = Mips::BLTL;
3835 break;
3836 case Mips::BLELImmMacro:
3837 PseudoOpcode = Mips::BLEL;
3838 break;
3839 case Mips::BGELImmMacro:
3840 PseudoOpcode = Mips::BGEL;
3841 break;
3842 case Mips::BGTLImmMacro:
3843 PseudoOpcode = Mips::BGTL;
3844 break;
3845 case Mips::BLTULImmMacro:
3846 PseudoOpcode = Mips::BLTUL;
3847 break;
3848 case Mips::BLEULImmMacro:
3849 PseudoOpcode = Mips::BLEUL;
3850 break;
3851 case Mips::BGEULImmMacro:
3852 PseudoOpcode = Mips::BGEUL;
3853 break;
3854 case Mips::BGTULImmMacro:
3855 PseudoOpcode = Mips::BGTUL;
3856 break;
3857 }
3858
3859 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3860 false, IDLoc, Out, STI))
3861 return true;
3862 }
3863
3864 switch (PseudoOpcode) {
3865 case Mips::BLT:
3866 case Mips::BLTU:
3867 case Mips::BLTL:
3868 case Mips::BLTUL:
3869 AcceptsEquality = false;
3870 ReverseOrderSLT = false;
3871 IsUnsigned =
3872 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3873 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3874 ZeroSrcOpcode = Mips::BGTZ;
3875 ZeroTrgOpcode = Mips::BLTZ;
3876 break;
3877 case Mips::BLE:
3878 case Mips::BLEU:
3879 case Mips::BLEL:
3880 case Mips::BLEUL:
3881 AcceptsEquality = true;
3882 ReverseOrderSLT = true;
3883 IsUnsigned =
3884 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3885 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3886 ZeroSrcOpcode = Mips::BGEZ;
3887 ZeroTrgOpcode = Mips::BLEZ;
3888 break;
3889 case Mips::BGE:
3890 case Mips::BGEU:
3891 case Mips::BGEL:
3892 case Mips::BGEUL:
3893 AcceptsEquality = true;
3894 ReverseOrderSLT = false;
3895 IsUnsigned =
3896 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3897 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3898 ZeroSrcOpcode = Mips::BLEZ;
3899 ZeroTrgOpcode = Mips::BGEZ;
3900 break;
3901 case Mips::BGT:
3902 case Mips::BGTU:
3903 case Mips::BGTL:
3904 case Mips::BGTUL:
3905 AcceptsEquality = false;
3906 ReverseOrderSLT = true;
3907 IsUnsigned =
3908 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3909 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3910 ZeroSrcOpcode = Mips::BLTZ;
3911 ZeroTrgOpcode = Mips::BGTZ;
3912 break;
3913 default:
3914 llvm_unreachable("unknown opcode for branch pseudo-instruction")::llvm::llvm_unreachable_internal("unknown opcode for branch pseudo-instruction"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 3914)
;
3915 }
3916
3917 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3918 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3919 if (IsSrcRegZero && IsTrgRegZero) {
3920 // FIXME: All of these Opcode-specific if's are needed for compatibility
3921 // with GAS' behaviour. However, they may not generate the most efficient
3922 // code in some circumstances.
3923 if (PseudoOpcode == Mips::BLT) {
3924 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3925 IDLoc, STI);
3926 return false;
3927 }
3928 if (PseudoOpcode == Mips::BLE) {
3929 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3930 IDLoc, STI);
3931 Warning(IDLoc, "branch is always taken");
3932 return false;
3933 }
3934 if (PseudoOpcode == Mips::BGE) {
3935 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3936 IDLoc, STI);
3937 Warning(IDLoc, "branch is always taken");
3938 return false;
3939 }
3940 if (PseudoOpcode == Mips::BGT) {
3941 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3942 IDLoc, STI);
3943 return false;
3944 }
3945 if (PseudoOpcode == Mips::BGTU) {
3946 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3947 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3948 return false;
3949 }
3950 if (AcceptsEquality) {
3951 // If both registers are $0 and the pseudo-branch accepts equality, it
3952 // will always be taken, so we emit an unconditional branch.
3953 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3954 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3955 Warning(IDLoc, "branch is always taken");
3956 return false;
3957 }
3958 // If both registers are $0 and the pseudo-branch does not accept
3959 // equality, it will never be taken, so we don't have to emit anything.
3960 return false;
3961 }
3962 if (IsSrcRegZero || IsTrgRegZero) {
3963 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3964 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3965 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3966 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3967 // the pseudo-branch will never be taken, so we don't emit anything.
3968 // This only applies to unsigned pseudo-branches.
3969 return false;
3970 }
3971 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3972 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3973 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3974 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3975 // the pseudo-branch will always be taken, so we emit an unconditional
3976 // branch.
3977 // This only applies to unsigned pseudo-branches.
3978 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3979 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3980 Warning(IDLoc, "branch is always taken");
3981 return false;
3982 }
3983 if (IsUnsigned) {
3984 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3985 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3986 // the pseudo-branch will be taken only when the non-zero register is
3987 // different from 0, so we emit a BNEZ.
3988 //
3989 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3990 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3991 // the pseudo-branch will be taken only when the non-zero register is
3992 // equal to 0, so we emit a BEQZ.
3993 //
3994 // Because only BLEU and BGEU branch on equality, we can use the
3995 // AcceptsEquality variable to decide when to emit the BEQZ.
3996 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3997 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3998 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3999 return false;
4000 }
4001 // If we have a signed pseudo-branch and one of the registers is $0,
4002 // we can use an appropriate compare-to-zero branch. We select which one
4003 // to use in the switch statement above.
4004 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4005 IsSrcRegZero ? TrgReg : SrcReg,
4006 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4007 return false;
4008 }
4009
4010 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4011 // expansions. If it is not available, we return.
4012 unsigned ATRegNum = getATReg(IDLoc);
4013 if (!ATRegNum)
4014 return true;
4015
4016 if (!EmittedNoMacroWarning)
4017 warnIfNoMacro(IDLoc);
4018
4019 // SLT fits well with 2 of our 4 pseudo-branches:
4020 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4021 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4022 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4023 // This is accomplished by using a BNEZ with the result of the SLT.
4024 //
4025 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4026 // and BLE with BGT), so we change the BNEZ into a BEQZ.
4027 // Because only BGE and BLE branch on equality, we can use the
4028 // AcceptsEquality variable to decide when to emit the BEQZ.
4029 // Note that the order of the SLT arguments doesn't change between
4030 // opposites.
4031 //
4032 // The same applies to the unsigned variants, except that SLTu is used
4033 // instead of SLT.
4034 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4035 ReverseOrderSLT ? TrgReg : SrcReg,
4036 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4037
4038 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4039 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4040 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4041 STI);
4042 return false;
4043}
4044
4045// Expand a integer division macro.
4046//
4047// Notably we don't have to emit a warning when encountering $rt as the $zero
4048// register, or 0 as an immediate. processInstruction() has already done that.
4049//
4050// The destination register can only be $zero when expanding (S)DivIMacro or
4051// D(S)DivMacro.
4052
4053bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4054 const MCSubtargetInfo *STI, const bool IsMips64,
4055 const bool Signed) {
4056 MipsTargetStreamer &TOut = getTargetStreamer();
4057
4058 warnIfNoMacro(IDLoc);
4059
4060 const MCOperand &RdRegOp = Inst.getOperand(0);
4061 assert(RdRegOp.isReg() && "expected register operand kind")((RdRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("RdRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4061, __PRETTY_FUNCTION__))
;
4062 unsigned RdReg = RdRegOp.getReg();
4063
4064 const MCOperand &RsRegOp = Inst.getOperand(1);
4065 assert(RsRegOp.isReg() && "expected register operand kind")((RsRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("RsRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4065, __PRETTY_FUNCTION__))
;
4066 unsigned RsReg = RsRegOp.getReg();
4067
4068 unsigned RtReg;
4069 int64_t ImmValue;
4070
4071 const MCOperand &RtOp = Inst.getOperand(2);
4072 assert((RtOp.isReg() || RtOp.isImm()) &&(((RtOp.isReg() || RtOp.isImm()) && "expected register or immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("(RtOp.isReg() || RtOp.isImm()) && \"expected register or immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4073, __PRETTY_FUNCTION__))
4073 "expected register or immediate operand kind")(((RtOp.isReg() || RtOp.isImm()) && "expected register or immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("(RtOp.isReg() || RtOp.isImm()) && \"expected register or immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4073, __PRETTY_FUNCTION__))
;
4074 if (RtOp.isReg())
4075 RtReg = RtOp.getReg();
4076 else
4077 ImmValue = RtOp.getImm();
4078
4079 unsigned DivOp;
4080 unsigned ZeroReg;
4081 unsigned SubOp;
4082
4083 if (IsMips64) {
4084 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4085 ZeroReg = Mips::ZERO_64;
4086 SubOp = Mips::DSUB;
4087 } else {
4088 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4089 ZeroReg = Mips::ZERO;
4090 SubOp = Mips::SUB;
4091 }
4092
4093 bool UseTraps = useTraps();
4094
4095 unsigned Opcode = Inst.getOpcode();
4096 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4097 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4098 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4099 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4100
4101 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4102 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4103 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4104 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4105
4106 if (RtOp.isImm()) {
4107 unsigned ATReg = getATReg(IDLoc);
4108 if (!ATReg)
4109 return true;
4110
4111 if (ImmValue == 0) {
4112 if (UseTraps)
4113 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4114 else
4115 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4116 return false;
4117 }
4118
4119 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4120 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4121 return false;
4122 } else if (isDiv && ImmValue == 1) {
4123 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4124 return false;
4125 } else if (isDiv && Signed && ImmValue == -1) {
4126 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4127 return false;
4128 } else {
4129 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4130 false, Inst.getLoc(), Out, STI))
4131 return true;
4132 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4133 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4134 return false;
4135 }
4136 return true;
4137 }
4138
4139 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4140 // break, insert the trap/break and exit. This gives a different result to
4141 // GAS. GAS has an inconsistency/missed optimization in that not all cases
4142 // are handled equivalently. As the observed behaviour is the same, we're ok.
4143 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4144 if (UseTraps) {
4145 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4146 return false;
4147 }
4148 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4149 return false;
4150 }
4151
4152 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4153 // not expand to macro sequence.
4154 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4155 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4156 return false;
4157 }
4158
4159 // Temporary label for first branch traget
4160 MCContext &Context = TOut.getStreamer().getContext();
4161 MCSymbol *BrTarget;
4162 MCOperand LabelOp;
4163
4164 if (UseTraps) {
4165 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4166 } else {
4167 // Branch to the li instruction.
4168 BrTarget = Context.createTempSymbol();
4169 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4170 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4171 }
4172
4173 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4174
4175 if (!UseTraps)
4176 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4177
4178 if (!Signed) {
4179 if (!UseTraps)
4180 TOut.getStreamer().EmitLabel(BrTarget);
4181
4182 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4183 return false;
4184 }
4185
4186 unsigned ATReg = getATReg(IDLoc);
4187 if (!ATReg)
4188 return true;
4189
4190 if (!UseTraps)
4191 TOut.getStreamer().EmitLabel(BrTarget);
4192
4193 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4194
4195 // Temporary label for the second branch target.
4196 MCSymbol *BrTargetEnd = Context.createTempSymbol();
4197 MCOperand LabelOpEnd =
4198 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4199
4200 // Branch to the mflo instruction.
4201 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4202
4203 if (IsMips64) {
4204 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4205 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4206 } else {
4207 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4208 }
4209
4210 if (UseTraps)
4211 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4212 else {
4213 // Branch to the mflo instruction.
4214 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4215 TOut.emitNop(IDLoc, STI);
4216 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4217 }
4218
4219 TOut.getStreamer().EmitLabel(BrTargetEnd);
4220 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4221 return false;
4222}
4223
4224bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4225 SMLoc IDLoc, MCStreamer &Out,
4226 const MCSubtargetInfo *STI) {
4227 MipsTargetStreamer &TOut = getTargetStreamer();
4228
4229 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4229, __PRETTY_FUNCTION__))
;
4230 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4231, __PRETTY_FUNCTION__))
4231 Inst.getOperand(2).isReg() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4231, __PRETTY_FUNCTION__))
;
4232
4233 unsigned FirstReg = Inst.getOperand(0).getReg();
4234 unsigned SecondReg = Inst.getOperand(1).getReg();
4235 unsigned ThirdReg = Inst.getOperand(2).getReg();
4236
4237 if (hasMips1() && !hasMips2()) {
4238 unsigned ATReg = getATReg(IDLoc);
4239 if (!ATReg)
4240 return true;
4241 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4242 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4243 TOut.emitNop(IDLoc, STI);
4244 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4245 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4246 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4247 TOut.emitNop(IDLoc, STI);
4248 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4249 : Mips::CVT_W_S,
4250 FirstReg, SecondReg, IDLoc, STI);
4251 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4252 TOut.emitNop(IDLoc, STI);
4253 return false;
4254 }
4255
4256 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4257 : Mips::TRUNC_W_S,
4258 FirstReg, SecondReg, IDLoc, STI);
4259
4260 return false;
4261}
4262
4263bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4264 MCStreamer &Out, const MCSubtargetInfo *STI) {
4265 if (hasMips32r6() || hasMips64r6()) {
4266 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4267 }
4268
4269 const MCOperand &DstRegOp = Inst.getOperand(0);
4270 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4270, __PRETTY_FUNCTION__))
;
4271 const MCOperand &SrcRegOp = Inst.getOperand(1);
4272 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4272, __PRETTY_FUNCTION__))
;
4273 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4274 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4274, __PRETTY_FUNCTION__))
;
4275
4276 MipsTargetStreamer &TOut = getTargetStreamer();
4277 unsigned DstReg = DstRegOp.getReg();
4278 unsigned SrcReg = SrcRegOp.getReg();
4279 int64_t OffsetValue = OffsetImmOp.getImm();
4280
4281 // NOTE: We always need AT for ULHU, as it is always used as the source
4282 // register for one of the LBu's.
4283 warnIfNoMacro(IDLoc);
4284 unsigned ATReg = getATReg(IDLoc);
4285 if (!ATReg)
4286 return true;
4287
4288 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4289 if (IsLargeOffset) {
4290 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4291 IDLoc, Out, STI))
4292 return true;
4293 }
4294
4295 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4296 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4297 if (isLittle())
4298 std::swap(FirstOffset, SecondOffset);
4299
4300 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4301 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4302
4303 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4304 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4305
4306 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4307 FirstOffset, IDLoc, STI);
4308 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4309 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4310 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4311
4312 return false;
4313}
4314
4315bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4316 const MCSubtargetInfo *STI) {
4317 if (hasMips32r6() || hasMips64r6()) {
4318 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4319 }
4320
4321 const MCOperand &DstRegOp = Inst.getOperand(0);
4322 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4322, __PRETTY_FUNCTION__))
;
4323 const MCOperand &SrcRegOp = Inst.getOperand(1);
4324 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4324, __PRETTY_FUNCTION__))
;
4325 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4326 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4326, __PRETTY_FUNCTION__))
;
4327
4328 MipsTargetStreamer &TOut = getTargetStreamer();
4329 unsigned DstReg = DstRegOp.getReg();
4330 unsigned SrcReg = SrcRegOp.getReg();
4331 int64_t OffsetValue = OffsetImmOp.getImm();
4332
4333 warnIfNoMacro(IDLoc);
4334 unsigned ATReg = getATReg(IDLoc);
4335 if (!ATReg)
4336 return true;
4337
4338 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4339 if (IsLargeOffset) {
4340 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4341 IDLoc, Out, STI))
4342 return true;
4343 }
4344
4345 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4346 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4347 if (isLittle())
4348 std::swap(FirstOffset, SecondOffset);
4349
4350 if (IsLargeOffset) {
4351 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4352 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4353 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4354 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4355 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4356 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4357 } else {
4358 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4359 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4360 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4361 }
4362
4363 return false;
4364}
4365
4366bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4367 const MCSubtargetInfo *STI) {
4368 if (hasMips32r6() || hasMips64r6()) {
4369 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4370 }
4371
4372 const MCOperand &DstRegOp = Inst.getOperand(0);
4373 assert(DstRegOp.isReg() && "expected register operand kind")((DstRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("DstRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4373, __PRETTY_FUNCTION__))
;
4374 const MCOperand &SrcRegOp = Inst.getOperand(1);
4375 assert(SrcRegOp.isReg() && "expected register operand kind")((SrcRegOp.isReg() && "expected register operand kind"
) ? static_cast<void> (0) : __assert_fail ("SrcRegOp.isReg() && \"expected register operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4375, __PRETTY_FUNCTION__))
;
4376 const MCOperand &OffsetImmOp = Inst.getOperand(2);
4377 assert(OffsetImmOp.isImm() && "expected immediate operand kind")((OffsetImmOp.isImm() && "expected immediate operand kind"
) ? static_cast<void> (0) : __assert_fail ("OffsetImmOp.isImm() && \"expected immediate operand kind\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4377, __PRETTY_FUNCTION__))
;
4378
4379 MipsTargetStreamer &TOut = getTargetStreamer();
4380 unsigned DstReg = DstRegOp.getReg();
4381 unsigned SrcReg = SrcRegOp.getReg();
4382 int64_t OffsetValue = OffsetImmOp.getImm();
4383
4384 // Compute left/right load/store offsets.
4385 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4386 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4387 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4388 if (isLittle())
4389 std::swap(LxlOffset, LxrOffset);
4390
4391 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4392 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4393 unsigned TmpReg = SrcReg;
4394 if (IsLargeOffset || DoMove) {
4395 warnIfNoMacro(IDLoc);
4396 TmpReg = getATReg(IDLoc);
4397 if (!TmpReg)
4398 return true;
4399 }
4400
4401 if (IsLargeOffset) {
4402 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4403 IDLoc, Out, STI))
4404 return true;
4405 }
4406
4407 if (DoMove)
4408 std::swap(DstReg, TmpReg);
4409
4410 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4411 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4412 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4413 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4414
4415 if (DoMove)
4416 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4417
4418 return false;
4419}
4420
4421bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4422 const MCSubtargetInfo *STI) {
4423 MipsTargetStreamer &TOut = getTargetStreamer();
4424
4425 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4425, __PRETTY_FUNCTION__))
;
4426 assert(Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4428, __PRETTY_FUNCTION__))
4427 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4428, __PRETTY_FUNCTION__))
4428 Inst.getOperand(2).isReg() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4428, __PRETTY_FUNCTION__))
;
4429
4430 unsigned DstReg = Inst.getOperand(0).getReg();
4431 unsigned SrcReg = Inst.getOperand(1).getReg();
4432 unsigned OpReg = Inst.getOperand(2).getReg();
4433 unsigned OpCode;
4434
4435 warnIfNoMacro(IDLoc);
4436
4437 switch (Inst.getOpcode()) {
4438 case Mips::SGE:
4439 OpCode = Mips::SLT;
4440 break;
4441 case Mips::SGEU:
4442 OpCode = Mips::SLTu;
4443 break;
4444 default:
4445 llvm_unreachable("unexpected 'sge' opcode")::llvm::llvm_unreachable_internal("unexpected 'sge' opcode", "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4445)
;
4446 }
4447
4448 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4449 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4450 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4451
4452 return false;
4453}
4454
4455bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4456 const MCSubtargetInfo *STI) {
4457 MipsTargetStreamer &TOut = getTargetStreamer();
4458
4459 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4459, __PRETTY_FUNCTION__))
;
4460 assert(Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4462, __PRETTY_FUNCTION__))
4461 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4462, __PRETTY_FUNCTION__))
4462 Inst.getOperand(2).isImm() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4462, __PRETTY_FUNCTION__))
;
4463
4464 unsigned DstReg = Inst.getOperand(0).getReg();
4465 unsigned SrcReg = Inst.getOperand(1).getReg();
4466 int64_t ImmValue = Inst.getOperand(2).getImm();
4467 unsigned OpRegCode, OpImmCode;
4468
4469 warnIfNoMacro(IDLoc);
4470
4471 switch (Inst.getOpcode()) {
4472 case Mips::SGEImm:
4473 case Mips::SGEImm64:
4474 OpRegCode = Mips::SLT;
4475 OpImmCode = Mips::SLTi;
4476 break;
4477 case Mips::SGEUImm:
4478 case Mips::SGEUImm64:
4479 OpRegCode = Mips::SLTu;
4480 OpImmCode = Mips::SLTiu;
4481 break;
4482 default:
4483 llvm_unreachable("unexpected 'sge' opcode with immediate")::llvm::llvm_unreachable_internal("unexpected 'sge' opcode with immediate"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4483)
;
4484 }
4485
4486 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4487 if (isInt<16>(ImmValue)) {
4488 // Use immediate version of STL.
4489 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4490 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4491 } else {
4492 unsigned ImmReg = DstReg;
4493 if (DstReg == SrcReg) {
4494 unsigned ATReg = getATReg(Inst.getLoc());
4495 if (!ATReg)
4496 return true;
4497 ImmReg = ATReg;
4498 }
4499
4500 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4501 false, IDLoc, Out, STI))
4502 return true;
4503
4504 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4505 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4506 }
4507
4508 return false;
4509}
4510
4511bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4512 const MCSubtargetInfo *STI) {
4513 MipsTargetStreamer &TOut = getTargetStreamer();
4514
4515 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4515, __PRETTY_FUNCTION__))
;
4516 assert(Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4518, __PRETTY_FUNCTION__))
4517 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4518, __PRETTY_FUNCTION__))
4518 Inst.getOperand(2).isImm() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4518, __PRETTY_FUNCTION__))
;
4519
4520 unsigned DstReg = Inst.getOperand(0).getReg();
4521 unsigned SrcReg = Inst.getOperand(1).getReg();
4522 unsigned ImmReg = DstReg;
4523 int64_t ImmValue = Inst.getOperand(2).getImm();
4524 unsigned OpCode;
4525
4526 warnIfNoMacro(IDLoc);
4527
4528 switch (Inst.getOpcode()) {
4529 case Mips::SGTImm:
4530 case Mips::SGTImm64:
4531 OpCode = Mips::SLT;
4532 break;
4533 case Mips::SGTUImm:
4534 case Mips::SGTUImm64:
4535 OpCode = Mips::SLTu;
4536 break;
4537 default:
4538 llvm_unreachable("unexpected 'sgt' opcode with immediate")::llvm::llvm_unreachable_internal("unexpected 'sgt' opcode with immediate"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4538)
;
4539 }
4540
4541 if (DstReg == SrcReg) {
4542 unsigned ATReg = getATReg(Inst.getLoc());
4543 if (!ATReg)
4544 return true;
4545 ImmReg = ATReg;
4546 }
4547
4548 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4549 false, IDLoc, Out, STI))
4550 return true;
4551
4552 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4553 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4554
4555 return false;
4556}
4557
4558bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4559 MCStreamer &Out,
4560 const MCSubtargetInfo *STI) {
4561 MipsTargetStreamer &TOut = getTargetStreamer();
4562
4563 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4563, __PRETTY_FUNCTION__))
;
4564 assert(Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4566, __PRETTY_FUNCTION__))
4565 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4566, __PRETTY_FUNCTION__))
4566 Inst.getOperand(2).isImm() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4566, __PRETTY_FUNCTION__))
;
4567
4568 unsigned ATReg = Mips::NoRegister;
4569 unsigned FinalDstReg = Mips::NoRegister;
4570 unsigned DstReg = Inst.getOperand(0).getReg();
4571 unsigned SrcReg = Inst.getOperand(1).getReg();
4572 int64_t ImmValue = Inst.getOperand(2).getImm();
4573
4574 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4575
4576 unsigned FinalOpcode = Inst.getOpcode();
4577
4578 if (DstReg == SrcReg) {
4579 ATReg = getATReg(Inst.getLoc());
4580 if (!ATReg)
4581 return true;
4582 FinalDstReg = DstReg;
4583 DstReg = ATReg;
4584 }
4585
4586 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4587 Inst.getLoc(), Out, STI)) {
4588 switch (FinalOpcode) {
4589 default:
4590 llvm_unreachable("unimplemented expansion")::llvm::llvm_unreachable_internal("unimplemented expansion", "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4590)
;
4591 case Mips::ADDi:
4592 FinalOpcode = Mips::ADD;
4593 break;
4594 case Mips::ADDiu:
4595 FinalOpcode = Mips::ADDu;
4596 break;
4597 case Mips::ANDi:
4598 FinalOpcode = Mips::AND;
4599 break;
4600 case Mips::NORImm:
4601 FinalOpcode = Mips::NOR;
4602 break;
4603 case Mips::ORi:
4604 FinalOpcode = Mips::OR;
4605 break;
4606 case Mips::SLTi:
4607 FinalOpcode = Mips::SLT;
4608 break;
4609 case Mips::SLTiu:
4610 FinalOpcode = Mips::SLTu;
4611 break;
4612 case Mips::XORi:
4613 FinalOpcode = Mips::XOR;
4614 break;
4615 case Mips::ADDi_MM:
4616 FinalOpcode = Mips::ADD_MM;
4617 break;
4618 case Mips::ADDiu_MM:
4619 FinalOpcode = Mips::ADDu_MM;
4620 break;
4621 case Mips::ANDi_MM:
4622 FinalOpcode = Mips::AND_MM;
4623 break;
4624 case Mips::ORi_MM:
4625 FinalOpcode = Mips::OR_MM;
4626 break;
4627 case Mips::SLTi_MM:
4628 FinalOpcode = Mips::SLT_MM;
4629 break;
4630 case Mips::SLTiu_MM:
4631 FinalOpcode = Mips::SLTu_MM;
4632 break;
4633 case Mips::XORi_MM:
4634 FinalOpcode = Mips::XOR_MM;
4635 break;
4636 case Mips::ANDi64:
4637 FinalOpcode = Mips::AND64;
4638 break;
4639 case Mips::NORImm64:
4640 FinalOpcode = Mips::NOR64;
4641 break;
4642 case Mips::ORi64:
4643 FinalOpcode = Mips::OR64;
4644 break;
4645 case Mips::SLTImm64:
4646 FinalOpcode = Mips::SLT64;
4647 break;
4648 case Mips::SLTUImm64:
4649 FinalOpcode = Mips::SLTu64;
4650 break;
4651 case Mips::XORi64:
4652 FinalOpcode = Mips::XOR64;
4653 break;
4654 }
4655
4656 if (FinalDstReg == Mips::NoRegister)
4657 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4658 else
4659 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4660 return false;
4661 }
4662 return true;
4663}
4664
4665bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4666 const MCSubtargetInfo *STI) {
4667 MipsTargetStreamer &TOut = getTargetStreamer();
4668 unsigned ATReg = Mips::NoRegister;
4669 unsigned DReg = Inst.getOperand(0).getReg();
4670 unsigned SReg = Inst.getOperand(1).getReg();
4671 unsigned TReg = Inst.getOperand(2).getReg();
4672 unsigned TmpReg = DReg;
4673
4674 unsigned FirstShift = Mips::NOP;
4675 unsigned SecondShift = Mips::NOP;
4676
4677 if (hasMips32r2()) {
4678 if (DReg == SReg) {
4679 TmpReg = getATReg(Inst.getLoc());
4680 if (!TmpReg)
4681 return true;
4682 }
4683
4684 if (Inst.getOpcode() == Mips::ROL) {
4685 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4686 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4687 return false;
4688 }
4689
4690 if (Inst.getOpcode() == Mips::ROR) {
4691 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4692 return false;
4693 }
4694
4695 return true;
4696 }
4697
4698 if (hasMips32()) {
4699 switch (Inst.getOpcode()) {
4700 default:
4701 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4701)
;
4702 case Mips::ROL:
4703 FirstShift = Mips::SRLV;
4704 SecondShift = Mips::SLLV;
4705 break;
4706 case Mips::ROR:
4707 FirstShift = Mips::SLLV;
4708 SecondShift = Mips::SRLV;
4709 break;
4710 }
4711
4712 ATReg = getATReg(Inst.getLoc());
4713 if (!ATReg)
4714 return true;
4715
4716 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4717 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4718 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4719 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4720
4721 return false;
4722 }
4723
4724 return true;
4725}
4726
4727bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4728 MCStreamer &Out,
4729 const MCSubtargetInfo *STI) {
4730 MipsTargetStreamer &TOut = getTargetStreamer();
4731 unsigned ATReg = Mips::NoRegister;
4732 unsigned DReg = Inst.getOperand(0).getReg();
4733 unsigned SReg = Inst.getOperand(1).getReg();
4734 int64_t ImmValue = Inst.getOperand(2).getImm();
4735
4736 unsigned FirstShift = Mips::NOP;
4737 unsigned SecondShift = Mips::NOP;
4738
4739 if (hasMips32r2()) {
4740 if (Inst.getOpcode() == Mips::ROLImm) {
4741 uint64_t MaxShift = 32;
4742 uint64_t ShiftValue = ImmValue;
4743 if (ImmValue != 0)
4744 ShiftValue = MaxShift - ImmValue;
4745 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4746 return false;
4747 }
4748
4749 if (Inst.getOpcode() == Mips::RORImm) {
4750 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4751 return false;
4752 }
4753
4754 return true;
4755 }
4756
4757 if (hasMips32()) {
4758 if (ImmValue == 0) {
4759 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4760 return false;
4761 }
4762
4763 switch (Inst.getOpcode()) {
4764 default:
4765 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4765)
;
4766 case Mips::ROLImm:
4767 FirstShift = Mips::SLL;
4768 SecondShift = Mips::SRL;
4769 break;
4770 case Mips::RORImm:
4771 FirstShift = Mips::SRL;
4772 SecondShift = Mips::SLL;
4773 break;
4774 }
4775
4776 ATReg = getATReg(Inst.getLoc());
4777 if (!ATReg)
4778 return true;
4779
4780 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4781 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4782 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4783
4784 return false;
4785 }
4786
4787 return true;
4788}
4789
4790bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4791 const MCSubtargetInfo *STI) {
4792 MipsTargetStreamer &TOut = getTargetStreamer();
4793 unsigned ATReg = Mips::NoRegister;
4794 unsigned DReg = Inst.getOperand(0).getReg();
4795 unsigned SReg = Inst.getOperand(1).getReg();
4796 unsigned TReg = Inst.getOperand(2).getReg();
4797 unsigned TmpReg = DReg;
4798
4799 unsigned FirstShift = Mips::NOP;
4800 unsigned SecondShift = Mips::NOP;
4801
4802 if (hasMips64r2()) {
4803 if (TmpReg == SReg) {
4804 TmpReg = getATReg(Inst.getLoc());
4805 if (!TmpReg)
4806 return true;
4807 }
4808
4809 if (Inst.getOpcode() == Mips::DROL) {
4810 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4811 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4812 return false;
4813 }
4814
4815 if (Inst.getOpcode() == Mips::DROR) {
4816 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4817 return false;
4818 }
4819
4820 return true;
4821 }
4822
4823 if (hasMips64()) {
4824 switch (Inst.getOpcode()) {
4825 default:
4826 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4826)
;
4827 case Mips::DROL:
4828 FirstShift = Mips::DSRLV;
4829 SecondShift = Mips::DSLLV;
4830 break;
4831 case Mips::DROR:
4832 FirstShift = Mips::DSLLV;
4833 SecondShift = Mips::DSRLV;
4834 break;
4835 }
4836
4837 ATReg = getATReg(Inst.getLoc());
4838 if (!ATReg)
4839 return true;
4840
4841 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4842 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4843 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4844 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4845
4846 return false;
4847 }
4848
4849 return true;
4850}
4851
4852bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
4853 MCStreamer &Out,
4854 const MCSubtargetInfo *STI) {
4855 MipsTargetStreamer &TOut = getTargetStreamer();
4856 unsigned ATReg = Mips::NoRegister;
4857 unsigned DReg = Inst.getOperand(0).getReg();
4858 unsigned SReg = Inst.getOperand(1).getReg();
4859 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
4860
4861 unsigned FirstShift = Mips::NOP;
4862 unsigned SecondShift = Mips::NOP;
4863
4864 MCInst TmpInst;
4865
4866 if (hasMips64r2()) {
4867 unsigned FinalOpcode = Mips::NOP;
4868 if (ImmValue == 0)
4869 FinalOpcode = Mips::DROTR;
4870 else if (ImmValue % 32 == 0)
4871 FinalOpcode = Mips::DROTR32;
4872 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4873 if (Inst.getOpcode() == Mips::DROLImm)
4874 FinalOpcode = Mips::DROTR32;
4875 else
4876 FinalOpcode = Mips::DROTR;
4877 } else if (ImmValue >= 33) {
4878 if (Inst.getOpcode() == Mips::DROLImm)
4879 FinalOpcode = Mips::DROTR;
4880 else
4881 FinalOpcode = Mips::DROTR32;
4882 }
4883
4884 uint64_t ShiftValue = ImmValue % 32;
4885 if (Inst.getOpcode() == Mips::DROLImm)
4886 ShiftValue = (32 - ImmValue % 32) % 32;
4887
4888 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4889
4890 return false;
4891 }
4892
4893 if (hasMips64()) {
4894 if (ImmValue == 0) {
4895 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
4896 return false;
4897 }
4898
4899 switch (Inst.getOpcode()) {
4900 default:
4901 llvm_unreachable("unexpected instruction opcode")::llvm::llvm_unreachable_internal("unexpected instruction opcode"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 4901)
;
4902 case Mips::DROLImm:
4903 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4904 FirstShift = Mips::DSLL;
4905 SecondShift = Mips::DSRL32;
4906 }
4907 if (ImmValue == 32) {
4908 FirstShift = Mips::DSLL32;
4909 SecondShift = Mips::DSRL32;
4910 }
4911 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4912 FirstShift = Mips::DSLL32;
4913 SecondShift = Mips::DSRL;
4914 }
4915 break;
4916 case Mips::DRORImm:
4917 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4918 FirstShift = Mips::DSRL;
4919 SecondShift = Mips::DSLL32;
4920 }
4921 if (ImmValue == 32) {
4922 FirstShift = Mips::DSRL32;
4923 SecondShift = Mips::DSLL32;
4924 }
4925 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4926 FirstShift = Mips::DSRL32;
4927 SecondShift = Mips::DSLL;
4928 }
4929 break;
4930 }
4931
4932 ATReg = getATReg(Inst.getLoc());
4933 if (!ATReg)
4934 return true;
4935
4936 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
4937 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4938 Inst.getLoc(), STI);
4939 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4940
4941 return false;
4942 }
4943
4944 return true;
4945}
4946
4947bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4948 const MCSubtargetInfo *STI) {
4949 MipsTargetStreamer &TOut = getTargetStreamer();
4950 unsigned FirstRegOp = Inst.getOperand(0).getReg();
4951 unsigned SecondRegOp = Inst.getOperand(1).getReg();
4952
4953 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4954 if (FirstRegOp != SecondRegOp)
4955 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4956 else
4957 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
4958 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
4959
4960 return false;
4961}
4962
4963bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4964 const MCSubtargetInfo *STI) {
4965 MipsTargetStreamer &TOut = getTargetStreamer();
4966 unsigned ATReg = Mips::NoRegister;
4967 unsigned DstReg = Inst.getOperand(0).getReg();
4968 unsigned SrcReg = Inst.getOperand(1).getReg();
4969 int32_t ImmValue = Inst.getOperand(2).getImm();
4970
4971 ATReg = getATReg(IDLoc);
4972 if (!ATReg)
4973 return true;
4974
4975 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
4976 STI);
4977
4978 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
4979 SrcReg, ATReg, IDLoc, STI);
4980
4981 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
4982
4983 return false;
4984}
4985
4986bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4987 const MCSubtargetInfo *STI) {
4988 MipsTargetStreamer &TOut = getTargetStreamer();
4989 unsigned ATReg = Mips::NoRegister;
4990 unsigned DstReg = Inst.getOperand(0).getReg();
4991 unsigned SrcReg = Inst.getOperand(1).getReg();
4992 unsigned TmpReg = Inst.getOperand(2).getReg();
4993
4994 ATReg = getATReg(Inst.getLoc());
4995 if (!ATReg)
4996 return true;
4997
4998 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
4999 SrcReg, TmpReg, IDLoc, STI);
5000
5001 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5002
5003 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5004 DstReg, DstReg, 0x1F, IDLoc, STI);
5005
5006 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5007
5008 if (useTraps()) {
5009 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5010 } else {
5011 MCContext & Context = TOut.getStreamer().getContext();
5012 MCSymbol * BrTarget = Context.createTempSymbol();
5013 MCOperand LabelOp =
5014 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5015
5016 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5017 if (AssemblerOptions.back()->isReorder())
5018 TOut.emitNop(IDLoc, STI);
5019 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5020
5021 TOut.getStreamer().EmitLabel(BrTarget);
5022 }
5023 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5024
5025 return false;
5026}
5027
5028bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5029 const MCSubtargetInfo *STI) {
5030 MipsTargetStreamer &TOut = getTargetStreamer();
5031 unsigned ATReg = Mips::NoRegister;
5032 unsigned DstReg = Inst.getOperand(0).getReg();
5033 unsigned SrcReg = Inst.getOperand(1).getReg();
5034 unsigned TmpReg = Inst.getOperand(2).getReg();
5035
5036 ATReg = getATReg(IDLoc);
5037 if (!ATReg)
5038 return true;
5039
5040 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5041 SrcReg, TmpReg, IDLoc, STI);
5042
5043 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5044 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5045 if (useTraps()) {
5046 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5047 } else {
5048 MCContext & Context = TOut.getStreamer().getContext();
5049 MCSymbol * BrTarget = Context.createTempSymbol();
5050 MCOperand LabelOp =
5051 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5052
5053 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5054 if (AssemblerOptions.back()->isReorder())
5055 TOut.emitNop(IDLoc, STI);
5056 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5057
5058 TOut.getStreamer().EmitLabel(BrTarget);
5059 }
5060
5061 return false;
5062}
5063
5064bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5065 const MCSubtargetInfo *STI) {
5066 MipsTargetStreamer &TOut = getTargetStreamer();
5067 unsigned DstReg = Inst.getOperand(0).getReg();
5068 unsigned SrcReg = Inst.getOperand(1).getReg();
5069 unsigned TmpReg = Inst.getOperand(2).getReg();
5070
5071 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5072 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5073
5074 return false;
5075}
5076
5077// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5078// lw $<reg+1>>, offset+4($reg2)'
5079// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5080// sw $<reg+1>>, offset+4($reg2)'
5081// for O32.
5082bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5083 MCStreamer &Out,
5084 const MCSubtargetInfo *STI,
5085 bool IsLoad) {
5086 if (!isABI_O32())
5087 return true;
5088
5089 warnIfNoMacro(IDLoc);
5090
5091 MipsTargetStreamer &TOut = getTargetStreamer();
5092 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5093 unsigned FirstReg = Inst.getOperand(0).getReg();
5094 unsigned SecondReg = nextReg(FirstReg);
5095 unsigned BaseReg = Inst.getOperand(1).getReg();
5096 if (!SecondReg)
5097 return true;
5098
5099 warnIfRegIndexIsAT(FirstReg, IDLoc);
5100
5101 assert(Inst.getOperand(2).isImm() &&((Inst.getOperand(2).isImm() && "Offset for load macro is not immediate!"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && \"Offset for load macro is not immediate!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5102, __PRETTY_FUNCTION__))
5102 "Offset for load macro is not immediate!")((Inst.getOperand(2).isImm() && "Offset for load macro is not immediate!"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && \"Offset for load macro is not immediate!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5102, __PRETTY_FUNCTION__))
;
5103
5104 MCOperand &FirstOffset = Inst.getOperand(2);
5105 signed NextOffset = FirstOffset.getImm() + 4;
5106 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5107
5108 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5109 return true;
5110
5111 // For loads, clobber the base register with the second load instead of the
5112 // first if the BaseReg == FirstReg.
5113 if (FirstReg != BaseReg || !IsLoad) {
5114 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5115 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5116 } else {
5117 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5118 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5119 }
5120
5121 return false;
5122}
5123
5124
5125// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5126// swc1 $<reg>, offset+4($reg2)'
5127// or if little endian to 'swc1 $<reg>, offset($reg2);
5128// swc1 $<reg+1>, offset+4($reg2)'
5129// for Mips1.
5130bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5131 MCStreamer &Out,
5132 const MCSubtargetInfo *STI) {
5133 if (!isABI_O32())
5134 return true;
5135
5136 warnIfNoMacro(IDLoc);
5137
5138 MipsTargetStreamer &TOut = getTargetStreamer();
5139 unsigned Opcode = Mips::SWC1;
5140 unsigned FirstReg = Inst.getOperand(0).getReg();
5141 unsigned SecondReg = nextReg(FirstReg);
5142 unsigned BaseReg = Inst.getOperand(1).getReg();
5143 if (!SecondReg)
5144 return true;
5145
5146 warnIfRegIndexIsAT(FirstReg, IDLoc);
5147
5148 assert(Inst.getOperand(2).isImm() &&((Inst.getOperand(2).isImm() && "Offset for macro is not immediate!"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && \"Offset for macro is not immediate!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5149, __PRETTY_FUNCTION__))
5149 "Offset for macro is not immediate!")((Inst.getOperand(2).isImm() && "Offset for macro is not immediate!"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && \"Offset for macro is not immediate!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5149, __PRETTY_FUNCTION__))
;
5150
5151 MCOperand &FirstOffset = Inst.getOperand(2);
5152 signed NextOffset = FirstOffset.getImm() + 4;
5153 MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5154
5155 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5156 return true;
5157
5158 if (!IsLittleEndian)
5159 std::swap(FirstReg, SecondReg);
5160
5161 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5162 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5163
5164 return false;
5165}
5166
5167bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5168 const MCSubtargetInfo *STI) {
5169 MipsTargetStreamer &TOut = getTargetStreamer();
5170
5171 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5171, __PRETTY_FUNCTION__))
;
5172 assert(Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5174, __PRETTY_FUNCTION__))
5173 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5174, __PRETTY_FUNCTION__))
5174 Inst.getOperand(2).isReg() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isReg() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isReg() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5174, __PRETTY_FUNCTION__))
;
5175
5176 unsigned DstReg = Inst.getOperand(0).getReg();
5177 unsigned SrcReg = Inst.getOperand(1).getReg();
5178 unsigned OpReg = Inst.getOperand(2).getReg();
5179
5180 warnIfNoMacro(IDLoc);
5181
5182 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5183 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5184 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5185 return false;
5186 }
5187
5188 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5189 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5190 return false;
5191}
5192
5193bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5194 const MCSubtargetInfo *STI) {
5195 MipsTargetStreamer &TOut = getTargetStreamer();
5196
5197 assert(Inst.getNumOperands() == 3 && "Invalid operand count")((Inst.getNumOperands() == 3 && "Invalid operand count"
) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid operand count\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5197, __PRETTY_FUNCTION__))
;
5198 assert(Inst.getOperand(0).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5200, __PRETTY_FUNCTION__))
5199 Inst.getOperand(1).isReg() &&((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5200, __PRETTY_FUNCTION__))
5200 Inst.getOperand(2).isImm() && "Invalid instruction operand.")((Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg
() && Inst.getOperand(2).isImm() && "Invalid instruction operand."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm() && \"Invalid instruction operand.\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5200, __PRETTY_FUNCTION__))
;
5201
5202 unsigned DstReg = Inst.getOperand(0).getReg();
5203 unsigned SrcReg = Inst.getOperand(1).getReg();
5204 int64_t Imm = Inst.getOperand(2).getImm();
5205
5206 warnIfNoMacro(IDLoc);
5207
5208 if (Imm == 0) {
5209 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5210 return false;
5211 }
5212
5213 if (SrcReg == Mips::ZERO) {
5214 Warning(IDLoc, "comparison is always false");
5215 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5216 DstReg, SrcReg, SrcReg, IDLoc, STI);
5217 return false;
5218 }
5219
5220 unsigned Opc;
5221 if (Imm > -0x8000 && Imm < 0) {
5222 Imm = -Imm;
5223 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5224 } else {
5225 Opc = Mips::XORi;
5226 }
5227
5228 if (!isUInt<16>(Imm)) {
5229 unsigned ATReg = getATReg(IDLoc);
5230 if (!ATReg)
5231 return true;
5232
5233 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5234 Out, STI))
5235 return true;
5236
5237 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5238 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5239 return false;
5240 }
5241
5242 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5243 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5244 return false;
5245}
5246
5247// Map the DSP accumulator and control register to the corresponding gpr
5248// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5249// do not map the DSP registers contigously to gpr registers.
5250static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5251 switch (Inst.getOpcode()) {
5252 case Mips::MFTLO:
5253 case Mips::MTTLO:
5254 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5255 case Mips::AC0:
5256 return Mips::ZERO;
5257 case Mips::AC1:
5258 return Mips::A0;
5259 case Mips::AC2:
5260 return Mips::T0;
5261 case Mips::AC3:
5262 return Mips::T4;
5263 default:
5264 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5264)
;
5265 }
5266 case Mips::MFTHI:
5267 case Mips::MTTHI:
5268 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5269 case Mips::AC0:
5270 return Mips::AT;
5271 case Mips::AC1:
5272 return Mips::A1;
5273 case Mips::AC2:
5274 return Mips::T1;
5275 case Mips::AC3:
5276 return Mips::T5;
5277 default:
5278 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5278)
;
5279 }
5280 case Mips::MFTACX:
5281 case Mips::MTTACX:
5282 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
5283 case Mips::AC0:
5284 return Mips::V0;
5285 case Mips::AC1:
5286 return Mips::A2;
5287 case Mips::AC2:
5288 return Mips::T2;
5289 case Mips::AC3:
5290 return Mips::T6;
5291 default:
5292 llvm_unreachable("Unknown register for 'mttr' alias!")::llvm::llvm_unreachable_internal("Unknown register for 'mttr' alias!"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5292)
;
5293 }
5294 case Mips::MFTDSP:
5295 case Mips::MTTDSP:
5296 return Mips::S0;
5297 default:
5298 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!")::llvm::llvm_unreachable_internal("Unknown instruction for 'mttr' dsp alias!"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5298)
;
5299 }
5300}
5301
5302// Map the floating point register operand to the corresponding register
5303// operand.
5304static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5305 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
5306 case Mips::F0: return Mips::ZERO;
5307 case Mips::F1: return Mips::AT;
5308 case Mips::F2: return Mips::V0;
5309 case Mips::F3: return Mips::V1;
5310 case Mips::F4: return Mips::A0;
5311 case Mips::F5: return Mips::A1;
5312 case Mips::F6: return Mips::A2;
5313 case Mips::F7: return Mips::A3;
5314 case Mips::F8: return Mips::T0;
5315 case Mips::F9: return Mips::T1;
5316 case Mips::F10: return Mips::T2;
5317 case Mips::F11: return Mips::T3;
5318 case Mips::F12: return Mips::T4;
5319 case Mips::F13: return Mips::T5;
5320 case Mips::F14: return Mips::T6;
5321 case Mips::F15: return Mips::T7;
5322 case Mips::F16: return Mips::S0;
5323 case Mips::F17: return Mips::S1;
5324 case Mips::F18: return Mips::S2;
5325 case Mips::F19: return Mips::S3;
5326 case Mips::F20: return Mips::S4;
5327 case Mips::F21: return Mips::S5;
5328 case Mips::F22: return Mips::S6;
5329 case Mips::F23: return Mips::S7;
5330 case Mips::F24: return Mips::T8;
5331 case Mips::F25: return Mips::T9;
5332 case Mips::F26: return Mips::K0;
5333 case Mips::F27: return Mips::K1;
5334 case Mips::F28: return Mips::GP;
5335 case Mips::F29: return Mips::SP;
5336 case Mips::F30: return Mips::FP;
5337 case Mips::F31: return Mips::RA;
5338 default: llvm_unreachable("Unknown register for mttc1 alias!")::llvm::llvm_unreachable_internal("Unknown register for mttc1 alias!"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5338)
;
5339 }
5340}
5341
5342// Map the coprocessor operand the corresponding gpr register operand.
5343static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5344 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
5345 case Mips::COP00: return Mips::ZERO;
5346 case Mips::COP01: return Mips::AT;
5347 case Mips::COP02: return Mips::V0;
5348 case Mips::COP03: return Mips::V1;
5349 case Mips::COP04: return Mips::A0;
5350 case Mips::COP05: return Mips::A1;
5351 case Mips::COP06: return Mips::A2;
5352 case Mips::COP07: return Mips::A3;
5353 case Mips::COP08: return Mips::T0;
5354 case Mips::COP09: return Mips::T1;
5355 case Mips::COP010: return Mips::T2;
5356 case Mips::COP011: return Mips::T3;
5357 case Mips::COP012: return Mips::T4;
5358 case Mips::COP013: return Mips::T5;
5359 case Mips::COP014: return Mips::T6;
5360 case Mips::COP015: return Mips::T7;
5361 case Mips::COP016: return Mips::S0;
5362 case Mips::COP017: return Mips::S1;
5363 case Mips::COP018: return Mips::S2;
5364 case Mips::COP019: return Mips::S3;
5365 case Mips::COP020: return Mips::S4;
5366 case Mips::COP021: return Mips::S5;
5367 case Mips::COP022: return Mips::S6;
5368 case Mips::COP023: return Mips::S7;
5369 case Mips::COP024: return Mips::T8;
5370 case Mips::COP025: return Mips::T9;
5371 case Mips::COP026: return Mips::K0;
5372 case Mips::COP027: return Mips::K1;
5373 case Mips::COP028: return Mips::GP;
5374 case Mips::COP029: return Mips::SP;
5375 case Mips::COP030: return Mips::FP;
5376 case Mips::COP031: return Mips::RA;
5377 default: llvm_unreachable("Unknown register for mttc0 alias!")::llvm::llvm_unreachable_internal("Unknown register for mttc0 alias!"
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5377)
;
5378 }
5379}
5380
5381/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5382/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5383bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5384 const MCSubtargetInfo *STI) {
5385 MipsTargetStreamer &TOut = getTargetStreamer();
5386 unsigned rd = 0;
5387 unsigned u = 1;
5388 unsigned sel = 0;
5389 unsigned h = 0;
5390 bool IsMFTR = false;
5391 switch (Inst.getOpcode()) {
5392 case Mips::MFTC0:
5393 IsMFTR = true;
5394 LLVM_FALLTHROUGH[[gnu::fallthrough]];
5395 case Mips::MTTC0:
5396 u = 0;
5397 rd = getRegisterForMxtrC0(Inst, IsMFTR);
5398 sel = Inst.getOperand(2).getImm();
5399 break;
5400 case Mips::MFTGPR:
5401 IsMFTR = true;
5402 LLVM_FALLTHROUGH[[gnu::fallthrough]];
5403 case Mips::MTTGPR:
5404 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5405 break;
5406 case Mips::MFTLO:
5407 case Mips::MFTHI:
5408 case Mips::MFTACX:
5409 case Mips::MFTDSP:
5410 IsMFTR = true;
5411 LLVM_FALLTHROUGH[[gnu::fallthrough]];
5412 case Mips::MTTLO:
5413 case Mips::MTTHI:
5414 case Mips::MTTACX:
5415 case Mips::MTTDSP:
5416 rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5417 sel = 1;
5418 break;
5419 case Mips::MFTHC1:
5420 h = 1;
5421 LLVM_FALLTHROUGH[[gnu::fallthrough]];
5422 case Mips::MFTC1:
5423 IsMFTR = true;
5424 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5425 sel = 2;
5426 break;
5427 case Mips::MTTHC1:
5428 h = 1;
5429 LLVM_FALLTHROUGH[[gnu::fallthrough]];
5430 case Mips::MTTC1:
5431 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5432 sel = 2;
5433 break;
5434 case Mips::CFTC1:
5435 IsMFTR = true;
5436 LLVM_FALLTHROUGH[[gnu::fallthrough]];
5437 case Mips::CTTC1:
5438 rd = getRegisterForMxtrFP(Inst, IsMFTR);
5439 sel = 3;
5440 break;
5441 }
5442 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5443 unsigned Op1 =
5444 IsMFTR ? rd
5445 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5446 : Inst.getOperand(0).getReg());
5447
5448 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5449 STI);
5450 return false;
5451}
5452
5453unsigned
5454MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5455 const OperandVector &Operands) {
5456 switch (Inst.getOpcode()) {
5457 default:
5458 return Match_Success;
5459 case Mips::DATI:
5460 case Mips::DAHI:
5461 if (static_cast<MipsOperand &>(*Operands[1])
5462 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5463 return Match_Success;
5464 return Match_RequiresSameSrcAndDst;
5465 }
5466}
5467
5468unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5469 switch (Inst.getOpcode()) {
5470 // As described by the MIPSR6 spec, daui must not use the zero operand for
5471 // its source operand.
5472 case Mips::DAUI:
5473 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5474 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5475 return Match_RequiresNoZeroRegister;
5476 return Match_Success;
5477 // As described by the Mips32r2 spec, the registers Rd and Rs for
5478 // jalr.hb must be different.
5479 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5480 // and registers Rd and Base for microMIPS lwp instruction
5481 case Mips::JALR_HB:
5482 case Mips::JALR_HB64:
5483 case Mips::JALRC_HB_MMR6:
5484 case Mips::JALRC_MMR6:
5485 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5486 return Match_RequiresDifferentSrcAndDst;
5487 return Match_Success;
5488 case Mips::LWP_MM:
5489 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5490 return Match_RequiresDifferentSrcAndDst;
5491 return Match_Success;
5492 case Mips::SYNC:
5493 if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5494 return Match_NonZeroOperandForSync;
5495 return Match_Success;
5496 case Mips::MFC0:
5497 case Mips::MTC0:
5498 case Mips::MTC2:
5499 case Mips::MFC2:
5500 if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5501 return Match_NonZeroOperandForMTCX;
5502 return Match_Success;
5503 // As described the MIPSR6 spec, the compact branches that compare registers
5504 // must:
5505 // a) Not use the zero register.
5506 // b) Not use the same register twice.
5507 // c) rs < rt for bnec, beqc.
5508 // NB: For this case, the encoding will swap the operands as their
5509 // ordering doesn't matter. GAS performs this transformation too.
5510 // Hence, that constraint does not have to be enforced.
5511 //
5512 // The compact branches that branch iff the signed addition of two registers
5513 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5514 // operand swapping. They do not have restriction of using the zero register.
5515 case Mips::BLEZC: case Mips::BLEZC_MMR6:
5516 case Mips::BGEZC: case Mips::BGEZC_MMR6:
5517 case Mips::BGTZC: case Mips::BGTZC_MMR6:
5518 case Mips::BLTZC: case Mips::BLTZC_MMR6:
5519 case Mips::BEQZC: case Mips::BEQZC_MMR6:
5520 case Mips::BNEZC: case Mips::BNEZC_MMR6:
5521 case Mips::BLEZC64:
5522 case Mips::BGEZC64:
5523 case Mips::BGTZC64:
5524 case Mips::BLTZC64:
5525 case Mips::BEQZC64:
5526 case Mips::BNEZC64:
5527 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5528 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5529 return Match_RequiresNoZeroRegister;
5530 return Match_Success;
5531 case Mips::BGEC: case Mips::BGEC_MMR6:
5532 case Mips::BLTC: case Mips::BLTC_MMR6:
5533 case Mips::BGEUC: case Mips::BGEUC_MMR6:
5534 case Mips::BLTUC: case Mips::BLTUC_MMR6:
5535 case Mips::BEQC: case Mips::BEQC_MMR6:
5536 case Mips::BNEC: case Mips::BNEC_MMR6:
5537 case Mips::BGEC64:
5538 case Mips::BLTC64:
5539 case Mips::BGEUC64:
5540 case Mips::BLTUC64:
5541 case Mips::BEQC64:
5542 case Mips::BNEC64:
5543 if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5544 Inst.getOperand(0).getReg() == Mips::ZERO_64)
5545 return Match_RequiresNoZeroRegister;
5546 if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5547 Inst.getOperand(1).getReg() == Mips::ZERO_64)
5548 return Match_RequiresNoZeroRegister;
5549 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5550 return Match_RequiresDifferentOperands;
5551 return Match_Success;
5552 case Mips::DINS: {
5553 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dins!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dins!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5554, __PRETTY_FUNCTION__))
5554 "Operands must be immediates for dins!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dins!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dins!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5554, __PRETTY_FUNCTION__))
;
5555 const signed Pos = Inst.getOperand(2).getImm();
5556 const signed Size = Inst.getOperand(3).getImm();
5557 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5558 return Match_RequiresPosSizeRange0_32;
5559 return Match_Success;
5560 }
5561 case Mips::DINSM:
5562 case Mips::DINSU: {
5563 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dinsm/dinsu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dinsm/dinsu!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5564, __PRETTY_FUNCTION__))
5564 "Operands must be immediates for dinsm/dinsu!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dinsm/dinsu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dinsm/dinsu!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5564, __PRETTY_FUNCTION__))
;
5565 const signed Pos = Inst.getOperand(2).getImm();
5566 const signed Size = Inst.getOperand(3).getImm();
5567 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5568 return Match_RequiresPosSizeRange33_64;
5569 return Match_Success;
5570 }
5571 case Mips::DEXT: {
5572 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for DEXTM!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for DEXTM!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5573, __PRETTY_FUNCTION__))
5573 "Operands must be immediates for DEXTM!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for DEXTM!") ? static_cast
<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for DEXTM!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5573, __PRETTY_FUNCTION__))
;
5574 const signed Pos = Inst.getOperand(2).getImm();
5575 const signed Size = Inst.getOperand(3).getImm();
5576 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5577 return Match_RequiresPosSizeUImm6;
5578 return Match_Success;
5579 }
5580 case Mips::DEXTM:
5581 case Mips::DEXTU: {
5582 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dextm/dextu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dextm/dextu!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5583, __PRETTY_FUNCTION__))
5583 "Operands must be immediates for dextm/dextu!")((Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm
() && "Operands must be immediates for dextm/dextu!")
? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && \"Operands must be immediates for dextm/dextu!\""
, "/build/llvm-toolchain-snapshot-10~svn374877/lib/Target/Mips/AsmParser/MipsAsmParser.cpp"
, 5583, __PRETTY_FUNCTION__))
;
5584 const signed Pos = Inst.getOperand(2).getImm();
5585 const signed Size = Inst.getOperand(3).getImm();
5586 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5587 return Match_RequiresPosSizeRange33_64;
5588 return Match_Success;
5589 }
5590 case Mips::CRC32B: case Mips::CRC32CB:
5591 case Mips::CRC32H: case Mips::CRC32CH:
5592 case Mips::CRC32W: case Mips::CRC32CW:
5593 case Mips::CRC32D: case Mips::CRC32CD:
5594 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5595 return Match_RequiresSameSrcAndDst;
5596 return Match_Success;
5597 }
5598
5599 uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
5600 if ((TSFlags & MipsII::HasFCCRegOperand) &&
5601 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5602 return Match_NoFCCRegisterForCurrentISA;
5603
5604 return Match_Success;
5605
5606}
5607
5608static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5609 uint64_t ErrorInfo) {
5610 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5611 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5612 if (ErrorLoc == SMLoc())
5613 return Loc;
5614 return ErrorLoc;
5615 }
5616 return Loc;
5617}
5618
5619bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5620 OperandVector &Operands,
5621 MCStreamer &Out,
5622 uint64_t &ErrorInfo,
5623 bool MatchingInlineAsm) {
5624 MCInst Inst;
5625 unsigned MatchResult =
5626 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5627
5628 switch (MatchResult) {
5629 case Match_Success:
5630 if (processInstruction(Inst, IDLoc, Out, STI))
5631 return true;
5632 return false;
5633 case Match_MissingFeature:
5634 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5635 return true;
5636 case Match_InvalidOperand: {
5637 SMLoc ErrorLoc = IDLoc;
5638 if (ErrorInfo != ~0ULL) {
5639 if (ErrorInfo >= Operands.size())
5640 return Error(IDLoc, "too few operands for instruction");
5641
5642 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5643 if (ErrorLoc == SMLoc())
5644 ErrorLoc = IDLoc;
5645 }
5646
5647 return Error(ErrorLoc, "invalid operand for instruction");
5648 }
5649 case Match_NonZeroOperandForSync:
5650 return Error(IDLoc,
5651 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5652 case Match_NonZeroOperandForMTCX:
5653 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5654 case Match_MnemonicFail:
5655 return Error(IDLoc, "invalid instruction");
5656 case Match_RequiresDifferentSrcAndDst:
5657 return Error(IDLoc, "source and destination must be different");
5658 case Match_RequiresDifferentOperands:
5659 return Error(IDLoc, "registers must be different");
5660 case Match_RequiresNoZeroRegister:
5661 return Error(IDLoc, "invalid operand ($zero) for instruction");
5662 case Match_RequiresSameSrcAndDst:
5663 return Error(IDLoc, "source and destination must match");
5664 case Match_NoFCCRegisterForCurrentISA:
5665 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5666 "non-zero fcc register doesn't exist in current ISA level");
5667 case Match_Immz:
5668 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5669 case Match_UImm1_0:
5670 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5671 "expected 1-bit unsigned immediate");
5672 case Match_UImm2_0:
5673 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5674 "expected 2-bit unsigned immediate");
5675 case Match_UImm2_1:
5676 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5677 "expected immediate in range 1 .. 4");
5678 case Match_UImm3_0:
5679 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5680 "expected 3-bit unsigned immediate");
5681 case Match_UImm4_0:
5682 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5683 "expected 4-bit unsigned immediate");
5684 case Match_SImm4_0:
5685 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5686 "expected 4-bit signed immediate");
5687 case Match_UImm5_0:
5688 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5689 "expected 5-bit unsigned immediate");
5690 case Match_SImm5_0:
5691 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5692 "expected 5-bit signed immediate");
5693 case Match_UImm5_1:
5694 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5695 "expected immediate in range 1 .. 32");
5696 case Match_UImm5_32:
5697 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5698 "expected immediate in range 32 .. 63");
5699 case Match_UImm5_33:
5700 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5701 "expected immediate in range 33 .. 64");
5702 case Match_UImm5_0_Report_UImm6:
5703 // This is used on UImm5 operands that have a corresponding UImm5_32
5704 // operand to avoid confusing the user.
5705 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5706 "expected 6-bit unsigned immediate");
5707 case Match_UImm5_Lsl2:
5708 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5709 "expected both 7-bit unsigned immediate and multiple of 4");
5710 case Match_UImmRange2_64:
5711 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5712 "expected immediate in range 2 .. 64");
5713 case Match_UImm6_0:
5714 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5715 "expected 6-bit unsigned immediate");
5716 case Match_UImm6_Lsl2:
5717 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5718 "expected both 8-bit unsigned immediate and multiple of 4");
5719 case Match_SImm6_0:
5720 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5721 "expected 6-bit signed immediate");
5722 case Match_UImm7_0:
5723 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5724 "expected 7-bit unsigned immediate");
5725 case Match_UImm7_N1:
5726 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5727 "expected immediate in range -1 .. 126");
5728 case Match_SImm7_Lsl2:
5729 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5730 "expected both 9-bit signed immediate and multiple of 4");
5731 case Match_UImm8_0:
5732 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5733 "expected 8-bit unsigned immediate");
5734 case Match_UImm10_0:
5735 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5736 "expected 10-bit unsigned immediate");
5737 case Match_SImm10_0:
5738 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5739 "expected 10-bit signed immediate");
5740 case Match_SImm11_0:
5741 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5742 "expected 11-bit signed immediate");
5743 case Match_UImm16:
5744 case Match_UImm16_Relaxed:
5745 case Match_UImm16_AltRelaxed:
5746 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5747 "expected 16-bit unsigned immediate");
5748 case Match_SImm16:
5749 case Match_SImm16_Relaxed:
5750 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5751 "expected 16-bit signed immediate");
5752 case Match_SImm19_Lsl2:
5753 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5754 "expected both 19-bit signed immediate and multiple of 4");
5755 case Match_UImm20_0:
5756 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5757 "expected 20-bit unsigned immediate");
5758 case Match_UImm26_0:
5759 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5760 "expected 26-bit unsigned immediate");
5761 case Match_SImm32:
5762 case Match_SImm32_Relaxed:
5763 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5764 "expected 32-bit signed immediate");
5765 case Match_UImm32_Coerced:
5766 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5767 "expected 32-bit immediate");
5768 case Match_MemSImm9:
5769 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5770 "expected memory with 9-bit signed offset");
5771 case Match_MemSImm10:
5772 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5773 "expected memory with 10-bit signed offset");
5774 case Match_MemSImm10Lsl1:
5775 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5776 "expected memory with 11-bit signed offset and multiple of 2");
5777 case Match_MemSImm10Lsl2:
5778 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5779 "expected memory with 12-bit signed offset and multiple of 4");
5780 case Match_MemSImm10Lsl3:
5781 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5782 "expected memory with 13-bit signed offset and multiple of 8");
5783 case Match_MemSImm11:
5784 return Error