Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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