Bug Summary

File:llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 3998, column 31
The left operand of '==' is a garbage value

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 -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -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~++20200112100611+7fa5290d5bd/build-llvm/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/Target/Mips/AsmParser -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/Target/Mips -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/lib/Target/Mips -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/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~++20200112100611+7fa5290d5bd/build-llvm/lib/Target/Mips/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd=. -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-2020-01-13-084841-49055-1 -x c++ /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

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