Bug Summary

File:llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Warning:line 6631, column 11
Value stored to 'PrevReg' is never read

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