Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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