Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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

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

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